zoukankan      html  css  js  c++  java
  • Opencv 图像平滑基础二维离散卷积 python API

    二维离散卷积

    要进行二维离散卷积运算首先需要对矩阵边界进行扩充,opencv提供了函数copyMakeBorder

    import cv2
    import numpy as np
    src = np.array([[5,1,7],[1,5,9],[2,6,2]])
    dst = cv2.copyMakeBorder(src,2,2,2,2,cv2.BORDER_REFLECT_101)
    dst
    
    array([[2, 6, 2, 6, 2, 6, 2],
           [9, 5, 1, 5, 9, 5, 1],
           [7, 1, 5, 1, 7, 1, 5],
           [9, 5, 1, 5, 9, 5, 1],
           [2, 6, 2, 6, 2, 6, 2],
           [9, 5, 1, 5, 9, 5, 1],
           [7, 1, 5, 1, 7, 1, 5]], dtype=int32)
    

    实现二维离散卷积运算

    使用Python的科学计算包Scipy提供的函数:convolve2d(in1m in2m mode = ‘full’, boundary = ‘fill’, fillvalue = 0)

    #计算任意卷积核且任意指定的锚点的same卷积
    import numpy as np
    from scipy import signal
    #主函数
    if __name__ == "__main__":
        #输入矩阵
        I = np.array([[1,2],[3,4]],np.float32)
        # I 的高和宽
        H1, W1 = I.shape[:2]
        #卷积核
        K = np.array([[-1,-2],[2,1]],np.float32)
        # K的高、宽
        H2, W2 = K.shape[:2]
        #计算full卷积
        c_full = signal.convolve2d(I,K,mode = 'full')
        #指定锚点位置
        kr, kc = 0,0
        #更具锚点位置,从full卷积中截取得到same卷积
        c_same = c_full[H2-kr-1:H1+H2-kr-1,W2-kc-1:W1+W2-kc-1]
        print(c_same)
    
    [[-5. -6.]
     [11.  4.]]
    

    可分离卷积核

    一个卷积核至少由两个尺寸比它小的卷积核full卷积而成,并且在计算过程中在所有边界处均进行扩充0的操作

    full卷积不满足交换律,但是一维水平方向和一维垂直方向上的卷积核的full卷积是满足交换律的

    import numpy as np
    from scipy import signal
    # 主函数
    if __name__ == "__main__":
        kernel1 = np.array([[1,2,3]], np.float32)
        kernel2 = np.array([[4],[5],[6]], np.float32)
        #计算两个核的全卷积
        kernel = signal.convolve2d(kernel1,kernel2,mode = 'full')
        print(kernel)
    
    [[ 4.  8. 12.]
     [ 5. 10. 15.]
     [ 6. 12. 18.]]
    

    离散卷积核的性质

    1、full卷积的性质

    如果卷积核可以分离则满足结合利率

    import numpy as np
    from scipy import signal
    I = np.array([[1,2,3,10,12],
                  [32,43,12,4,190],
                  [12,234,78,0,12],
                  [43,90,32,8,90],
                  [71,12,4,98,123]],np.float32)
    K = np.array([[1,0,-1],
                  [1,0,-1],
                  [1,0,-1]],np.float32)
    #计算两者的full卷积
    I_Kernel = signal.convolve2d(I,K,mode='full',boundary = 'fill',fillvalue = 0)
    print(I_Kernel)
    
    
    [[   1.    2.    2.    8.    9.  -10.  -12.]
     [  33.   45.  -18.  -31.  187.  -14. -202.]
     [  45.  279.   48. -265.  121.  -14. -214.]
     [  87.  367.   35. -355.  170.  -12. -292.]
     [ 126.  336.  -12. -230.  111. -106. -225.]
     [ 114.  102.  -78.    4.  177. -106. -213.]
     [  71.   12.  -67.   86.  119.  -98. -123.]]
    
    kernel1 = np.array([[1],[1],[1]],np.float32)
    kernel2 = np.array([[1,0,-1]],np.float32)
    I_k1 = signal.convolve2d(I,kernel1,mode='full',boundary = 'fill',fillvalue = 0)
    I_k1_k2 = signal.convolve2d(I_k1,kernel2,mode='full',boundary = 'fill',fillvalue = 0)
    print(I_k1_k2)
    
    [[   1.    2.    2.    8.    9.  -10.  -12.]
     [  33.   45.  -18.  -31.  187.  -14. -202.]
     [  45.  279.   48. -265.  121.  -14. -214.]
     [  87.  367.   35. -355.  170.  -12. -292.]
     [ 126.  336.  -12. -230.  111. -106. -225.]
     [ 114.  102.  -78.    4.  177. -106. -213.]
     [  71.   12.  -67.   86.  119.  -98. -123.]]
    

    2、same卷积的性质

    讨论一种情况:Kernel的宽和高均为奇数,并且可以分离为水平和垂直方向一维卷积核,则满足结合律,利用此规律可以降低运算量

    c_same = signal.convolve2d(I,K,mode='same',boundary = 'fill',fillvalue = 0)
    print(c_same)
    
    [[  45.  -18.  -31.  187.  -14.]
     [ 279.   48. -265.  121.  -14.]
     [ 367.   35. -355.  170.  -12.]
     [ 336.  -12. -230.  111. -106.]
     [ 102.  -78.    4.  177. -106.]]
    
    #利用卷积核的分离性进行same卷积运算,且采用0扩充边界,如果不采用0扩充边界卷积结果的上下左右边界的值会不同,在图像处理中可以忽略
    c_same1 = signal.convolve2d(I,kernel1,mode='same',boundary = 'fill',fillvalue = 0)
    c_same2 = signal.convolve2d(c_same1,kernel2,mode='same',boundary = 'fill',fillvalue = 0)
    print(c_same2)
    
    [[  45.  -18.  -31.  187.  -14.]
     [ 279.   48. -265.  121.  -14.]
     [ 367.   35. -355.  170.  -12.]
     [ 336.  -12. -230.  111. -106.]
     [ 102.  -78.    4.  177. -106.]]
    
  • 相关阅读:
    linux centos 常用命令(需掌握)
    centos轻松搭建NFS
    Centos6.1在yum安装软件的时候,居然报错了,如何解决
    安装好Centos后,需要做的几件事情。
    使用scp命令传输文件
    批量删除文件或者批量修改文件
    Centos7搭建常用的LNMP架构
    python实现自动抠名字签名,比PS还快
    inotify软件实现实时同步,ssh-key 秘钥连接方式,saltstack实战批量管理Linux,expect批量分发秘钥
    Cisco 路由器配置OSPF 动态路由 (开放式最短路径优先)
  • 原文地址:https://www.cnblogs.com/PythonFCG/p/13860126.html
Copyright © 2011-2022 走看看