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

文章目录

    • 参考依据
    • 目标
    • 图像梯度
      • 1. Sobel和Scharr求导
      • 2. Laplacian求导

参考依据

官方文档: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()

OpenCV-Python学习之路-10:Image Gradients(图像梯度)_第1张图片
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方向梯度

OpenCV-Python学习之路-10:Image Gradients(图像梯度)_第2张图片
Sobel vs. Scharr
scharr算子实际上是sobel算子的优化,从上述结果可以看出,scharr算子在处理边缘时比sobel精度高一些在ksize=3x3时,两种算子唯一的区别就是他们的卷积核不同,在时间复杂度都是一样的。但Scharr只应用在ksize=3x3的情况下,而Sobel可以为1, 3, 5, 7,...

2. Laplacian求导

图像的拉普拉斯算子由这个关系式计算:
在这里插入图片描述
其中每个梯度由Sobel方法求得,当ksize=1时,则使用以下内核进行滤波:
OpenCV-Python学习之路-10:Image Gradients(图像梯度)_第3张图片

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()

OpenCV-Python学习之路-10:Image Gradients(图像梯度)_第4张图片

你可能感兴趣的:(玩玩OpenCV,opencv,python,计算机视觉)