首页 > 编程笔记 > Python笔记 阅读:3

OpenCV findContours()函数的用法(附带实例)

在 OpenCV 中,使用 findContours() 函数,只需简单的几个步骤就可以检测出物体的轮廓,十分方便。

findContours() 函数声明如下:
cv.findContours( image, mode, method[, contours[, hierarchy[, offset]]]) -> contours, hierarchy
各个参数的含义如下:
1) image 表示原始图像,必须是 8 位单通道二值图像。一般情况下,都是将图像处理为二值图像后,再将其作为 image 参数来使用;

2) 参数 mode 决定了轮廓的提取方式,具体有如下 4 种:
3) 参数 method 决定了如何表达轮廓,可以取如下值:
4) 参数 contours 是一个向量,并且是双重向量,向量内每个元素保存了一组由连续的 Point 构成的点的集合向量,每一组 Point 点集就是一个轮廓,有多少个轮廓,向量 contours 内就有多少个元素。

5) 参数 hierarchy 定义为“vector<Vec4i> hierarchy”,其中,Vec4i 的定义如下:
typedef Vec<int, 4> Vec4i;
Vec4i 是 Vec<int,4> 的别名,定义了一个“向量内每一个元素包含了 4 个 int 型变量”的向量。所以从定义上看 hierarchy 也是一个向量,向量内每个元素保存了一个包含 4 个 int 型的数组。

向量 hierarchy 内的元素和轮廓向量 contours 内的元素是一一对应的,向量的容量相同。hierarchy 向量内每一个元素的 4 个 int 型变量(hierarchy[i][0]~hierarchy[i][3]),分别表示第 i 个轮廓的后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号。如果当前轮廓没有对应的后一个轮廓、前一个轮廓、父轮廓或内嵌轮廓,那么 hierarchy[i][0]~hierarchy[i][3] 的相应位被设置为默认值 -1。

6) 参数 offset 表示每个轮廓点移动的可选偏移量。

另外,绘制轮廓函数 drawContours() 经常和查找轮廓函数 findContours() 联合使用,查找出轮廓后通常需要把轮廓绘制出来。函数 drawContours() 声明如下:
cv.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset]]]]]) -> image
各个参数的含义如下:
【实例】查找图像的轮廓。
import cv2

img = cv2.imread("test2.jpg")
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)

#检测轮廓
contours, hierarchy = cv2.findContours(binary,cv2.RETR_TREE,
cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img,contours,-1,(0,0,255),3)  #绘制轮廓

cv2.imshow("img", img)
cv2.waitKey(0)
需要注意的是,cv2.findContours() 函数接收的参数为二值图,即黑白图(不是灰度图),所以读取的图像要先转为灰度图再转为二值图。最后检测轮廓、绘制轮廓。

运行工程,结果如下图所示:


注意,findContours() 函数会“原地”修改输入的图像。这一点可以通过下面的语句验证:
cv2.imshow("binary", binary)
contours, hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cv2.imshow("binary2", binary)
执行这段代码后,可以发现原图被修改了。

相关文章