findContours
findContours
函数主要作用是从二值图中检索轮廓。
用法
import cv2cv2.findContours(image, mode, method[, contours[, hierarchy[, offset]]])
参数
image
:8-bit单通道图像。该图像会将非0像素值视为1,0像素值视为0,因此也被视为二值图像。mode
:轮廓检索模式,检测外轮廓还是内轮廓,是否包含继承(包含)关系:cv2.RETR_EXTERNAL
表示只检测外轮廓,忽略轮廓内部的结构,无继承相关信息;cv2.RETR_LIST
检测所有的轮廓但不建立继承(包含)关系;cv2.RETR_CCOMP
检测所有轮廓,但是仅仅建立两层包含关系;cv2.RETR_TREE
检测所有轮廓,并且建立所有的继承(包含)关系。method
:轮廓近似方法,有记录方法:cv2.CHAIN_APPROX_NONE
存储所有的轮廓点,相邻的两个点的像素位置差不超过 1,即max(abs(x1-x2), abs(y1-y2))=1
;cv2.CHAIN_APPROX_SIMPLE
压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩阵轮廓只需 4 个点来保存轮廓信息。contours
:返回值,检测到的轮廓。每个轮廓都以点向量的形式存储。hierarchy
:返回值,包含有关图像轮廓的拓扑信息。它的元素和轮廓的数量一样多。对于第 i i i个轮廓contours[i]
,元素hierarchy[i][0]
、hierarchy[i][1]
、hierarchy[i][2]
和hierarchy[i][3]
分别设置为同一层次的下一个轮廓、同一层次的上一个轮廓、该轮廓的第一个子轮廓(嵌套轮廓)、该轮廓的父轮廓,它们的取值是轮廓的索引值(从0开始)。如果contours[i]
没有与其同级的下一个轮廓、上一个轮廓、嵌套轮廓或父轮廓,则hierarchy[i]
的相应元素将为负。hierarchy
表示连通域的继承关系矩阵。矩阵大小为 ( 1 , N , 4 ) (1,N,4) (1,N,4)。
基础元素由四个值组成:[Next
,Previous
,First_Child
,Parent
]。前两个值表示同级的前后关系,后两个值表示上下级关系。
Next
:下一个同级的轮廓的序号;
Previous
:上一个同级轮廓的序号;
First_Child
:第一个子轮廓的序号;
Parent
:父轮廓的序号;
矩阵中的每一个值代表都是 轮廓(contour
)的序号(id
),其中-1
代表没有这个元素。offset
:可选偏移量,每个轮廓点偏移量。如果从图像ROI中提取轮廓,然后在整个图像上下文中对其进行分析,这将非常有用。
实例
针对下面的图片,我们检索它的轮廓:
import cv2img = cv2.imread('image001.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转换为灰度图ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU) # 利用阈值自动选择的方法获取二值图像contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 检测轮廓# 打印轮廓
print("轮廓长度:",len(contours))
print("contours[2]:\n",contours[2])
# 打印继承矩阵
print("hierarchy:\n",hierarchy)
输出:
轮廓长度:7
contours[2]:[[[ 47 137]][[ 48 136]][[ 49 137]][[ 49 138]][[ 48 139]][[ 47 138]]]
hierarchy:[[[-1 -1 1 -1][ 2 -1 -1 0][ 3 1 -1 0][-1 2 4 0][ 5 -1 -1 3][ 6 4 -1 3][-1 5 -1 3]]]
结果解析:
从上述结果中,可以得到以下结论:
- 轮廓的长度为7;
- 对第3个轮廓进行打印,可以看到,轮廓确实是以点集的形式存储的;
- 图像轮廓的拓扑信息
hierarchy
,也称作连通域的继承关系矩阵,大小为 ( 1 , 7 , 4 ) (1,7,4) (1,7,4)。
轮廓的排序是从最外围往中间进行的排序,contours[0]
表示的是最外层外轮廓。
hierarchy
矩阵解释:
hierarchy[0]=[-1 -1 1 -1]
表示轮廓contours[0]
的拓扑关系,Next =-1
表示下一个与contours[0]
同级的轮廓,-1
表示不存在下一个同级轮廓;Previous = -1
表示上一个与contours[0]
同级的轮廓,-1
表示不存在上一个同级轮廓;First_Child = 1
表示contours[0]
第一个子轮廓是contours[1]
, 1是轮廓的索引;Parent = -1
表示contours[0]
的父轮廓,-1
表示不存在父轮廓。