【问题标题】:opencv: Using contours and Hough transform on rectangle detectionopencv:在矩形检测中使用轮廓和霍夫变换
【发布时间】:2025-12-30 00:15:09
【问题描述】:

我正在尝试使用不同的方法检测灰度图像中的白色矩形:轮廓检测和霍夫变换。不幸的是,我正在处理的图像存在一些限制,即

  1. 图像中有许多特征,矩形不是唯一的特征
  2. 矩形可以与其他特征合并(例如,矩形边缘之一可以与一条长直线重叠)
  3. 矩形可能包含一些其他特征(例如矩形内的字母、数字或某些徽标)
  4. 有些特征看起来像矩形(例如,字符“D”看起来像一个在右上角和右下角带有小圆弧的矩形;另一个例子是梯形而不是平行四边形)
  5. 矩形可以顺时针和逆时针旋转 0 到 15 度
  6. 在不同的光照条件下(例如 1 个像素间隙),线条可能会分成几条线,因此过滤线条的最小线条长度必须很短(例如在 Hough 变换中)
  7. 当最小线长度设置为较小值时,更常见的是同一条线在不同方向上出现重复线(即需要合并多条线)

对于轮廓方法,一些图像的轮廓被破坏了。此外,图像可能包含矩形等特征(例如字符“D”)。我不确定这是否是一个好方法。

我看到很多文章/论坛建议使用霍夫变换来检测矩形,如下面的帖子。不幸的是,我必须设置最小行长度的小值并且看到重复的行。我不知道如何处理上面提到的点(例如,结合所有重复的线并为每个边缘只选择一条线,如何区分大部分是线但带有像“D”这样的小弧线的特征,以及如何用一条边与一条长直线合并等来隔离正方形。

Hough transformation vs Contour detection for Rectangle recognition with perspective projection

欢迎提出任何建议!

编辑:添加一些图片

字符 D

带logo的矩形,边用长直线合并

梯形(顶部有阴影,底部形成梯形)

【问题讨论】:

  • 显示示例输入图像会有所帮助
  • @Antonio:图片已添加,谢谢:)

标签: c++ opencv image-processing hough-transform opencv-contour


【解决方案1】:

我建议您尝试在每张图像上使用binary threshold(自适应或其他),这将为您的轮廓检测提供一些清晰的线条。你也可以erode/dilate图片去噪点(比如第二张图片中的细线)

然后使用轮廓检测​​,计算轮廓,找到图像中具有四个边的最大对象(这可能就是您的对象)。

在使用二进制/腐蚀之前复制图像,这样一旦从轮廓检测中获得感兴趣区域,就可以将复制图像裁剪到该区域。

抱歉,示例链接是用 python 编写的,但我相信一旦你明白了,将它移植到 C++ 会很容易。

希望这会有所帮助。

编辑

刚刚自己尝试了上述方法,对每张图像进行阈值化,轮廓检测,然后在最大的一组轮廓周围绘制一个边界框。

下面看结果:

最大轮廓集周围的边界框

相同,绘制在原始图像上

【讨论】:

  • 我已经按照您过去的建议做过类似的事情。但是我发现在二进制阈值处理后,在不同的光照条件下,矩形的轮廓可以分成 2-3 半。在我看来,霍夫变换给出了更好的路线。我知道我们需要找到交点来获得矩形。但是,如果每条不同方向的边有多条线,你知道如何将这些线组合成一条线并找到交点吗?对于等高线方法,我认为这将比霍夫线更难组合等高线。
  • 如果您使用自适应阈值(如链接中所示),您应该会发现对象没有被分解,因为阈值是在几个局部区域中计算的,而不是整个图像,这将确保光照条件对最终得到的二进制文件的影响要小得多。如果你发现霍夫线能给你带来更好的结果,也许坚持下去,我发现它总是更容易适应你喜欢的东西来适应你的目的。如果您能够获得 XY 或线条的每一端,则可以根据围绕它的线条选择正确的线条
  • 我记得我也尝试过自适应阈值,但结果更差。对于霍夫变换,是否有一种常见的做法是“选择”正确的线,或者将线组合成一条线?
  • 我建议你重新审视阈值和轮廓,我刚刚尝试了一下,非常成功,我使用全局阈值获取二值图像,然后检测轮廓,并绘制边界框围绕最大的轮廓集,我将为您编辑带有图像的帖子
  • 非常感谢您的努力...但主要目标是仅识别矩形(例如自行车)并过滤掉所有其他矩形对象,例如字符“D”和梯形。如果我没有在问题中说清楚,我很抱歉。