轮廓检测可以理解为图像中具有相同颜色或密度的位于边界的连续点的集合,轮廓是形状分析和对象识别的有利工具。在Python-OpenCV中,常用 findContours 函数来计算轮廓,每个独立的轮廓都是以Numpy array 的点坐标的形式呈现。
为了在图像中显示计算出的轮廓,我们通常使用 drawContours 函数,通常这个函数会配合 findContours 使用。
轮廓检测:
contours, hierarchy = cv2.findContours(iamge, mode, method[, contours[,hierarchy[,offset]]])
image: 源图像,8位单通道图像,非0像素值均按像素值为1处理,该函数在提取轮廓的过程中会改变图像
mode:轮廓检索模式
cv2.RETR_EXTERNAL:只检测最外层轮廓,并置 hierarchy[i][2] = hierarchy[i][3] = -1
cv2.RETR_LIST: 提取所有轮廓并记录在列表中,轮廓之间无等级关系
cv2.RETR_CCOMP: 提取所有轮廓并建立双层结构(顶层为连通域的外围轮廓,底层为空的内层边界)
cv2.RETR_TREE: 提取所有轮廓,并重新建立轮廓层次结构
method:轮廓逼近方法
cv2.CHAIN_APPROX_NONE: 获取每个轮廓的每一个元素,相邻像素的位置差不超过1,及连续的点,但通常我们并不需要所有的点。
cv2.CHAIN_APPROX_SIMPLE: 压缩水平方向、垂直方向和对角线方向的元素,保留该方向的终点坐标。如矩形的轮廓可用4个角点表示,这是一种常用的方法,比第一种方法能得出更少的点
cv2.CHAIN_APPROX_TC_L1 和 cv2.CHAIN_APPROX_TC89_KCOS: 对应 Tch-Chain 链逼近算法
contours:轮廓信息,每个轮廓有点集组成,而所有的轮廓构成了 contours 列表
hierarchy:可选参数,表示轮廓的层次信息(拓扑信息),每个轮廓元素 contours[i] 对应 4 个 hierarchy 元素 hierarchy[i][0] ~ hierarchy[i][3],分别表示后一个轮廓,前一个轮廓,父轮廓和内嵌轮廓的编号,若无对应项,则该参数为负值。
offset:偏移
轮廓绘制
cv2.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset]]]]])
image: 目标输出图像
contours:所有轮廓,可直接传入 findContours 函数中的 contours 参数
contourIdx:轮廓的索引,即绘制那个轮廓,若为负值则绘制所有轮廓
color:绘制的颜色,元组形式,如(255)或(255,255,255)
thickness:绘制的轮廓线条的粗细程度,若为负数,表示要填充整个轮廓。
实例
import cv2
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from pandas import Series, DataFrame
img = cv2.imread('./lung.jpg')
plt.imshow(img)
plt.show()
grayImg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,binImg = cv2.threshold(grayImg, 100, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binImg, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img, contours, -1, (0, 200, 255), 2)
plt.imshow(img)
plt.show()
hierarchyDF = DataFrame(hierarchy[0], columns = ['pre', 'next', 'child', 'parent'])
可以得到7个轮廓,在这里首先在图上进行了简单的标记。
查看hierarchy可得:
对应的层次结构可以表示为:
0
|
+------+
| |
1 4
| |
+--+ 5
| | |
2 3 3
参考链接:https://blog.csdn.net/qq_30490125/article/details/80470758