我有这样的图像:
我需要在黑暗区域插入椭圆(注意:必须是椭圆,而不是圆形)。在OpenCV中执行此操作的最佳方法是什么?到目前为止,我的第一步是对其应用自适应(Otsu)阈值,这导致:
但我不知道从那里去哪里。我正在用Python编写应用程序,但它更多的是我正在寻找的算法设计。
根据回复/评论编辑:
好的,所以我已经尝试了形态学。基于OpenCV documentation,我对它进行了3次迭代“近距离”操作(扩张,然后侵蚀)以去除小颗粒,这导致:
然后,为了将它扩展回原来的形状,我进行了3次迭代“打开”操作(侵蚀,然后扩张),这导致:
从这里开始,我做了Canny边缘检测,结果是:
现在,我使用了findContours
,但遇到了一个问题。它沿边缘发现了数十个轮廓,每个轮廓沿圆周呈短段。这意味着,即使我采用最大尺寸轮廓,它也可能仅占圆周的10%,这不足以精确地拟合椭圆。这就是为什么@ Demi-Lune建议的其他问题对我不起作用的原因;他们都有非常干净,锋利的边缘和findContours
找到一个很好的单一轮廓覆盖每个形状的整个perimiter,但这不会发生我的混乱图像。那么,从这里拟合椭圆的最佳方法是什么?
如果对象有圆形,那么使用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()
在对图像应用自适应阈值后,您可以使用morphological operations使用cv2.erode()
和cv2.dilate()
来平滑图像。通过这些操作,您将能够隔离主圆图像并去除小颗粒噪声。接下来,您可以使用cv2.findContours()
定位图像中的圆,并过滤最大尺寸轮廓。这将为您提供边界框坐标,您可以在其中找到圆的中心。一旦你有了中心坐标,你就可以适应你的日食。