OpenCV3-Python轮廓检测流程介绍
在计算机视觉中,轮廓检测是另外一个比较重要的任务,不单用来检测图像或视频帧中物体的轮廓,而且还有其它操作与轮廓检测有关,如:计算多边形边界、形状逼近和计算感兴趣区域。
Numpy中的矩形区域可以使用数组切片(slice)来定义,因此在介绍物体检测(包括人脸)和物体跟踪时,会大量使用这种技术。
1. 导入所需模块
import cv2 import numpy as np from matplotlib import pyplot as plt
2. Numpy数组切片
创建一个200x200的黑色空白图像,接着利用数组切片在图像中放置一个100*100的白色方块。
img = np.zeros((200, 200), dtype=np.uint8) img[50:150, 50:150] = 255 cv2.imshow("Original Image", img) cv2.waitKey() cv2.destroyAllWindows()
3. 二值化处理(官网)
cv2.threshold(src,thresh,maxval,type[,dst])
thresh : 源图像,应该是灰度图像;
thresh : 分类像素值的阈值;
maxval : 表示在像素值大于(有时小于)阈值时要给出的值;
type:对应OpenCV不同风格的阈值,有5种不同类型;
import cv2 import numpy as np from matplotlib import pyplot as plt img = cv2.imread('gradient.png',0) #cv2.THRESH_BINARY 黑白二值化 ret,thresh1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY) #cv2.THRESH_BINARY_INV 黑白二值化反转 ret,thresh2 = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV) #cv2.THRESH_TRUNC 多像素值 ret,thresh3 = cv2.threshold(img,127,255,cv2.THRESH_TRUNC) #cv2.THRESH_TOZERO 阈值化为0 ret,thresh4 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO) #cv2.THRESH_TOZERO_INV 反转阈值化到 ret,thresh5 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV) titles = ['Original Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV'] images = [img, thresh1, thresh2, thresh3, thresh4, thresh5] for i in range(6): plt.subplot(2,3,i+1),plt.imshow(images[i],'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show()
4. 查找轮廓
cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]])
image: 所需寻找轮廓的图像,8位单通道太图像。零像素保持为0,非零像素视为1;
mode: 轮廓的检索模式;
method: 为轮廓的近似办法;
返回值: cv2.findContours()函数返回两个值,一个是轮廓本身,还有一个是每条轮廓对应的属性。
''' mode: 轮廓的检索模式,有如下四种: cv2.RETR_EXTERNAL: 只检测外轮廓,为所有轮廓设置阶层; cv2.RETR_LIST: 检测所有轮廓而不建立层次关系 cv2.RETR_CCOMP: 检测所有轮廓,建立两个等级的轮廓; 上面一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。 cv2.RETR_TREE: 检测所有轮廓并重建一个等级树结构的轮廓。 method: 为轮廓的近似办法: cv2.CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1 cv2.CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息 cv2.CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法 ''' image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) color = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
5. 绘制图像轮廓
函数cv2.drawContours()被用来绘制轮廓,它可以根据你提供的边界点绘制任何形状。
cv2.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset]]]]]) → image
image: 目标图像,
contours: 所有输入轮廓。每个轮廓都存储为点矢量,
contourIdx: 绘制轮廓的索引(在绘制独立轮廓是很有用,当设置为-1时绘制所有轮廓)。
color: 轮廓的颜色。
img = cv2.drawContours(color, contours, -1, (0,255,0), 2)
6. 显示图像轮廓
cv2.imshow("contours", color) cv2.waitKey() cv2.destroyAllWindows()