OpenCV基于Python图像轮廓分层及其检索模式

本文深入探讨了OpenCV中基于Python的图像轮廓处理,讲解了层次结构的概念,包括4种轮廓检索模式:RETR_LIST、RETR_EXTERNAL、RETR_CCOMP、RETR_TREE,并通过实例解析了每种模式的特性和应用场景。
摘要由CSDN通过智能技术生成

目标

在本篇文章中,我们将学习到轮廓的层次及轮廓层次中的4种检索模式,包括以下内容:

  • 层次结构是什么?
  • 层次结构在OpenCV中的表示
  • 4种轮廓检索模式——RETR_LIST、RETR_EXTERNAL、RETR_CCOMP、RETR_TREE

1. 理论

轮廓绘制及其特征文章中,我们已经讨论了与OpenCV提供的轮廓相关的几个函数,例如查找图像轮廓函数cv2.findContours()的语法格式如下 :

image,contours,hierarchy = cv2.findContours(image,mode,method)

该函数的各参数解释如下:

  • 返回值:
    • image:与原始图像中的参数一致
    • countours : 返回的轮廓
    • hierarchy : 图像的轮廓层次信息
  • 函数参数:
    • image : 原始图像(8位单通道,所有非零值被处理为1所有零值保持不变,即将灰度图像先采用阈值处理为二值图像)
    • mode : 轮廓检索模式
    • method : 轮廓的近似方法

注意: OpenCV4.x及以上版本的返回值中没有第一个参数image,即只有countours与hierarchy两个参数

从查找轮廓函数中不难发现,当我们使用cv.findcontour()函数在图像中找轮廓时,我们已经传递了一个参数,轮廓检索模式Contour Retrieval Mode,我们通常会传递cv.RETR_LISTcv.RETR_TREE而且运行效果很好。但这到底意味着什么呢?

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

这些问题正是本篇文章所要讨论的内容。

1.1 什么是层次结构

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

以下面这张图为例并思考其中对应的相互关系
层次结构图

图1 轮廓层次结构示意图

在这张图中,我按照顺序给轮廓从0-5开始编号,其中22a分别表示最外层盒子的外部和内部轮廓。

在这里,轮廓0, 1, 2在外部或最外面,即表示向外(external/outermost)轮廓。我们可以说,它们在层级-0(hierarchy-0)中,或者简单地说,它们在同一个层级(same hierarchy level)中。

注意: 为方便描述,本文中的“层次结构”含义等同“层级”。

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

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

1.2 OpenCV中的层次结构表示

综上所述可知,每个轮廓都有它自己的信息,如层次结构、谁是父轮廓,谁是子轮廓等等。OpenCV将这些信息表示为一个包含四个值的数组: [Next, Previous, First_Child, Parent]

Next 表示同一层次上的下一个轮廓。“Next denotes next contour at the same hierarchical level.”、

例如,对于图1中的contour-0,谁是下一个同级别的轮廓?显然是contour-1,所以可以令Next = 1 。类似地,Contour-1同级轮廓中的下一个轮廓是contour-2,所以 令Next = 2 。那么contour-2呢?从上图1中我们可以看出同级别中没有下一个轮廓存在了,其实也很简单,我们直接令 Next = -1。那么contour-4呢?在图1中它与contour-5处于同一级别,所以它的下个轮廓是contour-5,也就是说 Next = 5。

Previous 表示同一层次上的前一个轮廓。“Previous denotes previous contour at the same hierarchical level.”

与上面的分析一样,轮廓contour-1 在同级别的前一个轮廓就是contour-0。类似地,contour-2 同级别的前一个轮廓是 contour-1。对于contour-0,没有前一个轮廓,所以令Previous= -1

First_Child表示它的第一个子轮廓。"First_Child denotes its first child contour.”

这里不需要额外的解释,从图中可以看出,对于contour-2的子轮廓是contour-2a,所以它被称作contour-2a,2a 即对应的索引值。那么contour-3a呢?它有两个子轮廓,但我们只关注第一个子轮廓,它是contour-4,那么对contour-3a而言,第一个子轮廓表示为First_Child = 4

Parent表示其父轮廓的索引。 “Parent denotes index of its parent contour.”

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

要点提示: 如果某轮廓没有子轮廓(First_Child)或父轮廓(Parent)&#x

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值