图像轮廓
图像阈值分割主要是针对图片的背景和前景进行分离,而图像轮廓也是图像中非常重要的一个特征信息,通过对图像轮廓的操作,就能获取目标图像的大小、位置、方向等信息。画出图像轮廓的基本思路是:先用阈值分割划分为两类图像,再去寻找轮廓。OpenCV中使用cv2.findContours(image,mode,method)函数来寻找图像轮廓,其中参数image、mode、method分别为输入的图像、轮廓搜索模式(决定了轮廓的提取方式)、轮廓近似方法(决定了如何表达轮廓)。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 近似算法。
cv2.findContours()函数的输出信息contours、hierarchy分别为返回的轮廓和图像的拓扑信息(轮廓层次)。如果想要显示出图像轮廓,还需要使用OpenCV中的cv2.drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None)函数来绘制出图像轮廓,其中image、contours、contourIdx、color分别为输入的图像、绘制的轮廓、轮廓填充和轮廓的颜色。
示例代码
def f_contours():img = cv.imread("cup.jpg")# draw会改变原图,这里做一个备份img_copy = img.copy()gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)ret, thresh = cv.threshold(gray, 128, 255, cv.THRESH_BINARY)cv_show(thresh)# 这个函数只支持接收单颜色通道图像,否则报错contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_NONE)print(len(contours))result = cv.drawContours(img_copy, contours, -1, (0, 0, 255), 2)cv_show(result)