这是示例图片:
我使用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()
函数中搜索了可用方法的其他常量,但它似乎都返回了闭路径。
是否有一些检测发现轮廓是否已关闭的一般方法?
我在搜索之前用Google搜索并且没有得到结果,但我在右侧看到类似问题的好候选人:How can i know if a contour is open or closed in opencv?建议我使用cv2.isContourConvex(contour)
,但是:
>>> for contour in contours:
>>> print(cv2.isContourConvex(contour))
False
False
还有另一个更新:contourArea看起来它可能提供答案(至少对于简单的轮廓)但我没有测试其他任何内容,然后上面的示例图像:
>>> for contour in contours:
>>> print(cv2.contourArea(contour))
0.0
12437.5
答案 0 :(得分:1)
如果您的示例图像是位图,即使单个像素也有一个区域,因此它也具有轮廓。封闭的圆圈甚至有两个轮廓,一个在内侧,一个在外侧。半圆只有一个,横跨内外,并在末端掉头。
我想你想把这两个圆视为确实没有区域而只有一个“轮廓”的曲线。然后圆圈将是一条闭合曲线,半圆将是开放的。如果是这种情况,您的新问题是将位图转换为曲线。这并非易事,即使我们人类容易在那里感知曲线,因为它需要定义一个算法和参数,将一个区域变成一条曲线。
我知道的一种方法是从位图中导出一个骨架,它基本上剥离了外面的像素层,直到你只剩下一堆连接点。我不熟悉opencv,但我可以想象它已经有了一些实用工具。此外,搜索“曲线检测opencv”会在此处显示opencv-identifying-lines-and-curves作为第一个链接,以及其他一些点击。
答案 1 :(得分:0)
根据定义,闭合轮廓将具有单独的内部轮廓
查看findContours()
的hierarchy
参数:
层次结构 - 可选输出向量,包含有关的信息 图像拓扑。它具有与轮廓数量一样多的元素。对于 每个第i个轮廓轮廓[i],元素层次[i] [0], hiearchy i,hiearchy [i] [2]和hiearchy [i] [3]设置为 基于0的指数在下一轮和前一轮的轮廓中 相同的层次级别,第一个子轮廓和父级 轮廓,分别。如果轮廓i没有下一个, previous,parent或嵌套轮廓,相应的元素 等级[i]将是否定的。
答案 2 :(得分:0)
我自己遇到了这个问题,并且找到了解决方法...
正在经历这个..
for i in contours:
print(cv2.contourArea(i), cv2.arcLength(i,True))
我注意到,闭合轮廓(例如,圆)的contourArea
比arcLength
高,而开放轮廓(例如,线)的contourArea
比arcLength
低,
这样就可以对它们进行过滤...
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)
我知道这是3年前问过的,但是对于其他需要这个想法对我有用的人!