在最近的一组图像中,我的 OpenCV 代码无法找到轮廓的正确区域。这似乎发生在轮廓未闭合时。我试图确保轮廓关闭无济于事。
编辑:问题在于轮廓中存在间隙。
背景: 我在一个 channel 中有一系列胶囊图像,我想测量形状的面积以及时刻的质心。
问题: 当轮廓不闭合时,力矩是错误的。
编辑:当我有间隙时,轮廓不是整个形状,因此区域不正确。
我的工作:
- 读取图像 -> img =cv2.imread(fileName,0)
- 应用 Canny 过滤器 -> edges = cv2.Canny(img,lowerThreshold,lowerThreshold*2)
- 查找轮廓 -> 轮廓,hierarchy = cv2.findContours(edges,cv2.cv.CV_RETR_LIST,cv2.cv.CV_CHAIN_APPROX_NONE)
- 找到最长的轮廓
- 确保轮廓闭合
- 寻找时刻 -> cv2.moments(cnt)
可以找到带有测试图像的工作示例 here .
有一个question关于关闭轮廓,但这些建议均无效。使用 cv2.approxPolyDP 不会改变结果,尽管它应该返回一个封闭的轮廓。添加轮廓的第一个点作为最后一个点,以使其闭合,也不能解决问题。
下面是一个带有轮廓绘制的图像示例。在这里,该区域被确定为 85,而在几乎相同的图像中它是 8660,这是它应该是的。
如有任何建议,我们将不胜感激。
代码:
img =cv2.imread(fileName,0)
edges = cv2.Canny(img,lowerThreshold,lowerThreshold*2)
contours, hierarchy = cv2.findContours(edges,cv2.cv.CV_RETR_LIST,cv2.cv.CV_CHAIN_APPROX_NONE) #cv2.cv.CV_CHAIN_APPROX_NONE or cv2.cv.CV_CHAIN_APPROX_SIMPLE
#Select longest contour as this should be the capsule
lengthC=0
ID=-1
idCounter=-1
for x in contours:
idCounter=idCounter+1
if len(x) > lengthC:
lengthC=len(x)
ID=idCounter
if ID != -1:
cnt = contours[ID]
cntFull=cnt.copy()
#approximate the contour, where epsilon is the distance to
#the original contour
cnt = cv2.approxPolyDP(cnt, epsilon=1, closed=True)
#add the first point as the last point, to ensure it is closed
lenCnt=len(cnt)
cnt= np.append(cnt, [[cnt[0][0][0], cnt[0][0][1]]])
cnt=np.reshape(cnt, (lenCnt+1,1, 2))
lenCntFull=len(cntFull)
cntFull= np.append(cntFull, [[cntFull[0][0][0], cntFull[0][0][1]]])
cntFull=np.reshape(cntFull, (lenCntFull+1,1, 2))
#find the moments
M = cv2.moments(cnt)
MFull = cv2.moments(cntFull)
print('Area = %.2f \t Area of full contour= %.2f' %(M['m00'], MFull['m00']))
最佳答案
我的问题是,正如@HugoRune 所指出的,countour 中存在差距。解决办法是缩小差距。
我发现很难找到一种通用的方法来缩小差距,所以我反复更改 Canny 过滤器的阈值并执行 morphological closing直到找到闭合轮廓。
关于python - 查找 OpenCV 轮廓的面积,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29700952/