目标

这次我们学习轮廓的层次,即轮廓中的父子关系。

理论

在前几篇关于轮廓的文章中,我们已经讨论了与OpenCV提供的轮廓相关的几个函数。但是当我们使用cv.findcontour()函数在图像中找到轮廓时,我们已经传递了一个参数,轮廓检索模式。我们通常通过了cv.RETR_LISTcv.RETR_TREE,效果很好。但这到底意味着什么呢?

另外,在输出中,我们得到了三个数组,第一个是图像,第二个是轮廓,还有一个我们命名为hierarchy的输出(请检查前面文章中的代码)。但我们从未在任何地方使用过这种层次结构。那么这个层级是什么?它是用来做什么的?它与前面提到的函数参数有什么关系?

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

层次结构是什么?

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

下面是一个例子:

在这张图中,有一些形状我已经从0-5开始编号。22a表示最外层盒子的外部和内部轮廓。

这里,等高线0,1,2在外部或最外面。我们可以说,它们在层级-0中,或者简单地说,它们在同一个层级中。

其次是contour-2a。它可以被认为是contour-2的子级(或者反过来,contour-2是contour-2a的父级)。假设它在层级-1中。类似地,contour-3是contour-2的子级,它位于下一个层次结构中。最后,轮廓4,5是contour-3a的子级,他们在最后一个层级。从对方框的编号来看,我认为contour-4是contour-3a的第一个子级(它也可以是contour-5)。

我提到这些是为了理解一些术语,比如相同层级外部轮廓子轮廓父轮廓第一个子轮廓等等。现在让我们进入OpenCV。

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处于同一级别。它的下一条等高线是contour-5,所以next = 5

“Previous表示同一层次上的先前轮廓。

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

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

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

“Parent表示其父轮廓的索引。

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

注意
如果没有子元素或父元素,则该字段被视为-1

现在我们已经了解了OpenCV中使用的层次样式,我们可以借助上面给出的相同图像来检查OpenCV中的轮廓检索模式。一些标志如 cv.RETR_LISTcv.RETR_TREE,cv.RETR_CCOMPcv.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]]])

☆☆☆为方便大家查阅,小编已将OpenCV-Python专栏文章统一整理到公众号底部菜单栏,同步更新中,关注公众号,点击左下方“文章”,如图:

或点击下方“阅读原文”,进入OpenCV-Python专栏,即可查看系列文章。

不断更新资源

获取更多精彩

长按二维码扫码关注

OpenCV系列之轮廓分层 | 二十五相关推荐

  1. OpenCV系列之轮廓属性 | 二十三

    在这里,我们将学习提取一些常用的物体属性,如坚实度,等效直径,掩模图像,平均强度等.更多的功能可以在Matlab regionprops文档中找到. (注:质心.面积.周长等也属于这一类,但我们在上一 ...

  2. OpenCV系列之轮廓入门 | 二十一

    目标 了解轮廓是什么. 学习查找轮廓,绘制轮廓等. 你将看到以下功能:cv.findContours(),cv.drawContours() 什么是轮廓? 轮廓可以简单地解释为连接具有相同颜色或强度的 ...

  3. OpenCV系列之图像金字塔 | 二十

    目标 在本章中, 我们将学习图像金字塔 我们将使用图像金字塔创建一个新的水果"Orapple" 我们将看到以下功能:cv.pyrUp(),cv.pyrDown() 理论 通常,我们 ...

  4. Reflex WMS入门系列二十五:将叉车纳入系统进行管理

    Reflex WMS入门系列二十五:将叉车纳入系统进行管理 据笔者所知,SAP WM 模块里是不对仓库里常用的叉车等仓库管理工具进行管理的.笔者发现,Reflex WMS系统则会在很多仓库部门日常操作 ...

  5. 2021年大数据Hadoop(二十五):YARN通俗介绍和基本架构

    全网最详细的Hadoop文章系列,强烈建议收藏加关注! 后面更新文章都会列出历史文章目录,帮助大家回顾知识重点. 目录 本系列历史文章 前言 YARN通俗介绍和基本架构 Yarn通俗介绍 Yarn基本 ...

  6. linux exec 二程序,二十五、Linux 进程与信号---exec函数

    25.1 介绍 在用 fork 函数创建子进程后,子进程往往要调用一种 exec 函数以执行另一个程序 当进程调用一种 exec 函数时,该进程完全由新程序代换,替换原有进程的正文,而新程序则从其 m ...

  7. SAP UI5 初学者教程之二十五 - 使用代理服务器解决 SAP UI5 应用访问远端 OData 服务的跨域问题试读版

    一套适合 SAP UI5 初学者循序渐进的学习教程 教程目录 SAP UI5 本地开发环境的搭建 SAP UI5 初学者教程之一:Hello World SAP UI5 初学者教程之二:SAP UI5 ...

  8. FreeSql (二十五)延时加载

    FreeSql 支持导航属性延时加载,即当我们需要用到的时候才进行加载(读取),支持1对1.多对1.1对多.多对多关系的导航属性. 当我们希望浏览某条订单信息的时候,才显示其对应的订单详细记录时,我们 ...

  9. 二十五个软件测试经典面试题,你确定不收藏一波?

    二十五个软件测试经典面试题全在这里了,有兴趣的朋友建议收藏一波,或者留言交流! 1.在搜索引擎中输入汉字就可以解析到对应的域名,请问如何用LoadRunner进行测试? 建立测试计划,确定测试标准和测 ...

最新文章

  1. 【算法】差分与前缀和 算法详解+例题剖析
  2. 波士顿动力母公司最新机器人,就这?
  3. ZooKeeper安装及配置(Windows系统下)
  4. activity 启动模式_Intent#FLAG_ACTIVITY_CLEAR_TOP 真的会 clear top 吗
  5. 运用Axure6.5快速完成微信交互效果的简单办法
  6. 炎热天气看书还是钓鱼?隐马尔科夫模型教你预测!
  7. java 难度_java中难度大一点的面试题
  8. 【❤️万字长文总结❤️】一篇学会Redis高可用✔集群✔搭建详细教程
  9. angular2之pdf文件操作大全
  10. 计算机 继续教育培训心得体会,继续教育培训总结.doc
  11. 三维数据入库发布流程之3dMAX数据
  12. 信号带宽和示波器带宽(模拟带宽)关系?信号带宽和信道带宽关系?示波器参数、品牌
  13. 微信公众号H5 - 使用vue开发微信公众号网页
  14. Kubeadm初始化Kubernetes集群
  15. Excel的Index函数详解
  16. 为什么对偶问题一定是凸优化问题?
  17. EduCoder-程序设计技术R-函数-(第1关:求和)(第2关:回文数计算)(第3关: 编写函数求表达式的值)(第4关:阶乘数列)(第5关:亲密数)(第6关:公约公倍数)
  18. 移动端跨平台开发Flutter 与 React Native对比
  19. 在VUE中使用Lottie动画
  20. 软件之聊天工具:QQ,MSN,Google talk,Skype, Lync

热门文章

  1. 好久不用计算机比较慢,电脑很久没用开不了机是怎么回事 电脑很久没用运行卡慢怎么解决...
  2. 四、数据透视表公式与函数
  3. 雷曼兄弟:次贷中的又一大“牺牲品”
  4. BWT压缩算法及FM搜索算法详解
  5. 零基础如何学好软件测试?
  6. 太阳能光伏发电整流逆变实训装置,QY-TF01
  7. Snow Footprints CodeForces - 298A
  8. QT练手小项目-——天气播报小狗(ui展示分析,构造实现,json格式数据分析,界面交互,天气图标处理,小狗语音)
  9. android获取cpu架构,Android CPU架构支持
  10. 三年开发经验, 字节跳动抖音组离职后, 一口气拿到 15 家公司 Offer