繁体   English   中英

OpenCV:将单个圆拟合到图像(在 Python 中)

[英]OpenCV: Fitting a single circle to an image (in Python)

我有这样的图像:

在此处输入图片说明

我需要在黑暗区域拟合一个椭圆(注意:必须是椭圆,而不是圆)。 在 OpenCV 中执行此操作的最佳方法是什么? 到目前为止,我的第一步是对其应用自适应 (Otsu) 阈值,结果是:

在此处输入图片说明

但我不确定从那里去哪里。 我正在用 Python 编写应用程序,但更多的是我正在寻找的算法设计。

基于响应/评论的编辑:

好的,所以我已经尝试了形态学。 根据OpenCV 文档,我对其进行了 3 次迭代“关闭”操作(扩张,然后侵蚀)以去除小颗粒,结果:

在此处输入图片说明

然后,为了将其扩展回更接近原始形状,我进行了 3 次迭代“打开”操作(腐蚀,然后膨胀),结果:

在此处输入图片说明

从这里开始,我做了 Canny 边缘检测,结果是:

在此处输入图片说明

现在,我在其上使用了findContours ,但遇到了问题。 它沿着边缘发现了几十个轮廓,每一个都是沿着圆周的一小段。 这意味着,即使我采用最大尺寸的轮廓,它也可能只代表周长的 10%,这不足以准确拟合椭圆。 这就是@Demi-Lune 建议的其他问题对我不起作用的原因; 它们都有非常干净、锐利的边缘, findContours找到了一个很好的单一轮廓,覆盖了每个形状的整个边界,但对于我的凌乱图像来说,这不会发生。 那么,从这里拟合椭圆的最佳方法是什么?

为什么不做“关闭”然后“打开”清除所有混乱的事情。

原始图片:

原始图像

大津:

大津

关闭+打开; 都是7x7内核; 二进制图像现在美观整洁。

关闭+打开

只检测到一个轮廓:

一个轮廓

椭圆如下:(请注意,您的图像是圆形,因此椭圆应为圆形)

椭圆

如果对象有圆形,那么使用cv2.minEnclosingCircle是好的。 或者,您可以使用cv2.fitEllipse查找对象周围最合适的椭圆。 记得在黑色背景中找到与白色物体的轮廓。

import cv2
import numpy as np

img = cv2.imread("1.jpg")

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_,thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
thresh = cv2.bitwise_not(thresh)

element = cv2.getStructuringElement(shape=cv2.MORPH_RECT, ksize=(5, 5))

morph_img = thresh.copy()
cv2.morphologyEx(src=thresh, op=cv2.MORPH_CLOSE, kernel=element, dst=morph_img)

contours,_ = cv2.findContours(morph_img,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

areas = [cv2.contourArea(c) for c in contours]
sorted_areas = np.sort(areas)

#bounding box (red)
cnt=contours[areas.index(sorted_areas[-1])] #the biggest contour
r = cv2.boundingRect(cnt)
cv2.rectangle(img,(r[0],r[1]),(r[0]+r[2],r[1]+r[3]),(0,0,255),2)

#min circle (green)
(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
cv2.circle(img,center,radius,(0,255,0),2)

#fit ellipse (blue)
ellipse = cv2.fitEllipse(cnt)
cv2.ellipse(img,ellipse,(255,0,0),2)


cv2.imshow("morph_img",morph_img)
cv2.imshow("img", img)
cv2.waitKey()

在此输入图像描述 在此输入图像描述

在对图像应用自适应阈值后,您可以使用形态学操作来使用cv2.erode()cv2.dilate()来平滑图像。 通过这些操作,您将能够隔离主圆图像并去除小颗粒噪声。 接下来,您可以使用cv2.findContours()并过滤最大尺寸轮廓来定位图像中的圆。 这将为您提供边界框坐标,您可以在其中找到圆的中心。 一旦你有了中心坐标,你就可以适应你的日食。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM