Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/280.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

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 检测闭合轮廓_Python_Opencv - Fatal编程技术网

Python 检测闭合轮廓

Python 检测闭合轮廓,python,opencv,Python,Opencv,这是示例图像: >>> for contour in contours: >>> print(cv2.contourArea(contour)) 0.0 12437.5 我使用opencv检测轮廓: >>> fc = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) >>> contours = fc[0] 为了检测闭合轮廓,我想检查

这是示例图像:

>>> for contour in contours:
>>>     print(cv2.contourArea(contour))
0.0
12437.5

我使用opencv检测轮廓:

>>> fc = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
>>> contours = fc[0]
为了检测闭合轮廓,我想检查opencv返回的每个轮廓的起点和终点,同时我注意到,无论对象的形状如何,opencv似乎都会勾勒出每个对象的轮廓,因此我得到以下结果:

>>> for contour in contours:
>>>    print(contour[0,:,:], contour[-1,:,:])
[[246  38]] [[247  38]]
[[92 33]] [[93 33]]
或者每个找到的轮廓都有闭合路径

我在
findContour()

那么,是否有一些通用的方法来检测找到的轮廓是否闭合


在提问之前我用谷歌搜索了一下,没有得到结果,但我在右侧类似的问题中看到了很好的候选人:建议我使用
cv2.isContourConvex(contour)
,但是:

>>> for contour in contours:
>>>    print(cv2.isContourConvex(contour))
False
False

还有一个更新:看起来它可能提供了答案(至少对于简单的轮廓),但除了上面的示例图像之外,我没有在任何其他方面进行测试:

>>> for contour in contours:
>>>     print(cv2.contourArea(contour))
0.0
12437.5

如果您的示例图像是位图,那么即使单个像素已经有一个区域,因此它也有一个轮廓。闭合圆甚至有两个轮廓,一个在内侧,一个在外侧。这个半圆只有一个,跨越内外,在两端掉头

我猜你想把这两个圆当作曲线,实际上没有面积,只有一个“轮廓”。然后,圆将是闭合曲线,半圆将是开放的。如果是这样的话,你的新问题就是把位图变成曲线。这并不是一件小事,即使我们人类很容易察觉到那里的曲线,因为它需要定义一个算法和参数,将一个区域变成一条曲线


我知道的一种方法是从位图中导出一个骨架,它基本上剥离了外部的像素层,直到只剩下一堆连接点。我不熟悉opencv,但我可以想象它已经有了一些实用程序。此外,搜索“curve line detect opencv”(曲线检测opencv)作为第一个链接出现在这里,还有一系列其他点击。

根据定义,闭合轮廓将具有单独的内部轮廓。
查看以下的
层次结构
参数:

层次结构–可选输出向量,包含有关 图像拓扑。它的元素数量与等高线的数量相同。对于 每个第i等高线[i],元素层次[i][0], hiearchy、hiearchy[i][2]和hiearchy[i][3]设置为 下一个和上一个等高线的等高线中基于0的索引 同一层级,第一个子轮廓和父轮廓 轮廓,分别。如果轮廓i没有下一个, 上一个、父轮廓或嵌套轮廓的对应元素 层次结构[i]将为负


这并不完全是python的答案,可能已经太晚了。根据我使用Emgu的经验,任何面积为零的轮廓都不是闭合的。 您还可以将该区域与其周长进行比较,作为额外检查,如果该区域非常小,则它绝对不会关闭。不规则形状有时在其轮廓的某个地方有一个很小的封闭区域

轮廓面积可从

cvContourArea
Emgu中的等高线周长定义为

cvArcLength(contour, CV_WHOLE_SEQ, 1);

我自己也遇到了这个问题,我找到了一个解决办法

经历这一切

对于等高线中的i:
打印(cv2.轮廓面积(i),cv2.弧长(i,真))

我注意到闭合轮廓(例如圆)的
轮廓面积
高于
弧长
,而开放轮廓(例如直线)的
轮廓面积
低于
弧长
, 所以你可以这样过滤它们

closed_contours = []
open_contours = []
for i in contours:
    if cv2.contourArea(i) > cv2.arcLength(i, True):
        closed_contours.append(i)
    else:
        open_contours.append(i)

我知道这是三年前提出的,但对于任何需要想法的人来说,这对我来说都是可行的

不完全是这样,正如您在我的示例(
cv2.RETR\u EXTERNAL
)中看到的,没有内部轮廓。无论如何,如果你能从你引用的文档中推断出一种方法,请明确地表达出来,这样我们就可以看到你的想法在起作用。谢谢轮廓永远不会有重复点。这是故意的。尝试将图像放大一个或两个像素,以避免出现1像素厚的线条。这应该给你一个内部轮廓。你写的似乎不正确。无论膨胀如何,
cv2.RETR\u EXTERNAL
始终只返回外部轮廓,而即使轮廓线为1px宽,其他模式也将始终返回外部轮廓和内部轮廓。我不太确定,但您是否尝试使用
converxhull()的输出检查凸面?像
contourhulled=cv2.convexHull(轮廓);cv2.isContourConvex(轮廓线)