2013-07-05 132 views
3

这是示例图像:检测闭合轮廓

screenshot

和我使用的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

我不太清楚,但你尝试使用凸的凸形轮廓'输出(检查)'?像'contourhulled = cv2.convexHull(contour); cv2.isContourConvex(contourhulled)'。 – Jason

回答

1

如果您的示例图像是一个位图,即使一个像素已经有一个区域,所以它也有一个轮廓。闭环甚至有两个轮廓,一个在内侧,一个在外侧。半圈只有一个,跨越内外,在两端做掉头。

我想你想把这两个圆看作曲线,确实没有区域,只有一个“轮廓”。圆将是一个闭合的曲线,半圆将是开放的。如果是这样的话,你的新问题就是将位图变成曲线。这并不是微不足道的,尽管我们人类很容易察觉那里的曲线,因为它需要定义一个算法和参数来将一个区域变成曲线。

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

0

根据定义,闭合轮廓将具有单独的内部轮廓。
看的findContours()hierarchy论点:

层次 - 可选输出向量,关于 图像拓扑包含的信息。它具有与轮廓数量一样多的元素。对于 ,每个第i个轮廓轮廓[i],元素层次结构[i] [0], hierarchy i,hiearchy [i] [2]和hiearchy [i] [3]设置为 基于0的索引在下一个轮廓和上一个轮廓的相同层次级别,第一个子轮廓和父轮廓中分别显示轮廓。如果对于轮廓i,没有下一个, 先前,父级或嵌套轮廓,则层次结构[i]的相应元素将为负数。

+0

不完全如您在我的示例('cv2.RETR_EXTERNAL')中看到的那样,没有内部轮廓。无论如何,如果你可以从你引用的文档中推断出一种方法,请明确地提出它,以便我们可以看到你的想法在行动。谢谢 – theta

+0

轮廓永远不会有重复点。这是设计。尝试用一个像素或2来扩大图像,以避免1像素粗线条。这应该给你一个内部的轮廓。 –

+0

你写的东西看起来不正确。无论什么扩张,'cv2.RETR_EXTERNAL'总是只返回外部轮廓,即使轮廓线宽度为1px,其他模式也会始终返回外部轮廓和内部轮廓。 – theta

0

这不完全是python的答案,可能为时已晚。根据我对Emgu的经验,零面积的任何轮廓均未关闭。 您也可以将该区域与其周边作为额外支票进行比较,如果它非常小,那么它绝对不会关闭。不规则的形状有时沿其轮廓的某处有一个小小的封闭区域。

轮廓区域可以从

获得
cvContourArea 

轮廓周长Emgu被定义为

cvArcLength(contour, CV_WHOLE_SEQ, 1);