sobel算子是一种计算不同方向上梯度的工具。原理是使用卷积核对图像进行处理。
如果想计算x方向梯度,我们就需要这样的一个卷积核
以卷积核的中心为中心,将卷积核与图像上像素值一一对应,卷积核上的数字相当于系数。利用如下公式即可计算出卷积核中心的x方向梯度。
同理,如果想要计算y方向的梯度,卷积核应该是这样的,公式也是同理。
我们求得了某一像素x方向和y方向的梯度,那么该像素的梯度容易得出:
但是这个公式比较难算,所以我们一般直接把这个公式化作:
opencv中提供给我们封装好的Sobel算子函数,不需要我们一一计算。
其构造函数如下:
cv2.Sobel(src,ddepth,dx,dy,ksize)
参数解释:
src:原图 ddepth:处理结果图像深度,一般我们都填-1,即与原图深度相同。但在这里我们需要填写cv2.CV_64F。简单来说就是如果填写-1,我们在计算梯度时产生的负数就会被程序默认为0,导致有一边的边缘出不来。而cv2.CV_64F范围更大,可以保留负数。 dx:计算x方向的梯度 dy:计算y方向的梯度 ksize:卷积核的尺寸。默认为3,即3*3的矩阵。函数在使用时。如果我们想要计算x方向的梯度:
cv2.Sobel(src,ddepth,1,0,ksize)
反之,计算y方向的梯度
cv2.Sobel(src,ddepth,0,1,ksize)
当然,想要计算总梯度直接dx=1,dy=1也是可以的,但是效果十分不好。不建议使用这种方法。
我们通常使用的方法是按权相加法。按权相加x方向梯度和y方向梯度。使用cv2.addWeight()
函数,该函数支持五个参数:
我们还要注意一件事。在我们分别计算完x、y方向的权值时,里面是有负数的。我们需要对这些负数取绝对值,否则照样会被归为0。
取绝对值的函数是cv2.convertScaleAbs(img)
import numpy as np
import cv2
img=cv2.imread('D://zopencv//qi.jpg',0)
mask_x=cv2.Sobel(img,cv2.CV_64F,1,0)#计算x方向梯度
mask_y=cv2.Sobel(img,cv2.CV_64F,0,1)
img_x=cv2.convertScaleAbs(mask_x)#取绝对值
img_y=cv2.convertScaleAbs(mask_y)
mask=cv2.addWeighted(img_x,0.5,img_y,0.5,0)#按权相加
#mask=cv2.Sobel(img,cv2.CV_64F,1,1)
Archie=cv2.resize(mask,None,fx=0.5,fy=0.5,interpolation=cv2.INTER_AREA)#图片太大了,缩小图片
cv2.imshow('Archie',Archie)
cv2.waitKey(0)
cv2.destroyAllWindows()
这是按权相加得到的边缘图
这是直接取dx=1,dy=1得到的边缘图
差距一目了然。