OpenCV学习笔记-轮廓的层次结构

一、什么是层次结构

通常我们使用函数cv.findContours()在图片中查找一个对象。有时对象可能位于不同的位置。还有一些情况,一个形状在另外一个形状的内部。这种情况下我们称外部的形状为父,内部的形状为子。按照这种方式分类,一副图像中的所有轮廓之间就建立父子关系。

让我们来看一个简单的例子:

在这个图中,我给这几个形状编号为0-5,2和2a分别代表最外边矩形的外轮廓和内轮廓。

在这里边轮廓0,1,2在外部或最外边,我们可以称它们为(组织结构)第0级,它们属于同一级。

接下来是轮廓2a,它是轮廓2的子轮廓。它是第1级

轮廓3是轮廓2a的子轮廓。它是第2级。


轮廓3a是轮廓3的子轮廓。它是第3级。

轮廓4、5是轮廓3a的子轮廓。它是第4级。轮廓5是轮廓4的下一个轮廓。

二、OpenCV中层次结构

不管层次机构是什么样的,每一个轮廓都包含自己的信息:上一个轮廓是谁,下一个轮廓是谁,父轮廓是谁,子轮廓是谁。

OpenCV使用一个含有四个元素的数组表示:[Next, Previous, First_Child, Parent]。

Next 表示同一级组织结构中的下一个轮廓。


以轮廓0为例,轮廓1就是它的Next。同样,轮廓1的下一个轮廓是轮廓2,next=2.

轮廓2在同一级中没有Next,这是Next=-1,轮廓4的next是轮廓5,轮廓5的next=-1

previous表示统一结构中的前一个轮廓。


轮廓1的previous是轮廓0,轮廓5的previous是轮廓4,轮廓0没有previous,所以previous=-1

first_child表示它的第一个子轮廓

轮廓2的子轮廓是2a,所以它的first_child是2a.轮廓3a有两个子轮廓,但是我们只要第一个子轮廓,所以是轮廓4(按照从上到下,从左到右的顺序排序)

parent 表示它的父轮廓

和子轮廓相反。轮廓4和轮廓5的父轮廓是轮廓3a,而轮廓3a的父轮廓是3。

三、轮廓检索模式

RETR_LIST:

它只是提取所有的轮廓,而不去创建任何父子关系。所有的轮廓都是同一级别。
所以在这种情况下,组织结构数组的第三个、第四个数都是-1,除了第一行和最后一行情况特殊,其他行的next和previous都有对应的值。

我们可以看看数值:
hierarchy:
 [[[ 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]]]

RETR_EXTERNAL:

只返回最外边的轮廓,所有的子轮廓都会被忽略。

所以在上图中使用这种模式的话只会返回最外边的轮廓(第0级):轮廓0、1、2。
使用这种模式得到的结果:

hierarchy:
 [[[ 1 -1 -1 -1]
  [ 2  0 -1 -1]
  [-1  1 -1 -1]]]

RETR_CCOMP:

这种模式会返回所有的轮廓,并将轮廓分为两级组织结构。
例如:一个对象的外轮廓为第1级结构。而对象内部中空洞的轮廓为第2级组织结构。空洞中的任何对象的轮廓又是第1级组织结构。空洞的组织结构为第2级。
好吧,我自己也绕晕了,我们在图上看,用红色数字为这些轮廓编号,并用绿色数字代表它们的组织结构。

现在我们考虑轮廓0,它的组织结构是第1级。其中有两个空洞1和2,它们属于第2级组织结构。对于轮廓0来说,和它属于同一级组织结构的下一个(next)是轮廓3,并且没有previous。它的first_child为轮廓1,组织结构为2.由于它是第1级,所以没有父轮廓。因此它的组织结构数组为[3, -1, 1, -1]。
现在是轮廓1,它是第2级。处于同一级的下一个轮廓是2.没有previous,也没有child,父轮廓为0。所以数组是[2, -1, -1, 0]。
其他的以此类推。


RETR_TREE :

这种模式会返回所有的轮廓,并创建一个完整的组织结构列表。它会告诉你谁是爸爸,谁是儿子。
轮廓0的组织结构为0,同一级next为7,没有previous。子轮廓是1,没有父轮廓。所以数组是[7, -1, 1, -1]。
轮廓1的组织结构为1,同一级中没有其他,没有previous。子轮廓是2,父轮廓是0.所以数组是[-1, -1, 2, 0]。
剩下的以此类推。


猜你喜欢

转载自blog.csdn.net/qq_36387683/article/details/80472043
今日推荐