Python版本是Python3.7.3,OpenCV版本OpenCV3.4.1,开发环境为PyCharm
在OpenCV中,可以使用函数cv2.drawContours()绘制图像轮廓。该函数的语法格式是:
image=cv2.drawContours(
image,
contours,
contourIdx,
color[,
thickness[,
lineType[,
hierarchy[,
maxLevel[,
offset]]]]] )
其中,函数的返回值为image,表示目标图像,即绘制了边缘的原始图像。
该函数有如下参数:
● image:待绘制轮廓的图像。需要注意,函数cv2.drawContours()会在图像image上直接绘制轮廓。也就是说,在函数执行完以后,image不再是原始图像,而是包含了轮廓的图像。因此,如果图像image还有其他用途的话,则需要预先复制一份,将该副本图像传递给函数cv2.drawContours()使用。
● contours:需要绘制的轮廓。该参数的类型与函数cv2.findContours()的输出contours相同,都是list类型。
● contourIdx:需要绘制的边缘索引,告诉函数cv2.drawContours()要绘制某一条轮廓还是全部轮廓。如果该参数是一个整数或者为零,则表示绘制对应索引号的轮廓;如果该值为负数(通常为“-1”),则表示绘制全部轮廓。
● color:绘制的颜色,用BGR格式表示。
● thickness:可选参数,表示绘制轮廓时所用画笔的粗细。如将该值设置为“-1”,则表示要绘制实心轮廓。
● lineType:可选参数,表示绘制轮廓时所用的线型。关于参数color、thickness和lineType的具体介绍,可参考后面的第19章。
● hierarchy:对应函数cv2.findContours()所输出的层次信息。
● maxLevel:控制所绘制的轮廓层次的深度。如果值为0,表示仅仅绘制第0层的轮廓;如果值为其他的非零正数,表示绘制最高层及以下的相同数量层级的轮廓。
● offset:偏移参数。该参数使轮廓偏移到不同的位置展示出来。
函数cv2.drawContours()的参数image和返回值image,在函数运算后的值是相同的。因此,也可以将函数cv2.drawContours()写为没有返回值的形式:
cv2.drawContours(
image,
contours,
contourIdx,
color[,
thickness[,
lineType[,
hierarchy[,
maxLevel[,
offset]]]]] )
轮廓实例
下面通过具体实例说明如何获取轮廓、绘制轮廓。
eg1:绘制一幅图像内的所有轮廓。:
分析:如果要绘制图像内的所有轮廓,需要将函数cv2.drawContours()的参数contourIdx的值设置为“-1”。
代码如下:
import cv2
o = cv2.imread('contours.bmp')
cv2.imshow("original",o)
gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
image,contours, hierarchy = cv2.findContours(binary,
cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
o=cv2.drawContours(o,contours,-1,(0,0,255),5)
cv2.imshow("result",o)
cv2.waitKey()
cv2.destroyAllWindows()
在本程序中,轮廓的颜色被设置为红色,即(0, 0, 255),参数thickness(轮廓线条的粗细)被设置为“5”。
运行上述程序,结果如下图所示,图像内的所有轮廓都被绘制出来了。
eg2:逐个显示一幅图像内的边缘信息。
分析:如果要绘制图像内的某个具体轮廓,需要将函数cv2.drawContours()的参数contourIdx设置为具体的索引值。本例通过循环语句逐一绘制轮廓。
代码如下:
import cv2
import numpy as np
o = cv2.imread('contours.bmp')
cv2.imshow("original",o)
gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
image,contours, hierarchy = cv2.findContours(binary,
cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
n=len(contours)
contoursImg=[]
for i in range(n):
temp=np.zeros(o.shape,np.uint8)
contoursImg.append(temp)
contoursImg[i]=cv2.drawContours(
contoursImg[i],contours,i,(255,255,255),5)
cv2.imshow("contours[" + str(i)+"]",contoursImg[i])
cv2.waitKey()
cv2.destroyAllWindows()
本程序中将轮廓设置为白色,即(255, 255, 255)。
运行上述程序,结果如下图所示,图像内的轮廓被逐一绘制出来。
eg3:使用轮廓绘制功能,提取前景对象。
分析:将函数cv2.drawContours()的参数thickness的值设置为“-1”,可以绘制前景对象的实心轮廓。将该实心轮廓与原始图像进行“按位与”操作,即可将前景对象从原始图像中提取出来。
代码如下:
本例中将函数cv2.drawContours()的参数thickness设置为“-1”,得到了前景对象的实心轮廓mask。接下来,通过语句“cv2.bitwise_and(o, mask)”,将原始图像o与实心轮廓mask进行“按位与”运算,就得到了原始图像的前景对象。
运行上述程序,结果如下图所示。其中:
● 左图是原始图像,其前景对象是一朵小花。
● 中间的图像是从原始图像得到的小花的实心轮廓。
● 右图是提取的前景对象小花。