OpenCV边缘检测
梯度算子:是一阶导数算子,是水平G(x),G(y)方向对应模板的组合,也有对角线方向。
常见的一阶算子:
Roberts交叉算子,Rrewitt算子,Sobel算子
0 | 1 |
-1 | 0 |
=
1 | 0 |
0 | -1 |
Roberts交叉算子是对角线方向的梯度算子,对应的水平方向和竖直方向的梯度分别为:
Robert算子优缺点:
优点:边缘定位比较准,适用于边缘明显且噪声较少的图像。
缺点:没有描述水平和 竖直方向的灰度变化,只是关注了对角线方向,鲁棒性差,由于点本身参与了梯度计算,不能有效抑制噪声的干扰。
Sobel算子:
=
-1 | 0 | 1 |
-2 | 0 | 2 |
-1 | 0 | -1 |
=
1 | 2 | 1 |
0 | 0 | 0 |
-1 | -2 | -1 |
Sobel算子引入了类似局部加权平均的运算,对边缘的定位比prewitt 算子好。
sobel算子函数:
dst=cv2.Sobel(src,ddepth,dx,dy,ksize)
参数说明:参数2:图像的深度,-1表示采用的与原图像相同写深度。目标图像的深度必须大于等于原图像的深度;
参数3,4.dx,dy表示的是求导的阶数,0表示这个方向上没有求导,一般为0,1,2
参数5:ksize是sobel算子的大小,必须为1,3,5,7.
#Sobel算子练习
import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('test.jpg',0)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=5)
plt.subplot(1,3,1),plt.imshow(img,cmap = 'gray')
plt.title('Original'),plt.xticks([]),plt.yticks([])
plt.subplot(1,3,2),plt.imshow(sobelx,cmap = 'gray')
plt.title('Sobel X'),plt.xticks([]),plt.yticks([])
plt.subplot(1,3,3),plt.imshow(sobely,cmap = 'gray')
plt.title('Sobel Y'),plt.xticks([]),plt.yticks([])
plt.show()
梯度图结果:
Canny边缘检测算法
先平滑后求导。
评价边缘检测性能优劣的指标:
1好的信噪比,2高的定位性能,3虚假相应边缘应该得到最大抑制。
cv2.Canny(image,th1,th2,Size)
image:源图像
dth1:阈值1
th2:阈值2
Size:可选参数,Sobel算子的大小
步骤:
1彩色图像转换为灰度图像(以灰度图单通道图读入)
2对图像进行高斯模糊(去噪)
3计算图像梯度,根据梯度计算图像边缘幅值与角度
4沿梯度方向进行非极大值抑制(边缘细化)
5双阈值边缘连接处理
6二值化图像输出结果
import cv2
import numpy as np
img = cv2.imread('test.jpg')
v1 = cv2.Canny(img,80,150,(3,3))
v2 = cv2.Canny(img,50,100,(5,5))
ret = np.hstack((v1,v2))
cv2.imshow('img',ret)
cv2.waitKey(0)
cv2.destroyAllWindows()
实验测试用的原图:
还没有评论,来说两句吧...