我正在使用 OpenCV 检测二进制图像中的椭圆,如下所示。在图像中,有八个椭圆需要检测。我可以使用 findContours 获得很多轮廓,包括八个椭圆。问题是:我如何判断哪个是椭圆哪个不是?如何删除所有其他错误检测?
我正在使用 OpenCV 检测二进制图像中的椭圆,如下所示。在图像中,有八个椭圆需要检测。我可以使用 findContours 获得很多轮廓,包括八个椭圆。问题是:我如何判断哪个是椭圆哪个不是?如何删除所有其他错误检测?
在这种特定情况下,霍夫圆变换可能是最简单的解决方案。
复制教程中的代码并将参数更改cv::HoughCircles()
为:
/// Apply the Hough Transform to find the circles
HoughCircles( src_gray, circles, CV_HOUGH_GRADIENT, 1, 10, 40, 30, 0, 0 );
输出:
但我喜欢@George 的想法,随它去吧,它比指定硬编码常量更健壮。我的方法对这张图片很有效,但是如果你有不同大小的圆圈和东西的图片,你想使用cv::minEnclosingCircle()
.
一个选项有点老套:在 findContours 之上使用minEnclosureCircle并按 min 过滤轮廓。基于阈值的封闭半径(删除小于半径 A(删除小斑点)和大于半径 B(删除大斑点))。您还可以尝试minAreaRect并检查宽度/高度比以寻找均匀的斑点而不是高/宽的斑点。
不那么 hacky 的解决方案是使用 Hough 变换。看看霍夫圆和教程
现在我想我已经使用自己的算法成功地解决了这个问题。只需发布它以供将来参考。
如下图,所有的椭圆都可以准确定位。并且成功去除了错误检测。另一方面,该算法非常省时:在我的普通桌面上处理所有图像只需 0.03 秒。图像尺寸:448x336 像素
算法过程:
编辑: 对 George Profenza 和 karlphillip 的回答的评论。 感谢 George Profenza 和 karlphillip 的回答。但是,他们的回答并不能很好地解决问题。George Profenza 给出的第一个想法是为轮廓的大小设置阈值。事实上,我已经在我的算法中使用了它。但显然这是算法的初步步骤。有很多“好”尺寸的错误检测。George Profenza 的第二个想法是使用 HoughCircles,也是由 karlphillip 提出的。HoughCircles 的问题是:(a)它很慢,而我需要在嵌入式系统中实时实现算法。(b) 它只能检测圆形而不能检测椭圆。当然,当椭圆接近圆时,它也有效。但对于一般情况,它不会。此外,我上面的方法无法检测到“图 8”。这是一个大问题,我仍在努力。
虽然之前已经接受了另一个答案,但是有几个选项需要探索,所以我会添加另一个答案。假设 Hough 方法对您的应用程序来说足够快,这里有一些有趣的替代方案:
我还可以补充一点,霍夫可能是可靠地检测椭圆的“正确”方法,但您可能会遇到额外的挑战。您表示 Hough circles 在您的桌面上足够快,但桌面的性能与嵌入式系统匹配程度如何?嵌入式系统有浮点单元吗?如果不是,请不要对软件模拟浮点所表现出的性能过于担心。您仍然可以使用定点数学、查找表等令人满意地实现 Hough 算法。