python-opencv Tutorials 一码人翻译(22)图像处理----轮廓检测------轮廓层次结构

目标

这一次,我们学习了轮廓的层次结构,即父-子关系的轮廓。

理论

在前几篇关于等高线的文章中,我们已经研究了OpenCV提供的一些与等高线相关的函数。但是当我们使用cv.findContours()函数找到图像的轮廓时,我们已经传递了一个参数,轮廓检索模式。我们通常通过简历。cv.RETR_LISTcv.RETR_TREE 和它工作得很好。但这到底意味着什么呢?

同样,在输出中,我们有三个数组,首先是图像,第二个是我们的轮廓,还有一个输出,我们命名为层次结构(请在前面的文章中签出代码)。但我们从未在任何地方使用过这种层次结构。那么这个层次结构是什么呢?它与前面提到的函数参数的关系是什么?

这就是我们在这篇文章中要讨论的内容。

层次结构是什么?

通常我们使用cv.findContours()函数来检测图像中的对象,对吗?有时物体在不同的位置。但在某些情况下,有些形状在其他形状中。就像嵌套数据。在这种情况下,我们把外一称为父类,内部为子。这样,图像中的轮廓就会有一些相互关系。我们可以指定一个等高线是如何相互连接的,比如,它是其他轮廓的子结点,还是父类的,等等。这种关系的表示叫做层次结构。

考虑下面的示例图片:

hierarchy.png

在这个图像中,有一些形状我从0-5开始编号。2和2a表示最外层的外部和内部轮廓。

这里,轮廓0,1,2是外部的或最外层的。我们可以说,它们是分层的,或者只是它们处于相同的层次结构。

其次是contour-2a。它可以被认为是contour-2的子元素(或者相反,contour-2是cont2a的父类)。所以让它在层级1中。同样的,contour-3是contour-2的子元素,它是在下一个层次结构中出现的。最后,轮廓4,5是cont3a的孩子,他们进入了最后的层次结构。从我对盒子编号的方式来看,我想说的是,cont4是cont3a的第一个孩子(也可以是cont3)。

我提到过这些东西来理解类似的层次结构,外部轮廓,子轮廓,父轮廓,第一个孩子等等,现在让我们进入OpenCV。

在层次结构表示OpenCV

所以每个轮廓都有自己的信息关于什么层级,谁是它的孩子,谁是它的父等等。OpenCV将它表示为四个值的数组:下一个,前一个,firstchild,父类

“下一个是在相同的层次上的下一个轮廓。”

例如,在我们的图片中,以cont0为例。下一个等高线在同一水平上?这是contour-1。简单地说,下一个=1。类似于Contour-1,接下来是contour-2。所以接下来= 2。

contour-2呢?在同一水平上没有下一个等高线。简单地说,下一个=-1。contour-4呢?它和cont5是相同的。所以它的下一个轮廓是cont5,所以下一个=5。

“以前在相同的等级级别上表示以前的轮廓。”

它和上面一样。前面的contour-1的轮廓在相同的级别上是cont0。类似于contour-2,它是contour-1。对于cont0,没有之前的,所以把它设为-1。

“firstchild表示它的第一个子轮廓。”

不需要任何解释。对于contour-2,儿童是cont2a。所以它得到了cont2a的相应的索引值。contour-3a呢?它有两个孩子。但我们只带了第一个孩子。contour-4。第一个孩子=4的cont3a。

“父类表示其父轮廓的索引。”

它正好与firstchild相反。对于cont4和cont5,父类都是cont3a。对于cont3a,它是contour-3,等等。

请注意

如果没有孩子或父母,这个字段就会被当作-1

现在我们知道了OpenCV中使用的层次结构样式,我们可以在上面给出的相同图像的帮助下,检查OpenCV中的轮廓检索模式。比如,像简历这样的标志。RETR_LIST,简历。RETR_TREE,简历。RETR_CCOMP,简历。RETR_EXTERNAL等等的意思吗?

轮廓检索模式

1。RETR_LIST

这是四个标志中最简单的(从解释的角度)。它只是检索所有的轮廓,但不会创建任何父子关系。在这条规则下,父母和孩子是平等的,他们只是轮廓。它们都属于同一层次的层次。

这里,第3和第4项在层级数组中总是-1。但是很明显,下一个和之前的术语会有它们对应的值。你自己检查一下,然后验证一下。

下面是我得到的结果,每一行都是对应等高线的层次结构细节。对于eg,第一行对应于等值线。下一个等高线是等高线1。所以接下来= 1。没有之前的等高线,所以先前=-1。剩下的两个,就像之前说的,是-1。

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

2。RETR_EXTERNAL

如果你使用这个标志,它只返回极端的外旗。所有的儿童轮廓都被抛在后面。我们可以说,根据这项法律,每个家庭中只有最年长的人得到照顾。它不关心家庭的其他成员:)。

那么,在我们的图像中,有多少个极端的外轮廓?ie hierarchy-0水平?。只有3,也就是0 1 2,对吧?现在试着用这个标志来找到轮廓。在这里,每个元素的值都与上面相同。将其与上述结果进行比较。下面是我得到的:

如果你只想提取外部轮廓,你可以使用这个标志。在某些情况下它可能是有用的。

3。RETR_CCOMP

这个标志检索所有的轮廓并将它们排列到一个2级的层次结构中。物体的外部轮廓(即它的边界)被放置在层级1中。物体内部的孔的轮廓(如果有的话)被放置在层级-2中。如果里面有任何对象,它的轮廓只在层级1中被重新放置。它的洞是等级2,等等。

只要考虑一下黑色背景上的“大白零”的图像。0的外圆属于第一个层次结构,而零的内圈属于二级层次结构。

我们可以用一个简单的图像来解释它。在这里,我将红色的轮廓和它们所属的层次结构标记为绿色(1或2),顺序与OpenCV检测轮廓相同。

图像

以cont0:它在层级-0中。相同层次结构的下一个等高线是cont7。没有以前的轮廓。孩子是contour-1。和没有父母。所以数组(7,1,1,1)。

以contour-2:它是等级1。在同一水平上没有等高线。没有前一个。孩子是contour-3。父母是contour-1。所以数组(1,1,3,1)。

和剩余,试着自己。下面是完整的答案:

猜你喜欢

转载自blog.csdn.net/qq_41905045/article/details/81537305