我的形状像气泡。而且我只想检测出这种形状的椭圆,就像图像中带有绿色圆圈的椭圆一样。
我尝试了封闭形态,但是气泡的某些部分也被去除了。我使用的矩阵为20、20的内核。形状变得更加矩形。也许我必须更像这样更改内核矩阵:
0 1 0
1 1 1
0 1 0
我也尝试绘制凸包,但是它也没有效果。而且内部的凸包是不可能的。这是我绘制凸包的代码:
for i in range (max_index):
hull = cv2.convexHull(contours[i])
cv2.drawContours(image, [hull], 0, (0, 255, 0), 2)
我使用参数cv2.RETR_EXTERNAL
和cv2.CHAIN_APPROX_NONE
来检索轮廓
答案 0 :(得分:4)
这不是最聪明的方法。尽管有冗长的代码,但我在这里所做的实际上很简单。
首先,我得到了灰色图像并添加了许多模糊效果,并以您尝试的相同方式应用了阈值并找到了轮廓。然后,我取最大轮廓,并用fitEllipse
找到适合此轮廓的椭圆。这些全部在getEllipse
函数中。
在第一轮中,椭圆会偏斜,因为尾巴会挡住它。所以,我用这个不太好的椭圆来处理原始图像并再次尝试。
函数greyEllipse按椭圆过滤图像。因此,我使用第一次尝试得到的椭圆来处理原始图像,并突出显示第一个椭圆内的点。我将此图像用作第二轮的输入。
通过重复该过程,我第二次得到的最终椭圆就不会偏斜得多。
代码如下:
import cv2
import numpy as np
def getEllipse(imgray):
ret, thresh = cv2.threshold(imgray, 20, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU)
_, contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
maxArea = 0
best = None
for contour in contours:
area = cv2.contourArea(contour)
if area > maxArea :
maxArea = area
best = contour
ellipse = cv2.fitEllipse(best)
el = np.zeros(imgray.shape)
cv2.ellipse(el, ellipse,(255,255,255),-1)
return el
def grayEllipse(el, img):
el = np.dstack((el,el,el))
el = el*img
el = el/(255)
el = el.astype('uint8')
imgray = cv2.cvtColor(el, cv2.COLOR_BGR2LAB)[...,0]
return imgray
image = cv2.imread("./baloon.png", cv2.IMREAD_COLOR)
img = image.copy()
imgray = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)[...,0]
imgray = cv2.GaussianBlur(imgray, (79,79), 0)
el = getEllipse(imgray)
imgray = grayEllipse(el, img.copy())
imgray = cv2.GaussianBlur(imgray, (11,11), 0)
el = getEllipse(imgray)
imgray = grayEllipse(el, img.copy())
ret, thresh = cv2.threshold(imgray, 20, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU)
_, contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
maxArea = 0
best = None
for contour in contours:
area = cv2.contourArea(contour)
if area > maxArea :
maxArea = area
best = contour
ellipse = cv2.fitEllipse(best)
cv2.ellipse(image, ellipse, (0,255,0),3)
while True:
cv2.imshow("result", image)
k = cv2.waitKey(30) & 0xff
if k == 27:
break