图像梯度计算的是图像变化的速度。对于图像的边缘部分,其灰度值变化较大,梯度值也较大。一般情况下,图像梯度计算的是图像的边缘信息。严格来讲,图像梯度计算需要求导数,但图像梯度一般通过计算像素差值来得到梯度的近似值。
1.Sobel算子
Sobel算子是一种离散的微分算子,该算子结合了高斯平滑和微分求导运算。该算子利用局部差分寻找边缘,计算得到一个梯度的近似值。
滤波器通常是指有一幅图像根据像素点(x,y)邻近的区域计算得到另外一幅新图像的算法。滤波器规定了滤波时所采用的形状和该区域内像素值的组成规律。滤波器也被叫做“核”、“窗口”、“算子”、“掩模”、“模板”等。一般信号领域称之为滤波器,数学领域称为“核”。滤波的目标像素点的值等于原始像素值与其周围像素值的加权和,这个叫线性滤波器,基于这种线性核核滤波,就是我们熟悉的卷积。
1.1计算偏导数近似值
对于大小为3 X 3的Sobel算子,其水平方向上的偏导数Gx的计算方式:
其垂直方向上的偏导数Gy的计算方式:
注:由于十字路上的像素距离中间值最近,因此将差值权重设为2,其余差值权重设为1
1.2Sobel算子及函数使用
dst:代表目标图像;
src:代表原始图像;
ddepth:代表输出图像的深度,具体对应关系如下表:
dx:代表x方向上的求导阶数;
dy:代表y方向上的求导阶数;
ksize: 代表Sobel核的大小。当为-1时,则会使用Scharr算子进行运算。取值为1,3,5,7,当不输入的时候,默认为3。特殊的,当kSize = 1的时候,采用的模板为1*3或者3*1 而非平时的那些格式;
scale: 代表计算导数值时所采用的缩放因子,默认是1,即没有缩放。
delta: 代表加在目标图像上的值,默认是0;
borderType:代表边界样式。
在函数cv2.Sobel()中规定,可以将ddepth设置为-1,让处理结果与原始图像保持一致。但如果直接将cv2.Sobel()内ddepth参数的值设为-1,得到的计算结果可能是错的。
实际操作中计算梯度值可能会是负数,如果处理的图像是八位图类型,若设置的ddepth是-1,则所有计算结果中的负数会自动截断为0,发生信息丢失。为避免信息丢失,在计算时需要先使用更高的数据类型cv2.CV_64F,再通过绝对值将其映射为cv2.CV_8U.所以,通常将函数cv2.Sobel()内ddepth参数的值设为cv2.CV_64F。
在OpenCV中,使用cv2.convertScaleAbs(src[,alpha[,beta]]),来对参数取绝对值;
alpha:代表调节系数,该值是可选值,默认为1.
beta:代表调节亮度值,该值是可选值,默认为0.
该函数的作用是将原始图像转换为256色位图。可以表述为:
saturate()表示计算结果的最大值是饱和值,例如当结果超过255时,就取255。
参数dx和参数dy,通常值是0或1,最大值是2。如果是0,表示在该方向上没有求道。dx和dy不能同时为0。
例如,计算一个图像水平方向上的边缘:
其他情况:
2.Scharr算子及函数使用
在离散空间上,有许多方法可以来计算近似导数,在使用3 X 3的Sobel算子时,可能近似结果并不太精准。Scharr算子有更高的精度,且运算速度并没有降低。其核通常为:
、
OpenCV提供函数来实现Scharr运算:
各参数的意义和Sobel函数一致,Scharr仅作用于大小为3的内核。但需要注意的是:
1) ddepth 的值应该设为cv2.CV_64F,并对计算结果取绝对值,才能保证得到正确的结果;
2)参数dx和dy需要满足条件(否则会报错):dx >=0 && dy >=0 && dx+dy ==1
例如:
运行结果;
3.Laplacian算子
Laplacian算子是一种二阶导数算子,其具有旋转不变性,可以满足不同方向上的图像边缘锐化(边缘检测)的要求。一般算子的系数之和是0,例如一个3 X 3的Laplacian算子:
Laplacian类似二阶Sobel导数,需要计算两个方向上的梯度值。对于计算过程中可能会出现负数的情况,通常通过对运算结果取绝对值来避免。
ddepth: 代表图像的深度;
ksize: 代表用于二阶导数计算的核尺寸大小,该值必须是奇数,默认值是1。
scale: 代表计算导数值时所采用的缩放因子,默认是1,即没有缩放。
delta: 代表加在目标图像上的值,默认是0;
borderType:代表边界样式。
当ksize为1时,Laplacian计算时采用的3 X 3 的核如下:
通过从图像中减去它的Lapacian图像,可以增强图像的对比度,此时其算子(扩展算子)如下:
实例1:
运行结果: