首页 文章

如何在轮廓而不是边缘上关闭轮廓 - OpenCV

提问于
浏览
3

Tl;DR: How to measure area enclosed by contour rather than just the contour line itself

我想在下面的图像中找到对象的轮廓,并且有一个适用于大多数情况的代码 .
Original Image

当ligthing改变时,阈值处理和adpative阈值处理不能可靠地工作 . 我使用Canny边缘检测并检查区域以确保我找到了正确的轮廓 . 然而,偶尔,当存在无法通过形态学闭合闭合的间隙时,形状是正确的但是该区域是轮廓线而不是整个对象 .

Canny Contour Output

我通常做的是使用convexHull,因为它返回对象周围的轮廓 . 然而,在这种情况下,物体沿顶部向内弯曲,而凸部则不再是该区域的良好近似 .

Contour after Convex Hull

我尝试使用approxPolyDP但返回的区域是轮廓线而不是对象 .

How can I get the approxPolyDP to return a similar closed contour around the object, just like the convexHull function does?

用上面的图片说明这个代码:

import cv2
img = cv2.imread('Img_0.jpg',0)
cv2.imshow('Original', img)

edges = cv2.Canny(img,50,150) 
cv2.imshow('Canny', edges)

contours, hierarchy = cv2.findContours(edges,cv2.cv.CV_RETR_EXTERNAL,cv2.cv.CV_CHAIN_APPROX_NONE)

cnt = contours[1] #I have a function to do this but for simplicity here by hand

M = cv2.moments(cnt) 
print('Area = %f \t' %M['m00'], end="")

cntHull = cv2.convexHull(cnt, returnPoints=True)
cntPoly=cv2.approxPolyDP(cnt, epsilon=1, closed=True)
MHull = cv2.moments(cntHull)
MPoly = cv2.moments(cntPoly)
print('Area after Convec Hull = %f \t Area after apporxPoly = %f \n' %(MHull['m00'], MPoly['m00']), end="")

x, y =img.shape
size = (w, h, channels) = (x, y, 1)
canvas = np.zeros(size, np.uint8)
cv2.drawContours(canvas, cnt, -1, 255)
cv2.imshow('Contour', canvas)

canvas = np.zeros(size, np.uint8)
cv2.drawContours(canvas, cntHull, -1, 255)
cv2.imshow('Hull', canvas)

canvas = np.zeros(size, np.uint8)
cv2.drawContours(canvas, cntPoly, -1, 255)
cv2.imshow('Poly', canvas)

代码的输出是

Area = 24.500000    Area after Convec Hull = 3960.500000     Area after apporxPoly = 29.500000

1 回答

  • 1

    这是来自geosensor.net的非常有前途的ppt,它讨论了几种算法 . 我的建议是使用半径有限的摆臂法 .

    另一个完全没有经过测试的离墙概念是通过行和列扫描图像(更多方向增加精度)和线交叉点之间区域的颜色:

    _______
             /-------\
            /---------\
    --------+---------+------ (fill between 2 intersections)     
            |         |
            |
    --------+---------------- (no fill between single intersection)
             \
              -------
    

    随着扫描的线方向数量增加(超过90度和45度),最大误差将减小 . 获得最终区域就像像素数一样简单 .

相关问题