OpenCV-Python -- Contours Hierarchy
学习目标
这一部分,我们将学习轮廓的层次结构,比如轮廓中父子关系(parent-child)。
理论
在轮廓的前几部分内容中,OpenCV提供了多个关于轮廓的函数。在轮廓提取函数中,cv2.findContours()
,我们传递参数 Contour Retrieval Mode
(轮廓检索模式)。通常的参数为:cv2.RETR_LIST
,cv2.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
)。
考虑下面的图像:
我们将图中的形状进行的数字标号,2
和2a
分别表示最外层边框的最外和最内层的轮廓。这里,0,1,2表示外部(external)或者最外层(outermost)。我们可以简单称它们为 hierarchy-0,它们属于同一层次。
那么,contour-2a 认为是 contour-2 的孩子(反过来说,contour-2是其父母)。所以称之为 hierarchy-1. 同理,contour-3 是 contour-2 的孩子,处于下一个层次(hierarchy-2)。最后,contour-4,5是contour-3a的孩子,它们是最后一个层次。在这种规则下,我们可以说 contour-4 是 contour-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-0,
previous=-1
.
First_Child:表示第一个孩子轮廓
对于 contour-2,孩子轮廓为 contour-2a。所以,相应的值为 contour-2a 的索引值。对于 contour-3a,有2个孩子轮廓,但是我们只取第一个孩子轮廓,也就是 contour-4,所以 contour-3a,
First_Child=4
.
Parent:父母轮廓的索引
与First_Child情况相反。比如,contour-4 和 contour-5 的父母轮廓为 contour-3a.
Contour Retrieval Mode
1. RETR_LIST
这是最简单的四个参数之一,仅仅检测所有的轮廓,不会创建任何父母-孩子(parent-child)关系。所以,这种情况下,父母和孩子仅仅是轮廓,属于同一层次。
那么,相应的第三个和第四个参数通常为 -1,而且,Next 和 Previous,具有他们自己的相关的值。
下面的结果:每一行表示相关轮廓具有层次细节。比如,第一行是 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-3:Next=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相关推荐
- 利用python安装opencv_Linux下安装OpenCV+Python支持
原博文 2016-08-22 09:42 − 以下说明在Linux下Python和OpenCV结合安装的过程,Python要使用OpenCV模块,则必须导入OpenCV提供的包,所以要提供Python ...
- opencv+python视频实时质心显示
利用opencv+python实现以下功能: 1)获取实时视频,分解帧频: 2)将视频做二值化处理: 3) 将视频做滤波处理(去除噪点,获取准确轮廓个数): 4)识别图像轮廓: 5)计算质心: 6)描 ...
- OpenCV python 轮廓的极值点
OpenCV python 轮廓的极值点 处理图片:[cs1.jpg] import cv2 import numpy as npdef get_contour(img):""&q ...
- opencv python 多帧降噪算法_使用OpenCV和Python构建自己的车辆检测模型
介绍 我喜欢智慧城市的理念.自动智能能源系统.电网.一键接入端口的想法等等.这是一个令人着迷的概念!老实说,这是一个数据科学家的梦想,我很高兴世界上很多城市都在朝着更智能的方向发展. 智能城市的核心组 ...
- 使用opencv python进行手检测和手指计数
By seeing above image now you are very excited for implement it (like me). So not wasting too much t ...
- OpenCV+Python识别车牌和字符分割
本篇文章主要基于python语言和OpenCV库(cv2)进行车牌区域识别和字符分割,开篇之前针对在python中安装opencv的环境这里不做介绍,可以自行安装配置! 车牌号检测需要大致分为四个部分 ...
- 基于opencv+python实现数独
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 效果展示图 一.引入库 二.训练KNN模型 三.读取数独图片并提取轮廓 四.提取9*9的81小方格 五.解析数独数字 ...
- opencv python 识别视频水印_opencv+python实现视频实时质心读取
利用opencv+python实现以下功能: 1)获取实时视频,分解帧频: 2)将视频做二值化处理: 3) 将视频做滤波处理(去除噪点,获取准确轮廓个数): 4)识别图像轮廓: 5)计算质心: 6)描 ...
- 学习Opencv+Python之银行卡卡号识别
学习Opencv+Python之银行卡卡号识别 思路: 获取模板轮廓 获取模板中每个数字的轮廓 获取银行卡卡号轮廓 分别提取卡号中的每个数字的轮廓 对比识别 代码: # 导入工具包 from imut ...
- OpenCV+python:轮廓发现与对象测量
1,轮廓发现 当通过阈值分割提取到图像中的目标物体后,就需要通过边缘检测来提取目标物体的轮廓,使用这两种方法基本能够确定物体的边缘或者前景.接下来,通常需要做的是拟合这些边缘的前景,如拟合出包含前景或 ...
最新文章
- .Net SqlDbHelper
- 《C语言编程初学者指南》一2.9 理解运算符优先级
- 华为odc是什么意思_三星S20 FE官宣;华为Mate 40系列中国独占发售
- 数据库-SQL中like的用法
- TCP/IP的基本介绍
- 蓝桥杯九宫重排(bfs+用set去重)
- 在Windows XP 中使用Active Directory(活动目录)
- 20190109每日一句
- B-S期权定价模型 Black Scholdz
- VB2010实例(1)_字符大小写转换
- 控制萤石云摄像头转头
- 什么是bug(软件缺陷)
- TVM: End-to-End Optimization Stack for Deep Learning
- 性能之颠-应用程序性能技术
- Qt软件开发交流群分享
- c语言游戏经典案例,C语言_编游戏案例精编.doc
- 2013c语言二级等级考试试题,计算机等级考试二级c语言考试试题
- ALSA学习笔记 (1) ALSA 简介
- macOS安装homebrew cask 问题解决办法
- Https-证书应用