圖像卷積及其Python實現

  • 卷積簡介

卷積(Convolution)是數學上的一種積分變換,主要作用是爲了獲取某個函數的局部信息,被廣泛應用於信號、圖像和機器學習等領域。本文給出了圖像卷積的Python實現。

  • 算法實現
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
class ImageCov( object ):
    #image   :原圖像
    #convImg :卷積圖像
    #mfilter :濾波器
    def __init__( self, filename, filterArr ):
        self.image = np.array( Image.open( filename ) )
        [ mI, nI ] = np.shape( self.image )
        self.convImg = np.zeros( (mI, nI) )
        self.mfilter = filterArr
    #顯示圖像
    def showImg( self ):
         plt.figure(  )
         plt.imshow( self.image )
         plt.axis( 'off' )
         
         plt.figure(  )
         plt.imshow( self.convImg )
         plt.axis( 'off' )
    #計算兩個矩陣的內積
    def Dot2D( self, a, b ):
        c = np.multiply( a, b )
        d = np.sum( c )
        if d < 0:
            d = -d
        elif d > 255:
            d = 255
        return d
    
    #計算二維濾波器的大小和半徑
    def FilterRadius( self ): 
        [mF, nF] = np.shape( self.mfilter )
        half_mF = int( mF / 2 )
        half_nF = int( nF / 2 )
        return mF, nF, half_mF, half_nF
    
    #根據濾波器的大小對原始圖像進行擴充,以確保卷積之後的圖像與原圖像大小相同
    #fWidth, fHeight, fHalfWidht, fHalfHeight:濾波器的:寬、高、寬半徑、高半徑
    #tempImage:擴充後的圖像
    def  ImageExtension( self, fWidth, fHeight, fHalfWidht, fHalfHeight ):
        [mI, nI] = np.shape( self.image )
        if fHeight % 2 > 0 :
            fHeight = fHeight - 1
        if fWidth % 2  > 0:
            fWidth = fWidth - 1

        tempImage = np.zeros( (mI + fHeight, nI + fWidth) )
        aUp       = np.zeros( (fHalfHeight, nI + fWidth) )  #上側和下側增加部分的數據
        aLeft     = np.zeros( (mI, fHalfWidht) )            #左側和右側增加部分的數據
        aMiddle   = np.hstack( (aLeft, self.image, aLeft) )    #中間部分的數據
        tempImage = np.vstack( (aUp, aMiddle, aUp) )      #擴展之後的圖像數據

        return tempImage


    def ImageConvolution( self ):
        [ mI, nI ] = np.shape( self.image )
        [ mF, nF ] = np.shape( self.mfilter )
        
        if mF % 2 > 0:
            tempmI = mI - 1
        else:
            tempmI = mI
        if nF % 2 > 0:
            tempnI = nI - 1
        else:
            tempnI = nI
        
        #依次截取與濾波器大小相同的圖像塊進行內積運算
        for i in range( tempmI - 1 ):
            for j in range( tempnI - 1 ):
                localImage = np.zeros( (mF, nF) )
                for it in range( mF ):
                    for jt in range( nF ):
                        localImage[it][jt] = self.image[i+it][j+jt]
                self.convImg[i][j] = self.Dot2D( localImage, self.mfilter )


def main():
    filter1 = [ [-1, -2, -1], [0, 0, 0], [1, 2, 1] ]
    img1 = ImageCov ( 'lena.bmp', filter1 ) 
    img1.ImageConvolution()
    img1.showImg()
    
    filter2 = [ [-1, 0, 1], [-2, 0, 2], [-1, 0, 1] ]
    img2 = ImageCov ( 'lena.bmp', filter2 ) 
    img2.ImageConvolution()
    img2.showImg()
    
    filter3 = [ [1, -1], [1, -1] ]
    img3 = ImageCov ( 'lena.bmp', filter3 ) 
    img3.ImageConvolution()
    img3.showImg()
    
    filter4 = [ [1, 1], [-1, -1] ]
    img4 = ImageCov ( 'lena.bmp', filter4 ) 
    img4.ImageConvolution()
    img4.showImg()

if __name__ == '__main__':
    main()

作者:YangYF

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章