一、背景

cv.findContours()中的mode有什么用?cv.findContours()中的mode hierarchy是什么?有什么效果?

opencv houghline 完整范例_python


阅读官方文档,熟悉cv.findContours(),

我们可以知道,mode指定的是轮廓索引方式。

那么有哪些索引方式呢?

opencv houghline 完整范例_python_02


这是定义在C++中的枚举类型,

将就参考一下

特别说明 ,FLOODFILL用的不多,本文咱不作探究;

有兴趣的朋友可以看看这个 In opencv’s findContours, what does cv.RETR_FLOODFILL do?

二、分析

光看mode的枚举,很难看出是什么意思,比如CCOMP,TREE,跟轮廓有什么关系?
下面我将一步步手工学习并比较其中的不同。

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
from enum import Enum

img = cv.imread('find_c.png', cv.IMREAD_COLOR)

_ret, img2 = cv.threshold(cv.cvtColor(img,cv.COLOR_BGR2GRAY), 0, 255, cv.THRESH_BINARY)


# enum  cv::RetrievalModes {
#   cv::RETR_EXTERNAL = 0,
#   cv::RETR_LIST = 1,
#   cv::RETR_CCOMP = 2,
#   cv::RETR_TREE = 3,
#   cv::RETR_FLOODFILL = 4
# }
# 本文主要对前四种mode进行演示

class Mode(Enum):
    RETR_EXTERNAL = 0
    RETR_LIST = 1
    RETR_CCOMP = 2
    RETR_TREE = 3


# Since opencv 3.2 source image is not modified by this function.
contours = [-1 for i in range(5)]
hierarchy = [-1 for i in range(5)]
drawImg = []
for i in range(4):
    _img, contours[i], hierarchy[i] = cv.findContours(img2, i, cv.CHAIN_APPROX_NONE)

    drawImg.append(
        cv.cvtColor(
            cv.drawContours(img.copy(), contours[i], -1, (0, 0, 255), thickness=5),
            code=cv.COLOR_BGR2RGB)
    )

plt.figure(0)
plt.subplot(231), plt.imshow(img, cmap='gray'), plt.title('Org'), plt.axis('off')
# 这个图像我本来就往黑白画的 所以二值化图像和原图像应该是一样的表现
plt.subplot(232), plt.imshow(img2, cmap='gray'), plt.title('BINARY'), plt.axis('off')
for i in range(4):
    plt.subplot(233 + i), plt.imshow(drawImg[i]), plt.title(Mode(i).name), plt.axis('off')

opencv houghline 完整范例_python_03


我们可以看到,除了EXTERNAL是只检查外部轮廓之外,其他七个轮廓肉眼看起来都差不多。

阅读资料,发现应该是hierarchy存在不同。

检查hierarchy:

注:
hierarchy 共四个参数,分别是:
下一个 、前一个、第一个、父轮廓的索引的编号

  1. RETR_EXTERNAL
  2. opencv houghline 完整范例_计算机视觉_04

  3. 我们可以从 hierarchy中看出,只有三个轮廓 符合定义
  4. RETR_LIST

opencv houghline 完整范例_机器学习_05

最后两个值都是-1,也不构成层次关系

  1. RETR_CCOMP

opencv houghline 完整范例_python_06


这个不太容易立交CCOMP的意义,

查了一些资料

retrieves all of the contours and organizes them into a two-level hierarchy. At the top level, there are external boundaries of the components. At the second level, there are boundaries of the holes. If there is another contour inside a hole of a connected component, it is still put at the top level…

大概就是说,建立了两个层次的轮廓,一个内轮廓,一个外轮廓。

  1. RETR_TREE

opencv houghline 完整范例_计算机视觉_07

从这里来看,似乎不太明显,我决定再换一个具体代表性的图像来测试 RETR_TREE

opencv houghline 完整范例_opencv_08


opencv houghline 完整范例_人工智能_09

这下子就可以清楚的看清楚树形是怎么回事了

画出来大概就是

opencv houghline 完整范例_python_10


主要注意的是,节点中数字只代表编号,不代表顺序,顺序需要有hierarchy的前几位定。

mode、 hierarchy的学习笔记大致如上,希望能够帮到您~