1 实验目的
学习找轮廓,绘制轮廓等.
2 实验设备
安装了python和pychrm的电脑一台。
3 实验内容
包含图片的导入、轮廓检测、绘制轮廓、显示图片。
4实验原理
计算机视觉中,轮廓检测是另一个比较重要的任务,不单是用来检测图像或者视频帧中物体的轮廓,而且还有其他操作与轮廓检测有关。这些操作有:计算多边形边界、形状逼近和计算感兴趣区域。
函数:
cv2.fifindContours() 寻找轮廓
cv2.drawContours() 绘制轮廓
什么是轮廓
轮廓可以简单认为成将连续的点(连着边界)连在一起的曲线,具有相同的颜色或者灰度。轮廓在形状分析和物体的检测和识别中很有用。
轮廓检测要义:
• 为了更加准确,要使用二值化图像。在寻找轮廓之前,要进行阈值化处理或者 Canny 边界检测。
• 查找轮廓的函数会修改原始图像。如果你在找到轮廓之后还想使用原始图像的话,你应该将原始图像存储到其他变量中。
• 在 OpenCV 中,查找轮廓就像在黑色背景中超白色物体。你应该记住,要找的物体应该是白色而背景应该是黑色。
让我们看看如何在一个二值图像中查找轮廓:
函数 cv2.fifindContours()有三个参数,第一个是输入图像,第二个是轮廓检索模式,第三个是轮廓近似方法。返回值有三个,第一个是图像,第二个是轮廓,第三个是(轮廓的)层析结构。轮廓(第二个返回值)是一个 Python列表,其中存储这图像中的所有轮廓。每一个轮廓都是一个 Numpy 数组,包含对象边界点(x,y)的坐标。
轮廓发现是基于图像边缘提取的基础寻找对象轮廓的方法,所以边缘提取的阈值选定会影响最终轮廓发现结果。
contours, hierarchy=cv2.findContours(image, mode, method[, contours[, hierarchy[, offset]]])
参数:
image:源图像,8位单通道图像,非0像素值均按像素值为1处(非0的像素被看成1,0的像素值保持不变),单通道图像矩阵,可以是灰度图,但更常用的是二值图像,一般是经过Canny、拉普拉斯等边缘检测算子处理过的二值图像;该函数在提取轮廓的过程中会改变图像。
contours:轮廓信息,每个轮廓由点集组成,而所有的轮廓构成了contours列表 。
hierarchy:可选参数,表示轮廓的层次信息(拓扑信息,有种树结构的感觉),每个轮廓元素contours[i]对应4个hierarchy元素hierarchy[i][0]~hierarchy[i][3],分别表示后一个轮廓、前一个轮廓、父轮廓和内嵌轮廓的编号,若无对应项,则该参数为负值 。
mode:轮廓检索模式,有以下模式。
cv2.RETR_EXTERNAL:只检测最外层轮廓,并置hierarchy[i][2]=hierarchy[i][3]=-1
cv2.RETR_LIST:提取所有轮廓并记录在列表中,轮廓之间无等级关系 。
cv2.RETR_CCOMP:提取所有轮廓并建立双层结构(顶层为连通域的外围轮廓,底层为孔的内层边界) 。
cv2.RETR_TREE:提取所有轮廓,并重新建立轮廓层次结构
method:轮廓逼近方法,有以下逼近方法。
cv2.CHAIN_APPROX_NONE:获取每个轮廓的每个元素,相邻像素的位置差不超过1,即连续的点,但通常我们并不需要所有的点 。
cv2.CHAIN_APPROX_SIMPLE:压缩水平方向、垂直方向和对角线方向的元素,保留该方向的终点坐标,如矩形的轮廓可用4个角点表示,这是一种常用的方法,比第一种方法能得出更少的点 。
cv2.CHAIN_APPROX_TC89_L1和cv2.CHAIN_APPROX_TC89_KCOS:对应Tch-Chain链逼近算法。
为了在图像中显示出计算出的轮廓,我们使用drawContours函数绘制出轮廓。通常这个函数会配合findContours使用。
怎样绘制轮廓
函数 cv2.drawContours() 可以被用来绘制轮廓。它可以根据你提供的边界点绘制任何形状。它的第一个参数是原始图像,第二个参数是轮廓,一个 Python 列表。第三个参数是轮廓的索引(在绘制独立轮廓是很有用,当设置为 -1 时绘制所有轮廓)。接下来的参数是轮廓的颜色和厚度等。
绘制轮廓函数:
cv2.drawContours(image, contours, , color[, thickness[, lineType[, hierarchy[, maxLevel[, offset]]]]])
参数:
image:目标图像。
contours:所有的轮廓,可直接传入findContours函数中的contours参数 。
contourIdx:轮廓的索引,即绘制哪个轮廓,若为负值则绘制所有轮廓 。
color:绘制的颜色,元祖形式,如(255)或(255, 255, 255) 。
thickness:绘制的轮廓的线条粗细程度,若为负数,表示要填充整个轮廓。
注意:findContours()运行的时候,这个图像会被直接涂改,因此如果是将来还有用的图像,应该复制之后再传给findContours()。
5实验步骤
打开pycharm.
我们右击相应的文件目录,选择new--->点击Python File,然后输入新建的文件名,点击确定,相应的.py文件就建好了,可以进行编写代码了。
ipoert cv2
读取图片并转换为灰度图像。
img = cv2.imread("..\images\statue.jpg", 0)
调用threshold函数进行二值(将图像转化为0或255的像素,也就是黑白图像)。提取轮廓一般是用二值图像。
ret,frame=cv2.threshold(imgray,127,255,cv2.THRESH_BINARY)##二值化
调用findContours函数提取边界轮廓框。参数:输入图像,层次类型,轮廓逼近方法
这里我们采用cv2.RETR_TREE检索轮廓和cv2.CHAIN_APPROX_SIMPLE。
image, contours, hierarchy = cv2.findContours(frame, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
绘制所有轮廓,并用绿色绘制,线条粗细为1。 draw=cv2.drawContours(img,contours,-1,(0,255,0),1)显示绘制轮廓的图像。
cv2.imshow("img", img)
cv2.imshow("median",median)
cv2.waitKey()
原图和效果图:
原图和效果图