赞
踩
Opencv图像轮廓检测主要是通过对图像进行边缘提取,并将提取出的边缘连接成为一个完整的边缘线来实现的。
和边缘的区别,边缘是零散的,而图像的轮廓是一个整体
cv2.findContours() 是Opencv库中的一个函数,用于在二值化图像中查找轮廓。该函数的参数包括三个部分:
img: 需要查找轮廓的源图像,必须是一个灰度图或二值图。
mode: 轮廓检索模式,指定如何检测轮廓。有四种模式可选:
method: 轮廓逼近方法,应用于轮廓线的建立。有三种方法可选:
cv2.findContours() 函数返回两个值:
此次用的测试图片如下图,car.jpg
为了更精确的结果,往往要把图片转换成二值图 复习一下之前讲过的图像阈值threshold方法,可以将图像转换成二值图,以下是图像转换成二值图。
- import cv2
-
- #写一个方法用于展示图像,展示后按任意键继续下行代码
- def cv_show(title,img):
- cv2.imshow(title,img)
- cv2.waitKey(0)
- cv2.destroyAllWindows()
- return
-
- img = cv2.imread('car.jpg')
- img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转换成灰度图
- ret, binary = cv2.threshold(img,122,255,cv2.THRESH_BINARY)#灰度图转化成二值图,通过图像阈值的方法。
-
- cv_show('img',binary)#展示图片,按任意键继续
结果:
用转换后的二值图进行轮廓检测,完整代码如下:
- import cv2
- import numpy as np
-
- #写一个方法用于展示图像,展示后按任意键继续下行代码
- def cv_show(title,img):
- cv2.imshow(title,img)
- cv2.waitKey(0)
- cv2.destroyAllWindows()
- return
-
- img = cv2.imread('car2.jpg')
- gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转换成灰度图
- ret, binary = cv2.threshold(gray,122,255,cv2.THRESH_BINARY)#灰度图转化成二值图,通过图像阈值的方法。
- contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)#寻找轮廓
-
- copy = img.copy()
- resoult = cv2.drawContours(copy,contours[:],-1,(0,0,255),1)
- cv_show('res',resoult)
- print(np.array(contours).shape)
解释代码:
在计算完轮廓后,我们将找到的轮廓绘制在原图上。
这段代码使用了 cv2.drawContours() 函数在输入图像的副本上绘制了所有轮廓线。
具体来说,该函数的参数依次为:
copy:输入图像的副本,由于cv2.drawContours()方法会改变原对象,所以输入的img得先copy一个。
contours[:]:待绘制的轮廓列表,即所有轮廓
-1:绘制所有轮廓
(0,0,255):轮廓线的颜色,这里为红色 (0,0,255),BGR顺序
1:轮廓线的线宽,这里为1个像素
由于 cv2.drawContours() 函数可以同时处理多个轮廓,因此传入 contours[:] 可以绘制所有轮廓线。最终的绘制结果保存在 resoult 中,可以通过 cv_show() 函数展示出来。
结果:
通过结果发现轮廓检测很好地找到了图像中的所有轮廓,但是与此同时,我们发现乱七八糟的轮廓太多了,所以我们在实际应用中,通常不会直接对二值图进行图像检测,都要进行降噪处理。
下面是降噪处理后的完整代码:
- import cv2
- import numpy as np
-
- def cv_show(name,img):
- cv2.imshow(name,img)
- cv2.waitKey()
- cv2.destroyAllWindows()
-
- img = cv2.imread('car2.jpg')
- gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
- ret, binary = cv2.threshold(gray, 90, 255, cv2.THRESH_BINARY)
-
- # 高斯滤波降噪
- binary= cv2.GaussianBlur(binary, (5,5), 0)
- # 形态学开闭运算降噪
- kernel = np.ones((3,3), np.uint8) # 定义卷积核
- binary = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel, iterations=1)#开运算
- binary = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel, iterations=1)#闭运算
-
- edges = cv2.Canny(binary, 100, 200, apertureSize=3)
-
- cv_show("car2",edges)
-
- contour,hierarchy = cv2.findContours(edges, cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)#寻找轮廓,都储存在contour中
-
- copy = img.copy()
- resoult = cv2.drawContours(copy,contour[:],-1,(0,0,255),2)
- cv_show('res',resoult)
以上代码中,我先后对图像进行了高斯滤波降噪和开闭运算降噪处理,注意我调用了两次cv_show,这个方法用于展示图像,按任意键继续
结果:一些边缘消失了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。