zoukankan      html  css  js  c++  java
  • 图像梯度计算


    零、梯度理论

    可以把图像看成二维离散函数,图像梯度就是这个二维离散函数的求导:

    梯度一般产生在边缘位置;


    OpenCV 提供了三种不同的梯度滤波器,或者说高通滤波器:Sobel,Scharr和Lapacian。
    Sobel,Scharr其实就是求一阶或二阶导。
    Scharr是对Sobel的部分优化。
    Laplacian是求二阶导。


    一、Sobel 算子

    一个点附近是什么;

    $ G_x 水平, G_y 竖直 $

    将附近的点使用权重相加减,得到像素点差异值作为水平/垂直方向的梯度;

    以下以 3*3 的核为例

    $ G_x = left[ egin{matrix} -1 & 0 & +1 -2 & 0 & +2 -1 & 0 & +1 end{matrix} ight] * A $

    $ G_y = left[ egin{matrix} -1 & -2 & -1 0 & 0 & 0 +1 & +2 & +1 end{matrix} ight] * A $


    cv2. Sobel 方法

    Sobel(src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]]) -> dst

    • ddepth:图像的深度
    • dx和dy分别表示水平和竖直方向
    • ksize是Sobel算子的大小

    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    
    lena = cv2.imread('lena.jpg')
    lena_gray = cv2.imread('lena.jpg', 0)
    pie = cv2.imread('pie.png')
    
    # cv2.CV_64F 的位数更多,能表示负数的形式  
    sobelx = cv2.Sobel(pie, cv2.CV_64F, 1, 0, ksize=3)
    plt.imshow(sobelx)
    
    Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
    


    openCV 会对负数做截断;所以上方没有显示右侧的梯度;
    解决方法:取绝对值

    sobelx = cv2.Sobel(pie, cv2.CV_64F, 1, 0, ksize=3)
    sobelx = cv2.convertScaleAbs(sobelx)
    plt.imshow(sobelx)
    


    # 将 0,1 参数切换,计算竖直方向,不计算水平方向
    sobely = cv2.Sobel(pie, cv2.CV_64F, 0, 1, ksize=3)
    sobely = cv2.convertScaleAbs(sobely)
    plt.imshow(sobely)
    
    


    # 不能取 0,0
    sobelx = cv2.Sobel(pie, cv2.CV_64F, 1, 1, ksize=3)
    sobelx = cv2.convertScaleAbs(sobelx)
    plt.imshow(sobelx)
    


    # 计算整体的时候,分别计算 x 和 y,再求和;
    # 以上都设置为 1 的效果,没有这样求和的效果好;
    
    sobelxy = cv2.addWeighted(sobelx, 0.5, sobely, 0.5, 0)
    plt.imshow(sobelxy)
    


    
    sobelx = cv2.Sobel(lena_gray, cv2.CV_64F, 1, 0, ksize=3)
    sobelx = cv2.convertScaleAbs(sobelx)
    
    sobely = cv2.Sobel(lena_gray, cv2.CV_64F, 0, 1, ksize=3)
    sobely = cv2.convertScaleAbs(sobely)
    
    sobelxy = cv2.addWeighted(sobelx, 0.5, sobely, 0.5, 0)
    plt.imshow(sobelxy)
    
    
    


     plt.imshow(np.hstack([lena_gray,sobelxy]))
    


    二、Scharr 算子

    Sobel 算子 计算得到的值比较小;对数据更敏感;

    $ G_x = left[ egin{matrix} -3 & 0 & 3 -10 & 0 & 10 -3 & 0 & 3 end{matrix} ight] * A $

    $ G_y = left[ egin{matrix} -3 & -10 & -3 0 & 0 & 0 -3 & -10 & -3 end{matrix} ight] * A $


    scharrx = cv2.Scharr(lena_gray, cv2.CV_64F, 1, 0)
    scharry = cv2.Scharr(lena_gray, cv2.CV_64F, 0, 1)
    
    scharrx = cv2.convertScaleAbs(scharrx)
    scharry = cv2.convertScaleAbs(scharry)
    
    scharrxy = cv2.addWeighted(scharrx, 0.5, scharry, 0.5, 0)
    
    

    三、lapkacian 拉普拉斯算子

    Laplace Operator

    其他算子一般是一阶导;拉普拉斯用到了二阶导;

    用中间点和边缘四个点比较;

    不建议单独使用;一般和其他算法结合。

    $ G = left[ egin{matrix} 0 & 1 & 0 1 & -4 & 1 0 & 1 & 0 end{matrix} ight] * A $


    laplacian = cv2.Laplacian(lena_gray, cv2.CV_64F)
    
    laplacian = cv2.convertScaleAbs(laplacian)
     
    res = np.hstack((sobelxy, scharrxy, laplacian))
    plt.imshow(res)
    



  • 相关阅读:
    OpenStack Nova Release(Rocky to Train)
    5G 与 MEC 边缘计算
    Cinder LVM Oversubscription in thin provisioning
    浅析视频云行业及实现技术
    虚拟化技术实现 — KVM 的 CPU 虚拟化
    虚拟化技术实现 — QEMU-KVM
    云计算与虚拟化技术发展编年史
    计算机组成原理 — FPGA 现场可编程门阵列
    Installutil.exe 注册exe
    ASP.NET MVC- 布署
  • 原文地址:https://www.cnblogs.com/fldev/p/14371842.html
Copyright © 2011-2022 走看看