【问题标题】:How to detect a multiple-bar pattern?如何检测多条模式?
【发布时间】:2018-04-04 15:14:13
【问题描述】:

我想检测图像中的自定义“多条图案”。

图案看起来像这样,是一组平行的黑色条,宽度相同但高度不同,见下图:

此图案可能在图像上,也可能不在图像上,但如果是 - 我想知道它的位置。

注意:图案的颜色在任何情况下都是黑色

注意:图案大小未知,可能很大也可能超小。

注意:图案条数为固定数。每次出现都相同(在本例中为 7)。


图像可能如下所示:

在执行代码搜索算法之后,这应该会发生:


任何帮助将不胜感激。提前一百万谢谢,Tempi。

注意:到目前为止我得到的代码(不工作)

Mat myImage; // this is the mat of the photo you can see above
Mat algorithmImage;
myImage.coptyTo(algorithmImage); 
cvtColor(algorithmImage, algorithmImage, CV_RGB2HSV);

double imgThreshold = 20;
cv::inRange(algorithmImage, cv::Scalar(0, 0, 0, 0), cv::Scalar(180, 255, 30, 0), 20);

Mat canny;
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;

Canny( algorithmImage, canny, 3, 6, 3 );
findContours( canny, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );

for( int i = 0; i<contours.size(); i++ ) {
  // ??
}

bool isLineAlreadyFound(const Vec4i& _l1, const Vec4i& _l2) {
    Vec4i l1(_l1), l2(_l2);

    float length1 = sqrtf((l1[2] - l1[0])*(l1[2] - l1[0]) + (l1[3] - l1[1])*(l1[3] - l1[1]));
    float length2 = sqrtf((l2[2] - l2[0])*(l2[2] - l2[0]) + (l2[3] - l2[1])*(l2[3] - l2[1]));

    float product = (l1[2] - l1[0])*(l2[2] - l2[0]) + (l1[3] - l1[1])*(l2[3] - l2[1]);

    if (fabs(product / (length1 * length2)) < cos(CV_PI / 30))
        return false;

    float mx1 = (l1[0] + l1[2]) * 0.5f;
    float mx2 = (l2[0] + l2[2]) * 0.5f;

    float my1 = (l1[1] + l1[3]) * 0.5f;
    float my2 = (l2[1] + l2[3]) * 0.5f;
    float dist = sqrtf((mx1 - mx2)*(mx1 - mx2) + (my1 - my2)*(my1 - my2));

    if (dist > std::max(length1, length2) * 0.5f)
        return false;

    return true;
}

【问题讨论】:

  • 任意大小和旋转使这成为一个难题。是否有一组特定的旋转,例如 45 度的倍数?
  • @stark:一点也不。当然,这不是 C++ 问题。在模式识别中,这是微不足道的。
  • 微不足道?然而 3 个完全不同的答案。这些都没有建议如何识别结果模式的顶部或底部。

标签: c++ opencv image-processing template-matching


【解决方案1】:

这就是我将如何解决您的问题。

  • 既然你的图案是全黑的,也许你可以从中受益 并且只是做一个门槛。尝试一个非常低的阈值(如果它是一个完美的 黑色,使用 1 作为阈值)。

  • 经过上述步骤,使用 findContours 应该已经做好了 检测形状。但是您需要一种方法来识别您的 图案。由于您的模式可能会以不同的比例显示和/或 方向,您将需要一个比例/方向不变描述符。一世 这里的意思是一个形状描述符。你可以看看 https://en.wikipedia.org/wiki/Image_moment胡时刻。

  • 这将仅适用于每个模式中的一个柱。你应该完成 通过为您的模式设计一个特定的特征来进行搜索 从每个条中提取的特征的帮助。

【讨论】:

    【解决方案2】:

    这里的窍门是你有 14 条平行边。这些是不可能错过的。如其他答案所述,隔离它们的阈值。紧接着,运行边缘检测器。这会将黑白边缘变成线条,而图像的其余部分可能会产生一些分散的像素。将其可视化以自己查看。

    接下来,从 OpenCV 运行霍夫变换。这为您提供格式为 {offset, direction} 的行。即便是一些零散的背景像素碰巧排成一列,也不会形成14条方向一致的线。

    您可以计算最大偏移差以找到条形图案的比例,并仔细检查相对偏移量以检查各个条形的宽度和间距。请记住,这 14 条线是边,因此您需要将它们配对。

    此时您已经确定了条形图案的方向和比例。意识到您实际上并没有确定实际的条形位置可能有点令人惊讶。这个过程的原因是我们首先解决难题。我们现在回到边缘检测的输出,并将那里的所有边缘分为三类:平行边缘、两对平行边缘之间的圆形端盖(跟随轮廓)和随机背景像素。您可能需要 MORPH_CLOSE 操作来缩小轮廓中的间隙。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-27
      • 2013-01-23
      • 2019-10-17
      • 1970-01-01
      相关资源
      最近更新 更多