OpenCV:用轮廓上的大多数点拟合椭圆(而不是最小二乘)

2024-03-22

I have a binarized image, which I've already used open/close morphology operations on (this is as clean as I can get it, trust me on this) that looks like so: enter image description here

As you can see, there is an obvious ellipse with some distortion on the top. NOTE: I do not have prior info as to the size of the circle, and this has to run very quickly (HoughCircles is too slow, I've found). I'm trying to figure out how to fit an ellipse to it, such that it maximizes the number of points on the fitted ellipse that correspond to edges on the shape. That is, I want a result like this: enter image description here

However, I can't seem to find a way in OpenCV to do this. Using the common tools of fitEllipse (blue line) and minAreaRect (green line), I get these results: enter image description here

这显然不代表我试图检测的实际椭圆。关于我如何实现这一目标有什么想法吗?很高兴看到 Python 或 C++ 中的示例。


鉴于所显示的示例图像,我对以下陈述非常怀疑:

我已经使用过开/关形态学操作(这是我能得到的最干净的,相信我)

并且,在阅读了您的评论后,

为了精度,我需要它的精度在大约 2 像素以内

我非常确定,使用形态学运算可能会得到很好的近似。

请看一下下面的代码:

import cv2

# Load image (as BGR for later drawing the circle)
image = cv2.imread('images/hvFJF.jpg', cv2.IMREAD_COLOR)

# Convert to grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# Get rid of possible JPG artifacts (when do people learn to use PNG?...)
_, gray = cv2.threshold(gray, 128, 255, cv2.THRESH_BINARY)

# Downsize image (by factor 4) to speed up morphological operations
gray = cv2.resize(gray, dsize=(0, 0), fx=0.25, fy=0.25)

# Morphological Closing: Get rid of the hole
gray = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)))

# Morphological opening: Get rid of the stuff at the top of the circle
gray = cv2.morphologyEx(gray, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (121, 121)))

# Resize image to original size
gray = cv2.resize(gray, dsize=(image.shape[1], image.shape[0]))

# Find contours (only most external)
cnts, _ = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

# Draw found contour(s) in input image
image = cv2.drawContours(image, cnts, -1, (0, 0, 255), 2)

cv2.imwrite('images/intermediate.png', gray)
cv2.imwrite('images/result.png', image)

中间图像如下所示:

并且,最终结果如下所示:

由于您的图像相当大,我认为缩小它不会有什么坏处。以下形态学操作(大大)加速,这可能对您的设置感兴趣。

根据你的说法:

注意:我没有关于圆圈大小的事先信息[...]

您通常可以从输入中找到上述内核大小的适当近似值。由于只给出了一张示例图像,我们无法知道该问题的可变性。

希望有帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenCV:用轮廓上的大多数点拟合椭圆(而不是最小二乘) 的相关文章

随机推荐