计算图像变化的速度,一般通过计算像素的差来得到梯度的近似值。
sobel算子也就是sobel滤波器,线性滤波器是滤波的目标像素点的值等于原始像素值及其周围像素值的加权和。
P5x = (P3-P1)+2(P6-P4)+P9-P7
P5y = (P7-P1)+2(P8-P2)+P9-P3
sobel函数:
dst=cv2.Sobel (src,ddepth,dx,dy[,ksize[,scale[,delta[ ,borderType]]]])
ddepth: 输出图像的深度,通常为cv2.CV_64F
dx: x方向上的求导阶数
dy: y方向上的求导阶数
ksize: sobel核的大小,如果等于-1,则会使用Scharr函数
scale: 导数值的放缩因子,默认为1,无放缩
delta: 加在目标图像上的值,默认为0
borderType: 边界样式
在实际操作中,计算梯度值可能会出现负数,图像通常是8位的,如果值为负数,那么会变成0,发生信息丢失。为了避免信息丢失,我们要用cv2.CV_64F,然后在取绝对值映射为8位图类型的。
取绝对值函数:
dst=cv2.convertScaleAbs (src[,alpha[,beta]])
alpha:调节系数,默认值为1
beta:调节亮度,默认值为0
函数作用是,将原始图像转为256色位图
参数dx和dy的组合方式:
(1)dx=1,dy=0;计算x方向边缘
(2)dx=0,dy=1;计算y方向边缘
(3)两个参数的值均为1,获取两个方向的边缘
(4)x和y方向的边缘叠加
dx=cv2.Sobel (src ,ddepth ,1 ,0)
dy=cv2.Sobel (src ,ddepth ,0 ,1)
dst=cv2.addWeighted (src1 ,alpha ,src2 ,beta ,gamma)
addWeighted()函数说明:权重加法函数
cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]])
alpha: 第一张图像权重
beta: 第二张图像权重
gamma: 灰度系数,图像矫正的偏移量,用于亮度调节
dtype : 输出图像的深度
示例:两种方式实现处理边缘信息
方式1: 分别使用**“dx=1,dy=0"和“dx=0,dy=1"**计算图像在水平方向和垂直方向的边缘信息,然后将二者相加,构成两个方向的边缘信息。
方式2∶ 将参数dx和dy的值设为**“dx=1,dy=1”**,获取图像在两个方向的梯度。组合(4)
import cv2
o=cv2.imread ('lena.png',cv2.IMREAD_GRAYSCALE)
Sobelx=cv2.Sobel (o,cv2.CV_64F,1,0)
Sobely=cv2.Sobel (o,cv2.CV_64F,0,1)
Sobelx=cv2.convertScaleAbs (Sobelx)
Sobely=cv2.convertScaleAbs (Sobely)
Sobelxy=cv2.addWeighted (Sobelx,0.5,Sobely,0.5,0) //方式2
Sobelxy11=cv2.Sobel (o,cv2.CV_64F,1,1)
Sobelxy11=cv2.convertScaleAbs (Sobelxy11) //方式1
cv2.imshow ( "original",o)
cv2.imshow ( "xy",Sobelxy)
cv2.imshow ( "xy11",Sobelxy11)
cv2.waitKey ()
cv2.destroyAllWindows ()
结果:
可以看做是对sobel算子的改进,速度一样,但精度更高。其核为:
cv2.Scharr()函数
dst=cv2.Scharr(src,ddepth,dx,dy[,scale[,delta[,borderType]]])
scale: 放缩因子,默认值为1
delta: 图像的亮度值,默认值为0
dst=cv2.Scharr (src,ddepth,dx,dy) = dst=cv2.Sobel (src,ddepth,dx,dy,-1)
cv2.Scharr()函数使用方法和sobel一致,要对函数的计算结果取绝对值
使用方法:
dst=Scharr (src,cv2.CV_64F,dx,dy)
dst=cv2.convertScaleAbs (dst)
dx和dy满足的条件为:
dx >=0 && dy >=0 && dx+dy==1
(1)计算x方向边缘(梯度):dx=1,dy=0。
(2)计算y方向边缘(梯度)::dx=0,dy=1。
(3)计算x方向与y方向的边缘叠加:通过组合方式实现。
dx=Scharr(src,ddpeth,dx=1,dy=O)
dy=Scharr(src,ddpeth,dx=O,dy=1)
Scharrxy=cv2.addWeighted (dx,0.5,dy,0.5,0)
注意:dx和dy不能为1
两者比较:
分别用Sobel算子和Scharr算子:
import cv2
o=cv2.imread ('lena.png',cv2.IMREAD_GRAYSCALE)
Sobelx=cv2.Sobel (o,cv2.CV_64F,1,0,ksize=3)
Sobely=cv2.Sobel (o,cv2.CV_64F,0,1,ksize=3)
Sobelx=cv2.convertScaleAbs ( Sobelx)
Sobely=cv2.convertScaleAbs ( Sobely)
Sobelxy=cv2.addWeighted ( Sobelx,0.5,Sobely,0.5,0)
Scharrx=cv2.Scharr (o,cv2.CV_64F,1,0)
Scharry=cv2.Scharr (o,cv2.CV_64F,0,1)
Scharrx=cv2.convertScaleAbs ( Scharrx)
Scharry=cv2.convertScaleAbs ( Scharry)
Scharrxy=cv2.addWeighted ( Scharrx,0.5,Scharry,0.5,0)
cv2.imshow ( "original",o)
cv2.imshow ("Sobelxy",Sobelxy)
cv2.imshow ("Scharrxy",Scharrxy)
cv2.waitKey ()
cv2.destroyAllWindows ()
结果:
拉普拉斯算子是一种二阶导数算子,具有旋转不变性,满足不同方向的图像边缘检测要求,通常,算子的系数和要为0
左图是Laplacian算子,右图是图像
像素点的近似导数值为:P5lap= (P2+P4+P6+P8)-4·P5
dst=cv2.Laplacian (src,ddepth[,ksize[,scale[,delta[,borderType]]]])
ksize: 计算二阶导数的核尺寸大小,其值必须为正数的奇数
scale: 放缩比例因子
delta: 加到目标图像上的可选值
当ksize的值大于1时,dst = 二阶偏导相加,
当ksize的值为1时,Laplacian算子计算时采用上述3×3的核
如果从图像内减去它的Laplacian图像,可以增强图像的对比度,其算子为扩展算子:
三个算子总结:
三个算子的核为:
Sobel算子和Scharr算子计算的是一阶近似导数的值,
Sobel算子、Scharr算子 = |左边像素值 - 右像素值| / |下像素值-上像素值|
Laplacian算子=|左-右|+|左-右|+|下-上|+|下-上|