Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何关闭轮廓上的轮廓而不是边缘-OpenCV_Python_Opencv - Fatal编程技术网

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

Python 如何关闭轮廓上的轮廓而不是边缘-OpenCV,python,opencv,Python,Opencv,Tl;DR:如何测量由等高线包围的面积,而不仅仅是等高线本身 我想在下图中找到物体的轮廓,并有一个适用于大多数情况的代码。 阈值和自适应阈值不能可靠地工作,因为光线变化。我使用了一个精明的边缘检测和检查该地区,以确保我找到了正确的轮廓。但是,有时,当存在无法通过形态学闭合的间隙时,形状是正确的,但区域是轮廓线而不是整个对象 我通常做的是使用,因为它返回对象周围的轮廓。但是,在这种情况下,对象沿顶部向内弯曲,凸出部分不再是该区域的良好近似值 我尝试使用,但返回的区域是轮廓线,而不是对象 如何

Tl;DR:如何测量由等高线包围的面积,而不仅仅是等高线本身

我想在下图中找到物体的轮廓,并有一个适用于大多数情况的代码。

阈值和自适应阈值不能可靠地工作,因为光线变化。我使用了一个精明的边缘检测和检查该地区,以确保我找到了正确的轮廓。但是,有时,当存在无法通过形态学闭合的间隙时,形状是正确的,但区域是轮廓线而不是整个对象

我通常做的是使用,因为它返回对象周围的轮廓。但是,在这种情况下,对象沿顶部向内弯曲,凸出部分不再是该区域的良好近似值

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

如何让approxPolyDP返回对象周围类似的闭合轮廓,就像convexHull函数一样?

使用上图对此进行说明的代码:

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 
下面是geosensor.net提供的一个非常有前途的示例,其中讨论了几种算法。我的建议是使用半径有限的摆臂法

我的另一个完全未经测试的脱离墙壁的想法是按行和列扫描图像(更多方向可提高精度)以及线交点之间区域的颜色:

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

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

您是否尝试减少epsilon值?@mika即使epsilon=0,问题仍然存在。添加第一个点,因为最后一个点不会改变区域,我尝试了。这看起来很有希望,我将尝试并报告!谢谢。我想举一个例子,但是spyder在我的工作计算机上因为文件夹权限而变得一团糟,我无法访问numpy或scipy:(