【发布时间】:2021-06-30 22:12:06
【问题描述】:
我是 OpenCV 新手,问题是我需要获取所有轮廓点。这很容易在 findContours 方法中设置 cv2.RETR_TREE 模式。事情是这样,返回冗余坐标。所以,例如,在这个多边形中,我不想得到这样的轮廓点:
所以根据第一张图像,绿色是使用 RETR_TREE 模式检测到的轮廓,而点 1-2、3-5、4-6、... 是多余的,因为它们彼此非常接近。我需要将这些冗余点合二为一,并将其附加到 customContours 数组中。 目前,我只有第一张图片的代码,设置点之间的距离和点坐标:
def getContours(img, minArea=20000, cThr=[100, 100]):
font = cv2.FONT_HERSHEY_COMPLEX
imgColor = img
imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
imgBlur = cv2.GaussianBlur(imgGray, (5, 5), 1)
imgCanny = cv2.Canny(imgBlur, cThr[0], cThr[1])
kernel = np.ones((5, 5))
imgDial = cv2.dilate(imgCanny, kernel, iterations=3)
imgThre = cv2.erode(imgDial, kernel, iterations=2)
cv2.imshow('threshold', imgThre)
contours, hierachy = cv2.findContours(imgThre, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
customContours = []
for cnt in contours:
area = cv2.contourArea(cnt)
if area > minArea:
peri = cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, 0.009*peri, True)
bbox = cv2.boundingRect(approx)
customContours.append([len(approx), area, approx, bbox, cnt])
print('points: ', len(approx))
n = approx.ravel()
i = 0
for j in n:
if i % 2 == 0:
x = n[i]
y = n[i + 1]
string = str(x)+" " + str(y)
cv2.putText(imgColor, str(i//2+1) + ': ' + string, (x, y), font, 2, (0, 0, 0), 2)
i = i + 1
customContours = sorted(customContours, key=lambda x: x[1], reverse=True)
for cnt in customContours:
cv2.drawContours(imgColor, [cnt[2]], 0, (0, 0, 255), 5)
return imgColor, customContours
你能帮我了解一下关于第二张图片的真正要点吗?
(编辑 01/07/21)
我想要一个通用的解决方案,因为图像可能更复杂,例如下图: 注意: 注意中间的箭头(点 17 和 18)没有封闭区域,所以不是要研究的多边形。那么,那个区域就没有兴趣获得他的积分。另外,注意点的顺序并不重要,但如果入口是孔图像,它应该知道有 4 个多边形,所以每个多边形的点从 0 开始,然后是 1,等等。
【问题讨论】:
-
获得“内部”轮廓的原因是边缘检测器 - 这会产生两个边缘:第一个是第一个零交叉,当像素强度沿一个维度(水平或垂直)从
255更改为0。第二条边产生于第二个零交叉点,从0到255。您是否正在检测边缘以检测三角形的中间部分(最后一张图像中的点 2 到 5)?您是否只对获取点列表(上一张图像中的 1 到 4 点)感兴趣,还是需要完整的轮廓?
标签: python-3.x opencv computer-vision canny-operator