检测闭合轮廓

the*_*eta 5 python opencv

这是示例图像:

屏幕截图

我使用opencv来检测轮廓:

>>> fc = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
>>> contours = fc[0]
Run Code Online (Sandbox Code Playgroud)

为了检测闭合轮廓,我想检查一下opencv返回的每个轮廓中的起点和终点,而我注意到无论对象的形状如何,opencv似乎都在勾勒出每个对象的轮廓,因此我得到了以下结果:

>>> for contour in contours:
>>>    print(contour[0,:,:], contour[-1,:,:])
[[246  38]] [[247  38]]
[[92 33]] [[93 33]]
Run Code Online (Sandbox Code Playgroud)

或找到的每个轮廓都有闭合的路径。

我搜索了findContour()函数中可用方法的其他常量,但似乎所有常量都返回闭合路径。

那么,有什么通用的方法可以检测发现的轮廓是否闭合?


我在提出要求之前先用Google搜索,但没有得到结果,但是我在右侧的类似问题中看到了很好的候选人:我怎么知道在opencv中轮廓是打开还是关闭?建议在哪里使用cv2.isContourConvex(contour),但是:

>>> for contour in contours:
>>>    print(cv2.isContourConvex(contour))
False
False
Run Code Online (Sandbox Code Playgroud)

另一个更新:ContourArea看起来可以提供答案(至少对于简单的轮廓),但是我没有在示例图像之上进行任何其他测试:

>>> for contour in contours:
>>>     print(cv2.contourArea(contour))
0.0
12437.5
Run Code Online (Sandbox Code Playgroud)

Max*_*Max 6

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

经历这..

for i in contours: print(cv2.contourArea(i), cv2.arcLength(i,True))

我注意到,封闭轮廓(如圆)具有较高的contourAreaarcLength,而开放式轮廓(如线)具有较低的contourAreaarcLength,所以你可以过滤它们的方式...

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)
Run Code Online (Sandbox Code Playgroud)

我知道这是 3 年前提出的问题,但对于其他需要一个想法的人来说,这对我有用!


Ulr*_*rdt 1

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

我想您想将这两个圆视为确实没有面积并且只有一个“轮廓”的曲线。那么该圆将是一条闭合曲线,而半圆将是开放的。如果是这种情况,您的新问题是将位图转换为曲线。这并不是微不足道的,尽管我们人类很容易感知那里的曲线,因为它需要定义将一个区域变成曲线的算法和参数。

我知道的一种方法是从位图派生一个骨架,它基本上剥离外部的像素层,直到只剩下一堆连接点。我不熟悉 opencv,但我可以想象它已经有一些实用程序了。另外,搜索“curve line detector opencv”会出现opencv-identifying-lines-and-curves作为这里的第一个链接,以及一堆其他点击。