OpenCV-Python学习之路-10:Image Gradients(图像梯度)

参考依据

官方文档:https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_gradients/py_gradients.html#gradients

目标

  1. 寻找图像中的梯度、检测边缘等
  2. 学习到以下函数:cv2.Sobel()、cv2.Scharr()、cv2.Laplacian()等

图像梯度

OpenCV为我们提供了三个用于梯度检测的高通滤波器:Sobel,Scharr以及Laplacian

1. Sobel和Scharr求导

Sobel算子是高斯平滑求导运算的联合运算,因此它的抗噪性更好,在使用时,可以指定求导的方向x / y(水平方向或垂直方向)。还可以通过参数ksize指定内核的大小,如果ksize = -1(不指定),则默认使用大小为3x3的filter(此时,Scharr滤波器比Sobel滤波器的效果更好)。

Python: cv2.Sobel(src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]])
Python: cv2.Scharr(src, ddepth, dx, dy[, dst[, scale[, delta[, borderType]]]])

重要提示:ddepth为输出图像的深度,我们要注意,这里不能用cv2.CV_8U(8位无符号),因为在计算梯度时:White->Black这个方向计算得到的梯度是负值,如果使用uint8类型的话,会忽略掉这个方向的梯度,从而导致检测有误。因此最好将输出数据类型保留为更高的形式,例如cv2.CV_16S,16位的有符号数,或者更高阶的cv2.CV_64F等等。
Sobel

img = cv2.imread('0003.png',0)
sobelx = cv2.Sobel(img, cv2.CV_16S, 1, 0)  # 检测x方向梯度 ksize默认为3x3
sobely = cv2.Sobel(img, cv2.CV_16S, 0, 1)  # 检测y方向梯度
abx = cv2.convertScaleAbs(sobelx)  # 取sobelx绝对值,并转为uint8类型
aby = cv2.convertScaleAbs(sobely)  # 取sobelx绝对值,并转为uint8类型
 
dst = cv2.addWeighted(abx, 0.5, aby, 0.5, 0)  # 融合x、y两方向梯度

plt.subplot(121), plt.imshow(img, cmap='gray'), plt.title('原图')
plt.subplot(122), plt.imshow(abx, cmap='gray'), plt.title('x方向')
plt.show()
plt.subplot(121), plt.imshow(aby, cmap='gray'), plt.title('y方向')
plt.subplot(122), plt.imshow(dst, cmap='gray'), plt.title('边缘检测')
plt.show()

在这里插入图片描述
Scharr
代码和上面的差不多,只将Sobel换成对于的Scharr即可。

sobelx = cv2.Scharr(img, cv2.CV_16S, 1, 0)  # 检测x方向梯度 ksize默认为3x3
sobely = cv2.Scharr(img, cv2.CV_16S, 0, 1)  # 检测y方向梯度

在这里插入图片描述
Sobel vs. Scharr
scharr算子实际上是sobel算子的优化,从上述结果可以看出,scharr算子在处理边缘时比sobel精度高一些在ksize=3x3时,两种算子唯一的区别就是他们的卷积核不同,在时间复杂度都是一样的。但Scharr只应用在ksize=3x3的情况下,而Sobel可以为1, 3, 5, 7,...

2. Laplacian求导

图像的拉普拉斯算子由这个关系式计算:
在这里插入图片描述
其中每个梯度由Sobel方法求得,当ksize=1时,则使用以下内核进行滤波:
在这里插入图片描述

Python: cv2.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])

laplacian = cv2.Laplacian(img, cv2.CV_16S, ksize=3)
plt.subplot(121), plt.imshow(img, cmap='gray'), plt.title('原图')
plt.subplot(122), plt.imshow(abx, cmap='gray'), plt.title('Laplacian')
plt.show()

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值