OpenCV:使椭圆的轮廓上的点最多(而不是最小的正方形) [英] OpenCV: Fit ellipse with most points on contour (instead of least squares)

查看:128
本文介绍了OpenCV:使椭圆的轮廓上的点最多(而不是最小的正方形)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个二值化图像,我已经在其上使用了打开/关闭形态学操作(这很干净,请相信我),看起来像这样:

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:

如您所见,顶部有一个明显的椭圆形和一些变形.注意:我没有圈的大小的先验信息,并且它必须非常快地运行(我发现,HoughCircles太慢了.)将椭圆拟合到其上,以使其在拟合的椭圆上最大化与形状的边缘相对应的点数.也就是说,我想要这样的结果:

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:

但是,我似乎无法在OpenCV中找到一种方法来做到这一点.使用 fitEllipse (蓝线)和 minAreaRect (绿线)的常用工具,我得到以下结果:

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:

显然不代表我要检测的实际椭圆.关于如何实现此目标有任何想法吗?很高兴看到Python或C ++中的示例.

Which obviously do not represent the actual ellipse I'm trying to detect. Any thoughts as to how I could accomplish this? Happy to see examples in Python or C++.

推荐答案

鉴于显示的示例图像,我非常怀疑以下语句:

Given the shown example image, I was very skeptical of the following statement:

我已经在上面使用了打开/关闭形态学操作(这很干净,请相信我)

which I've already used open/close morphology operations on (this is as clean as I can get it, trust me on this)

而且,在阅读您的评论后,

And, after reading your comment,

为了精确起见,我需要使其精度在2像素左右以内

For precision, I need it to be fit within about 2 pixels accuracy

我很确定,使用形态学运算可能会有很好的近似值.

I was pretty sure, there might be good approximation using morphological operations.

请查看以下代码:

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)

中间图像如下:

然后,最终结果如下:

由于您的图片很大,我认为,缩小图片不会对您造成任何伤害.以下形态学操作(大量)加速了,您的设置可能对此很感兴趣.

Since your image is quite large, I think, no harm is done by downsizing it. The following morphological operations are (heavily) sped up, which might be of interest for your setting.

根据您的声明:

注意:我没有圈的大小的先验信息[...]

您几乎可以从您的输入中找到上述内核大小的适当近似值.由于仅提供了一个示例图像,因此我们无法知道该问题的可变性.

You can mostly find an appropriate approximation for the above kernel sizes from your inputs. Since there is only one example image given, we can't know the variability on that issue.

希望有帮助!

这篇关于OpenCV:使椭圆的轮廓上的点最多(而不是最小的正方形)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆