学习目标

这一部分,我们将学习轮廓的层次结构,比如轮廓中父子关系(parent-child)。

理论

在轮廓的前几部分内容中,OpenCV提供了多个关于轮廓的函数。在轮廓提取函数中,cv2.findContours() ,我们传递参数 Contour Retrieval Mode(轮廓检索模式)。通常的参数为:cv2.RETR_LISTcv2.RETR_TREE。但是这些参数是什么意思呢?

 contours, hierarchy = cv2.findContours(img_bin, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

contours:表示提取的轮廓。
hierarchy:表示轮廓的层次结构。
但是,之前的教程中并没有利用这个返回值。那么它是什么,代表什么意思?下面我们将介绍该返回值的含义和用法。

What is Hierarchy?

通常我们使用函数cv2.findContours()查找图像中的目标对象。但是,目标的分布都是不一样的。比如,有的形状分布在其它形状内部,就像网状结构一样。这种情况下,我们称外部的形状为parent,内部的为child。在这种规则下,形状之间是存在关系的。那么我们可以一个轮廓是如何与另一个轮廓连接方式,比如其它轮廓孩子,或则是否是父母等。这种关系称为层次结构(Hierarchy)。

考虑下面的图像:


我们将图中的形状进行的数字标号,22a分别表示最外层边框的最外和最内层的轮廓。这里,0,1,2表示外部(external)或者最外层(outermost)。我们可以简单称它们为 hierarchy-0,它们属于同一层次。

那么,contour-2a 认为是 contour-2 的孩子(反过来说,contour-2是其父母)。所以称之为 hierarchy-1. 同理,contour-3contour-2 的孩子,处于下一个层次(hierarchy-2)。最后,contour-4,5是contour-3a的孩子,它们是最后一个层次。在这种规则下,我们可以说 contour-4contour-3a 的第一个孩子(当然,contour-5也可以是第一个孩子)。

那么我们可以利用一些术语表达轮廓直接的关系,比如 same hierarchy level, external contour, child contour, parent contour, first child 等。

Hierarchy Representation in OpenCV

每一个轮廓都有其信息,比如它的孩子是什么,父母是是什么等。OpenCV中使用四元素的数组表达:[Next, Previous, First_Child, Parent].

Next: 表示同层次的下一个轮廓

比如,以上图为例,contour-0 的下一个同等层次的轮廓为contour-1,所以Next=1,同理,contour-1 的下一个轮廓为contour-2,所以Next=2. 但是,对于 contour-2 而言,没有同等层次的下一个轮廓,所以Next=-1. 而 contour-4 的下一个为 contour-5,所以Next=5.

Previous:表示同等层次下上一个轮廓

与上面的情况类似,contour-1 的上一个轮廓为 contour-0。类似,contour-2 的前一个为 contour-1。对于 contour-0previous=-1.

First_Child:表示第一个孩子轮廓

对于 contour-2,孩子轮廓为 contour-2a。所以,相应的值为 contour-2a 的索引值。对于 contour-3a,有2个孩子轮廓,但是我们只取第一个孩子轮廓,也就是 contour-4,所以 contour-3aFirst_Child=4.

Parent:父母轮廓的索引
First_Child情况相反。比如,contour-4contour-5 的父母轮廓为 contour-3a.

Contour Retrieval Mode

1. RETR_LIST

这是最简单的四个参数之一,仅仅检测所有的轮廓,不会创建任何父母-孩子(parent-child)关系。所以,这种情况下,父母和孩子仅仅是轮廓,属于同一层次。

那么,相应的第三个和第四个参数通常为 -1,而且,NextPrevious,具有他们自己的相关的值。

下面的结果:每一行表示相关轮廓具有层次细节。比如,第一行是 contour-0 的相关的四元素数组,Next 轮廓是1,所以 Next=1. 没有前一个轮廓,所以,Previous=0。同理另外两个一样,均为 -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

如果使用这个标志,那么仅仅返回外轮廓。所有的子轮廓放在最后。我们可以说,在这样的规则下,仅仅关注最外的轮廓。不关注内部轮廓。

那么在上面的图中,我们可以找到几个最外部轮廓,例如hierarchy-0,只有3个轮廓,contour,0,1,2. 下面的结果是在该参数下运行的例子:

>>> hierarchy
array([[[ 1, -1, -1, -1],[ 2,  0, -1, -1],[-1,  1, -1, -1]]])

如下图,只有三个轮廓返回,均是层次0的轮廓(最外层轮廓):

3. RETR_CCOMP

这个标志表示检索所有的轮廓,并把这些轮廓分为2个层次。比如,目标的外边界为hierarchy-1,内边界(洞的轮廓)为hierarchy-2. 如果任何目标在边框的内部,那么边界为hierarchy-1,内部的洞为hierarchy-2.

考虑黑色背景上的大的数字0,外圈是第一个层次,内圈是第二个层次,见下图:

我们使用一个简单的图像来解释。下图中,我们用红色标记轮廓的顺序,绿色表示该轮廓属于的层次(1或者2)。


如上图所示,考虑第一个轮廓,contour-0,属于hierarchy-1,它有2个洞,分别contour-1,2,它们属于层次2。所以,对于contour-0而言,下一个同层次的轮廓是contour-3。没有Previous没有值,为-1。但是,它的第一个孩子是层次2中的一个洞。没有父母,因为他是层次1,所以层次数组为[3, -1, 1, -1].

下面我们考虑contour-1,属于层次2. 同等层次的下一个轮廓为另外一个洞,即是contour-2. 没有Previous值,没有孩子,但是父母为contour-0,所以数组为[2, -1, -1, 0].

Contour-3Next=5(同等层次的下一个轮廓编号),Previous=0,孩子为contour-4,没有父母,所以数组为[5, 0, 4, -1].

Contour - 4 : 属于层次2,在contour-3之下,没有兄弟姐妹。所以没有next,也没有previous,没有孩子,父母是contour-3,数组为[-1, -1, -1, 3].

最终的数组如下:

[[[ 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

该参数会检索所有的轮廓,并且创建完整的家庭层次表(family hierarchy list). 包含完整的关系,比如父母,祖父母,儿子,孙子等等。

同样以上图为例,得到如下:

contour-0:属于层次0,next值为contour-7,没有previous值,孩子是contour-1,没有父母,所以数组为[7, -1, 1, -1].

contour-2:属于层次1,同等层次下没有轮廓。没有previous值,孩子是contour-2,父母为contour-1,数组为[-1 -1 3 1].

完整的结果如下:

[[[ 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]]]

OpenCV-Python -- Contours Hierarchy相关推荐

  1. 利用python安装opencv_Linux下安装OpenCV+Python支持

    原博文 2016-08-22 09:42 − 以下说明在Linux下Python和OpenCV结合安装的过程,Python要使用OpenCV模块,则必须导入OpenCV提供的包,所以要提供Python ...

  2. opencv+python视频实时质心显示

    利用opencv+python实现以下功能: 1)获取实时视频,分解帧频: 2)将视频做二值化处理: 3) 将视频做滤波处理(去除噪点,获取准确轮廓个数): 4)识别图像轮廓: 5)计算质心: 6)描 ...

  3. OpenCV python 轮廓的极值点

    OpenCV python 轮廓的极值点 处理图片:[cs1.jpg] import cv2 import numpy as npdef get_contour(img):""&q ...

  4. opencv python 多帧降噪算法_使用OpenCV和Python构建自己的车辆检测模型

    介绍 我喜欢智慧城市的理念.自动智能能源系统.电网.一键接入端口的想法等等.这是一个令人着迷的概念!老实说,这是一个数据科学家的梦想,我很高兴世界上很多城市都在朝着更智能的方向发展. 智能城市的核心组 ...

  5. 使用opencv python进行手检测和手指计数

    By seeing above image now you are very excited for implement it (like me). So not wasting too much t ...

  6. OpenCV+Python识别车牌和字符分割

    本篇文章主要基于python语言和OpenCV库(cv2)进行车牌区域识别和字符分割,开篇之前针对在python中安装opencv的环境这里不做介绍,可以自行安装配置! 车牌号检测需要大致分为四个部分 ...

  7. 基于opencv+python实现数独

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 效果展示图 一.引入库 二.训练KNN模型 三.读取数独图片并提取轮廓 四.提取9*9的81小方格 五.解析数独数字 ...

  8. opencv python 识别视频水印_opencv+python实现视频实时质心读取

    利用opencv+python实现以下功能: 1)获取实时视频,分解帧频: 2)将视频做二值化处理: 3) 将视频做滤波处理(去除噪点,获取准确轮廓个数): 4)识别图像轮廓: 5)计算质心: 6)描 ...

  9. 学习Opencv+Python之银行卡卡号识别

    学习Opencv+Python之银行卡卡号识别 思路: 获取模板轮廓 获取模板中每个数字的轮廓 获取银行卡卡号轮廓 分别提取卡号中的每个数字的轮廓 对比识别 代码: # 导入工具包 from imut ...

  10. OpenCV+python:轮廓发现与对象测量

    1,轮廓发现 当通过阈值分割提取到图像中的目标物体后,就需要通过边缘检测来提取目标物体的轮廓,使用这两种方法基本能够确定物体的边缘或者前景.接下来,通常需要做的是拟合这些边缘的前景,如拟合出包含前景或 ...

最新文章

  1. .Net SqlDbHelper
  2. 《C语言编程初学者指南》一2.9 理解运算符优先级
  3. 华为odc是什么意思_三星S20 FE官宣;华为Mate 40系列中国独占发售
  4. 数据库-SQL中like的用法
  5. TCP/IP的基本介绍
  6. 蓝桥杯九宫重排(bfs+用set去重)
  7. 在Windows XP 中使用Active Directory(活动目录)
  8. 20190109每日一句
  9. B-S期权定价模型 Black Scholdz
  10. VB2010实例(1)_字符大小写转换
  11. 控制萤石云摄像头转头
  12. 什么是bug(软件缺陷)
  13. TVM: End-to-End Optimization Stack for Deep Learning
  14. 性能之颠-应用程序性能技术
  15. Qt软件开发交流群分享
  16. c语言游戏经典案例,C语言_编游戏案例精编.doc
  17. 2013c语言二级等级考试试题,计算机等级考试二级c语言考试试题
  18. ALSA学习笔记 (1) ALSA 简介
  19. macOS安装homebrew cask 问题解决办法
  20. Https-证书应用

热门文章

  1. 字符串类型转数字类型的几种方法
  2. Locality Sensitive Hashing原理与实现
  3. Java课设之Swing学生信息管理系统(源码)
  4. 面向对象简称 OO(Object Oriented),20 世纪 80 年代以后,有了面向对象分析(OOA)、 面向对象设计(OOD)
  5. 工具分享|ArcHydro水文工具条
  6. 等保测评--《互联网安全保护技术措施规定》(公安部令第82号)
  7. 心得:小孩学绘画的7大好处[图]
  8. Arduino ESP8266自定义配置分区表
  9. 电脑u盘启动盘制作工具
  10. 性能优化的思路和步骤