本篇文章介绍图像轮廓,轮廓是形状分析和物体检测识别非常有用的工具。将学习如何寻找与绘制轮廓。
主要学习cv.findContours(),cv.drawContours()函数的使用。
环境:Windows 7(64) Python 3.6 OpenCV 3.4.2
cv.findContours()函数形式如下:
image, contours, hierarchy = cv.findContours( image, mode, method[, contours[, hierarchy[, offset]]] )
功能:在二值图像中寻找轮廓。
参数:
image:输入图像,八位单通道二值图像。如果mode等于RETR_CCOMP或RETR_FLOODFILL,则输入也可以是的32位整数图像(CV_32SC1)。
contours:得到的轮廓。数据类型是点向量。
hierarchy:层次信息。也是一个向量,每个元素是4个int变量的数组,它和contours元素相对应。hierarchy[i][0]~hierarchy[i][3]分别表示第i个轮廓的后一轮廓,前一轮廓,父轮廓、内嵌轮廓的索引编号。如果没有,会设为-1。
mode:轮廓检索模式
method:轮廓近似方法
offset:每个轮廓点移动的可选偏移量。
mode的取值如下:
cv.RETR_EXTERNAL:仅检索极端外轮廓。 它为所有轮廓设置hierarchy[i] [2] = hierarchy [i] [3] = - 1
cv.RETR_LIST:检索所有轮廓而不建立任何层次关系。
cv.RETR_CCOMP:检索所有轮廓并将它们组织成两级层次结构。 在顶层,组件有外部边界。 在第二层,有孔的边界。 如果连接组件的孔内有另一个轮廓,它仍然位于顶层。
cv.RETR_TREE:检索所有轮廓并重建嵌套轮廓的完整层次结构。
cv.RETR_FLOODFILL:文档无说明。
method的取值如下:
cv.CHAIN_APPROX_NONE:绝对存储所有轮廓点。 也就是说,轮廓的任何2个后续点(x1,y1)和(x2,y2)将是水平,垂直或对角线邻居,即max(abs(x1-x2),abs(y2-y1))== 1。
cv.CHAIN_APPROX_SIMPLE:压缩水平,垂直和对角线段,只留下它们的端点。 例如,右上方的矩形轮廓用4个点编码。
cv.CHAIN_APPROX_TC89_L1:应用Teh-Chin链近似算法的一种风格。
cv.CHAIN_APPROX_TC89_KCOS:应用Teh-Chin链式近似算法的一种风格。
cv.drawContours()函数形式如下:
image = cv.drawContours( image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset]]]]] )
功能:绘制或填充轮廓。
参数:
image:目标图像,即要选择在什么图像上绘制轮廓。
contours:输入要绘制的所有轮廓。
contourIdx:指要绘制的轮廓参数。如果为-1,则绘制所有轮廓。
color:指定绘制轮廓线的颜色。
thickness:指定绘制轮廓线的粗细。如果为负(或设置为FILLED),则是轮廓填充。
lineType:指定绘制轮廓线的类型。
hierarchy:轮廓的层次信息。
maxLevel:绘制轮廓的最大级别。如果为0,则仅绘制指定的轮廓。如果为1,则该函数绘制轮廓和所有嵌套轮廓。如果为2,则该函数绘制轮廓,所有嵌套轮廓,所有嵌套到嵌套的轮廓,等等。仅当有可用的层次结构时才考虑此参数。
offset:可选的轮廓移位参数。按指定的偏移=(dx,dy)移动所有绘制的轮廓。
代码如下:
import cv2 as cv
import numpy as np
img = cv.imread('1.png') #读取图像
imgray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) #灰度化
ret, thresh = cv.threshold(imgray, 127, 255, 0) #二值化
#轮廓提取
im2, contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
#轮廓绘制
cv.drawContours(img, contours, -1, (0, 255, 0), 3)
#显示
cv.imshow("src img", img)
运行结果图如下: