0
点赞
收藏
分享

微信扫一扫

【opencv】轮廓分层()

young_d807 2022-01-11 阅读 79

目录

理论

OpenCV中的分级表示

轮廓检索模式

1. RETR_LIST

2. RETR_EXTERNAL

3. RETR_CCOMP

4. RETR_TREE


例如,在我们的图片中取contour-0。谁是下一个同级别的等高线?这是contour-1。简单地令Next = 1。类似地,Contour-1也是contour-2。所以Next = 2。 contour-2呢?同一水平线上没有下一条等高线。简单地,让Next = -1。contour-4呢?它与contour-5处于同一级别。它的下一条等高线是contour-5,所以next = 5

和上面一样。contour-1之前的等值线为同级别的contour-0。类似地,contour-2也是contour-1。对于contour-0,没有前项,所以设为-1。

没有必要作任何解释。对于contour-2, child是contour-2a。从而得到contour-2a对应的指标值。contour-3a呢?它有两个孩子。但我们只关注第一个孩子。它是contour-4。那么First_Child = 4 对contour-3a而言。

它与**First_Child**相反。对于轮廓线-4和轮廓线-5,父轮廓线都是轮廓线-3a。对于轮廓3a,它是轮廓-3,以此类推。

现在我们已经了解了OpenCV中使用的层次样式,我们可以借助上面给出的相同图像来检查OpenCV中的轮廓检索模式。一些标志如 cv.RETR_LISTcv.RETR_TREE,cv.RETR_CCOMP, **cv.RETR_EXTERNAL**等等的含义。

轮廓检索模式

1. RETR_LIST

这是四个标志中最简单的一个(从解释的角度来看)。

  • 它只是检索所有的轮廓,但不创建任何亲子关系。
  • 在这个规则下,父轮廓和子轮廓是平等的,他们只是轮廓。他们都属于同一层级。

这里,第3和第4项总是-1。但是很明显,下一项和上一项都有对应的值。你自己检查一下就可以了。

下面是我得到的结果,每一行是对应轮廓的层次细节。例如,第一行对应于轮廓0。下一条轮廓是轮廓1。所以Next = 1。没有先前的轮廓,所以Previous=-1。剩下的两个,如前所述,是-1

>>> hierarchy
array([[[ 1, -1, -1, -1],
        [ 2,  0, -1, -1],
        [ 3,  1, -1, -1],
        [ 4,  2, -1, -1],
        [ 5,  3, -1, -1],
        [ 6,  4, -1, -1],
        [ 7,  5, -1, -1],
        [-1,  6, -1, -1]]])

如果您没有使用任何层次结构特性,那么这是在您的代码中使用的最佳选择。

2. RETR_EXTERNAL

如果使用此标志,它只返回极端外部标志。所有孩子的轮廓都被留下了。我们可以说,根据这项规则,每个家庭只有长子得到关注。它不关心家庭的其他成员:)

所以在我们的图像中,有多少个极端的外轮廓?在等级0级?有3个,即等值线是0 1 2,对吧?现在试着用这个标志找出等高线。这里,给每个元素的值与上面相同。并与上述结果进行了比较。以下是我得到的:

>>> hierarchy
array([[[ 1, -1, -1, -1],
        [ 2,  0, -1, -1],
        [-1,  1, -1, -1]]])
如果只想提取外部轮廓,可以使用此标志。它在某些情况下可能有用。

3. RETR_CCOMP

此标志检索所有轮廓并将其排列为2级层次结构。

  • 物体的外部轮廓(即物体的边界)放在层次结构-1中。
  • 对象内部孔洞的轮廓(如果有)放在层次结构-2中。

如果其中有任何对象,则其轮廓仅在层次结构1中重新放置。以及它在层级2中的漏洞等等。

只需考虑在黑色背景上的“白色的零”图像。零的外圆属于第一级,零的内圆属于第二级。

我们可以用一个简单的图像来解释它。这里我用红色标注了等高线的顺序和它们所属的层次,用绿色标注(1或2),顺序与OpenCV检测等高线的顺序相同。

考虑第一个轮廓,即contour-0。这是hierarchy-1。它有两个孔,分别是等高线1和2,属于第二级。因此,对于轮廓-0,在同一层次的下一个轮廓是轮廓-3。previous也没有。在hierarchy-2中,它的第一个子结点是contour-1。它没有父类,因为它在hierarchy-1中。所以它的层次数组是[3,-1,1,-1]

现在contour-1。它在层级-2中。相同层次结构中的下一个(在contour-1的父母关系下)是contour-2。没有previous。没有child,但是parent是contour-0。所以数组是[2,-1,-1,0]

类似的contour-2:它在hierarchy-2中。在contour-0下,同一层次结构中没有下一个轮廓。所以没有Nextprevious是contour-1。没有childparent是contour0。所以数组是[-1,1,-1,0]

contour-3:层次-1的下一个是轮廓-5。以前是contour-0。child是contour4,没有parent。所以数组是[5,0,4,-1]

contour-4:它在contour-3下的层次结构2中,它没有兄弟姐妹。没有next,没有previous,没有childparent是contour-3。所以数组是[-1,-1,-1,3]

剩下的你可以补充。这是我得到的最终答案:

>>> hierarchy
array([[[ 3, -1,  1, -1],
        [ 2, -1, -1,  0],
        [-1,  1, -1,  0],
        [ 5,  0,  4, -1],
        [-1, -1, -1,  3],
        [ 7,  3,  6, -1],
        [-1, -1, -1,  5],
        [ 8,  5, -1, -1],
        [-1,  7, -1, -1]]])

4. RETR_TREE

它检索所有的轮廓并创建一个完整的家族层次结构列表。它甚至告诉,谁是爷爷,父亲,儿子,孙子,甚至更多…:)。

例如,我拿上面的图片,重写了cv的代码。RETR_TREE,根据OpenCV给出的结果重新排序等高线并进行分析。同样,红色的字母表示轮廓数,绿色的字母表示层次顺序。

contour-0:它在hierarchy-0中。同一层次结构的next轮廓是轮廓-7。没有previous的轮廓。child是contour-1,没有parent。所以数组是[7,-1,1,-1]

contour-2为例:它在hierarchy-1中。没有轮廓在同一水平。没有previouschildcontour-3。父母是contour-1。所以数组是[-1,-1,3,1]

剩下的,你自己试试。以下是完整答案:

>>> hierarchy
array([[[ 7, -1,  1, -1],
        [-1, -1,  2,  0],
        [-1, -1,  3,  1],
        [-1, -1,  4,  2],
        [-1, -1,  5,  3],
        [ 6, -1, -1,  4],
        [-1,  5, -1,  4],
        [ 8,  0, -1, -1],
        [-1,  7, -1, -1]]])
举报

相关推荐

0 条评论