美文网首页
图像梯度

图像梯度

作者: 长歌行夜一 | 来源:发表于2020-07-05 11:56 被阅读0次

    图像梯度计算的是图像变化的速度。对于图像的边缘部分,其灰度值变化较大,梯度值也较大。一般情况下,图像梯度计算的是图像的边缘信息。严格来讲,图像梯度计算需要求导数,但图像梯度一般通过计算像素差值来得到梯度的近似值。

    1.Sobel算子

    Sobel算子是一种离散的微分算子,该算子结合了高斯平滑和微分求导运算。该算子利用局部差分寻找边缘,计算得到一个梯度的近似值。

    滤波器通常是指有一幅图像根据像素点(x,y)邻近的区域计算得到另外一幅新图像的算法。滤波器规定了滤波时所采用的形状和该区域内像素值的组成规律。滤波器也被叫做“核”、“窗口”、“算子”、“掩模”、“模板”等。一般信号领域称之为滤波器,数学领域称为“核”。滤波的目标像素点的值等于原始像素值与其周围像素值的加权和,这个叫线性滤波器,基于这种线性核核滤波,就是我们熟悉的卷积。

    1.1计算偏导数近似值

    对于大小为3 X 3的Sobel算子,其水平方向上的偏导数Gx的计算方式:

    Gx = \begin{bmatrix}
-1 & 0 & 1 \\
-2 & 0 & 2 \\
-1 & 0 & 1
\end{bmatrix} \cdot src

    其垂直方向上的偏导数Gy的计算方式:

    Gy = \begin{bmatrix}
-1 & -2 & -1 \\
0 & 0 & 0 \\
1 & 2 & 1
\end{bmatrix} \cdot src

    注:由于十字路上的像素距离中间值最近,因此将差值权重设为2,其余差值权重设为1

    1.2Sobel算子及函数使用

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

    dst:代表目标图像;

    src:代表原始图像;

    ddepth:代表输出图像的深度,具体对应关系如下表:

    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色位图。可以表述为:

    dst=saturate(src*alpha+beta)

    saturate()表示计算结果的最大值是饱和值,例如当结果超过255时,就取255。

    参数dx和参数dy,通常值是0或1,最大值是2。如果是0,表示在该方向上没有求道。dx和dy不能同时为0。

    例如,计算一个图像水平方向上的边缘:

    代码 运行结果

    其他情况:

    2.Scharr算子及函数使用

    在离散空间上,有许多方法可以来计算近似导数,在使用3 X 3的Sobel算子时,可能近似结果并不太精准。Scharr算子有更高的精度,且运算速度并没有降低。其核通常为:

    Gx = \begin{bmatrix}
-3 & 0 & 3 \\
-10 & 0 & 10 \\
-3 & 0 & 3
\end{bmatrix} \cdot src

    Gy = \begin{bmatrix}
-3 & -10 & -3 \\
0 & 0 & 0 \\
3 & 10 & 3
\end{bmatrix} \cdot src

    OpenCV提供函数来实现Scharr运算:

    dst = cv2.Scharr(src, ddepth, dx, dy[,scale[,delta[,borderType]]])

    各参数的意义和Sobel函数一致,Scharr仅作用于大小为3的内核。但需要注意的是:

    1) ddepth 的值应该设为cv2.CV_64F,并对计算结果取绝对值,才能保证得到正确的结果;

    2)参数dx和dy需要满足条件(否则会报错):dx >=0 && dy >=0 && dx+dy ==1

    例如:

    Scharr算子

    运行结果;

    可以看到更多的细节

    3.Laplacian算子

    Laplacian算子是一种二阶导数算子,其具有旋转不变性,可以满足不同方向上的图像边缘锐化(边缘检测)的要求。一般算子的系数之和是0,例如一个3 X 3的Laplacian算子:

    \begin{bmatrix}
0 & 1 & 0 \\
1 & -4 & 1 \\
0& 1 & 0
\end{bmatrix}

    Laplacian类似二阶Sobel导数,需要计算两个方向上的梯度值。对于计算过程中可能会出现负数的情况,通常通过对运算结果取绝对值来避免。

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

    ddepth: 代表图像的深度;

    ksize: 代表用于二阶导数计算的核尺寸大小,该值必须是奇数,默认值是1。

    scale: 代表计算导数值时所采用的缩放因子,默认是1,即没有缩放。

    delta: 代表加在目标图像上的值,默认是0;

    borderType:代表边界样式。

    当ksize为1时,Laplacian计算时采用的3 X 3 的核如下:

    \begin{bmatrix}
0 & 1 & 0 \\
1 & -4 & 1 \\
0& 1 & 0
\end{bmatrix}

    通过从图像中减去它的Lapacian图像,可以增强图像的对比度,此时其算子(扩展算子)如下:

    \begin{bmatrix}
0 & 1 & 0 \\
1 & -5 & 1 \\
0& 1 & 0
\end{bmatrix}

    实例1:

    比较不同的算子的差别

    运行结果:

    可以看出Laplacian的参数ksize默认值是1

    相关文章

      网友评论

          本文标题:图像梯度

          本文链接:https://www.haomeiwen.com/subject/anlyqktx.html