C++ OpenCV:检测两行而不是一行(Canny & findContours)

Posted

技术标签:

【中文标题】C++ OpenCV:检测两行而不是一行(Canny & findContours)【英文标题】:C++ OpenCV: Detecting two lines instead of one (Canny & findContours) 【发布时间】:2018-01-28 19:15:38 【问题描述】:

我目前正在从事一个基于检测图片中的轮廓的项目。我正在分析仅带有线条的图像,例如this rectangle,以及其他图片(也是彩色的)。问题是使用我的代码我得到一个image of "two rectangles",而不是一个。我理解其背后的原因:Canny 检测到线条两侧的边缘,因为渐变。但是,有什么办法可以去掉其中一个矩形(或其他图片中的线条)或将它们合并为一个?

我的代码片段:

cvtColor(source, imgGray, CV_RGB2GRAY);

GaussianBlur(imgGray, imgGauss, Size(5, 5), 1);

Canny(imgGauss, imgCanny, 100, 200);

findContours(imgCanny, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);

Mat imgDraw = Mat::zeros(imgCanny.size(), CV_8UC3);
for (int i = 0; i< contours.size(); i++)


    Scalar color(255, 255, 255);
    drawContours(imgDraw, contours, i, color, 1.5, 8, hierarchy, 0);

    cout << "Hierarchy: " << hierarchy[i] << endl;
    for (int j = 0; j < contours[i].size(); j++)
    
        cout << contours[i][j] << endl;
    

我尝试在findContours 中使用CV_RETR_CCOMP 模式,如示例代码 for drawContours function 中所示,但我得到了相同的结果。

我可能可以尝试几何图形比较,但据我所知,更复杂的形状(例如人脸)是行不通的。

另一个问题,为什么findContours 检测到四个轮廓而不是两个(对于这两个矩形)?

如果问题出现在其他地方,我很抱歉,如果你给我一个链接,我会很高兴。

【问题讨论】:

我已经有了,但据我了解,“霍夫线变换是一种用于检测直线的变换。”。正如我所提到的:矩形是一个例子,我也在处理更复杂的形状(例如画花、脸、猫......),其中不仅有直线,还有不规则曲线......跨度> findContours 有一个参数标志,只查找“外部”轮廓。使用它。 findContours使用标志cv2.RETR_EXTERNAL 我也试过了:CV_RETR_EXTERNAL模式只适用于最外轮廓。如果我有例如圆内的正方形,它只会找到圆的外部轮廓。我想知道是否有一种方法可以为一条线获得一个轮廓(通过删除一个轮廓或连接两个轮廓)。我想,没有,所以感谢所有的答案。 【参考方案1】:

任何边缘检测器都会检测从白色到黑色的过渡以及从黑色到白色的过渡。这就是为什么它会在您的线路中检测到两条边缘(线路的左侧和右侧)。

如果您使用填充的黑色方块进行测试,它只会检测到一个边缘。黑色背景中的实心白色方块也是如此。

对于线检测,霍夫变换可能更好。

对于第二个问题:Find contours 检测到一个白色正方形,里面有一个黑色正方形,里面有另一个白色正方形,里面有另一个黑色正方形。它看不到线条,它只看到一个在另一个里面的填充对象。在轮廓对象中,您可以获得正方形的颜色,它还告诉您轮廓是否在另一个轮廓内。也许你可以忽略另一个内部的轮廓。

【讨论】:

嗯,我知道 :) 我正在使用我的程序来处理多种图像(照片、也具有填充形状的图形)。这是一个特例。那么,没有已知的方法可以剪切出检测到的轮廓之一或合并它们吗? 您可以将 findContours 与 mode=CV_RETR_EXTERNAL 一起使用。这将只返回外部正方形

以上是关于C++ OpenCV:检测两行而不是一行(Canny & findContours)的主要内容,如果未能解决你的问题,请参考以下文章

使用 Restkit 上传图像 - 向 UITableView 添加两行而不是一行

PHP中的SQL插入两行而不是一行

如何自定义 Material ui 表格单元格,以便其中的文本将占用两行而不是一行?

jquery 数据表返回倒数第二行而不是最后一行

使用 OpenCV c++ 裁剪图像

如何更改此 C++ (OpenCV) 代码以获取图像而不是视频?