轉:圖像處理之理解卷積

圖像處理之理解卷積函數

 

一:什麼是卷積spa

卷積公式是用來求隨機變量和的密度函數(pdf)的計算公式.
定義式:orm

z(t)=x(t)*y(t)= ∫x(m)y(t-m)dm.已知x,y的pdf,x(t),y(t).如今要求z=x+y的pdf.咱們做變量替顯,令 input

z=x+y,m=x.雅可比行列式=1.那麼,z,m聯合密度就是f(z,m)=x(m)y(z-m)*1.這樣,就能夠很容易求Z的在(z,m)中邊緣分佈 
即fZ(z)=∫x(m)y(z-m)dm.數學

因爲這個公式和x(t),y(t)存在一一對應的關係.爲了方便,因此記 ∫x(m)y(z-m)dm=x(t)*y(t) io

長度爲m的向量序列u和長度爲n的向量序列v,卷積w的向量序列長度爲(m+n-1),
當m=n時,
w(1) = u(1)*v(1) 
w(2) = u(1)*v(2)+u(2)*v(1) 
w(3) = u(1)*v(3)+u(2)*v(2)+u(3)*v(1) 
… 
w(n) = u(1)*v(n)+u(2)*v(n-1)+ … +u(n)*v(1) 
… 圖像處理

w(2*n-1) = u(n)*v(n) pdf


當m≠n時,應以0補齊階次低的向量的高位後進行計算 
這是數學中經常使用的一個公式,在機率論中,是個重點也是一個難點.變量

離散卷積的數學公式能夠表示爲以下形式:方法

f(x) =  - 其中C(k)表明卷積操做數,g(i)表明樣本數據, f(x)表明輸出結果。

舉例以下:

假設g(i)是一個一維的函數,並且表明的樣本數爲G = [1,2,3,4,5,6,7,8,9]

假設C(k)是一個一維的卷積操做數, 操做數爲C=[-1,0,1]

則輸出結果f(x)能夠表示爲 F=[1,2,2,2,2,2,2,2,1]  //邊界數據未處理

 

以上只是一維的狀況下,當對一幅二維數字圖像加以卷積時,其數學意義能夠解釋以下:

源圖像是做爲輸入源數據,處理之後要的圖像是卷積輸出結果,卷積操做數做爲Filter

在XY兩個方向上對源圖像的每一個像素點實施卷積操做。如圖所示:

 

粉紅色的方格每次在X/Y前進一個像素方格,就會產生一個新的輸出像素,圖中正中間深藍色的代

表要輸出的像素方格,走徹底部的像素方格,就獲得了全部輸出像素。

 

圖中,粉紅色的矩陣表示卷積操做數矩陣,黑色表示源圖像– 每一個方格表明一個像素點。

 

二:卷積在數字圖像處理中應用

一副數字圖像能夠看做一個二維空間的離散函數能夠表示爲f(x, y), 假設有對於二維卷積操

做函數C(u, v) ,則會產生輸出圖像g(x, y) = f(x, y) *C(u,v), 利用卷積能夠實現對圖像模糊處理,邊緣檢測,產生軋花效果的圖像。

 

一個簡單的數字圖像卷積處理流程能夠以下:

1.      讀取源圖像像素

2.      應用卷積操做數矩陣產生目標圖像

3.      對目標圖像進行歸一化處理

4.      處理邊界像素

三:一個純Java的卷積模糊圖像效果

 

四:關鍵代碼解釋

 

完成對像素點RGB顏色的卷積計算代碼以下:

for( int  row = 1;row < srcH-1;row++)

{

   for( int  col= 1;col< srcW-1;col++)

   {

       // red color,能夠看出卷積核大小爲3*3

       out3DData[row][col][1] =

       in3DData[row][col][1] +

       in3DData[row-1][col][1] +

       in3DData[row+1][col][1] +

       in3DData[row][col-1][1] +

       in3DData[row-1][col-1][1] +

       in3DData[row+1][col-1][1] +

       in3DData[row][col+1][1] +

       in3DData[row-1][col+1][1] +

       in3DData[row+1][col+1][1];

             

      // green color

      out3DData[row][col][2] =

       in3DData[row][col][2] +

       in3DData[row-1][col][2] +

       in3DData[row+1][col][2] +

       in3DData[row][col-1][2] +

       in3DData[row-1][col-1][2] +

       in3DData[row+1][col-1][2] +

       in3DData[row][col+1][2] +

       in3DData[row-1][col+1][2] +

       in3DData[row+1][col+1][2];

             

      // blue color

       out3DData[row][col][3] =

       in3DData[row][col][3] +

       in3DData[row-1][col][3] +

       in3DData[row+1][col][3] +

       in3DData[row][col-1][3] +

       in3DData[row-1][col-1][3] +

       in3DData[row+1][col-1][3] +

       in3DData[row][col+1][3] +

       in3DData[row-1][col+1][3] +

       in3DData[row+1][col+1][3];

 }

}

計算歸一化因子以及對卷積結果歸一化處理的代碼以下:

// find the peak data frominput and output pixel data.

int inpeak = 0;

int outPeak = 0;

for(int row=0; row<srcH; row++) {

    for(int col=0; col<srcW; col++) {

       if(inpeak < in3DData[row][col][1]) {

           inpeak = in3DData[row][col][1];

       }

             

       if(inpeak < in3DData[row][col][2]) {

           inpeak = in3DData[row][col][2];

       }

             

       if(inpeak < in3DData[row][col][3]) {

           inpeak = in3DData[row][col][3];

       }

             

       if(outPeak < out3DData[row][col][1]) {

           outPeak = out3DData[row][col][1];

       }

       if(outPeak < out3DData[row][col][2]) {

           outPeak = out3DData[row][col][2];

       }

       if(outPeak < out3DData[row][col][3]) {

           outPeak = out3DData[row][col][3];

       }

    }

}

 

// normalization

double outputScale = ((double) inpeak) / ((double)outPeak);

for(int row=0; row<srcH; row++) {

    for(int col=0; col<srcW; col++) {

out3DData[row][col][1] = (int)(outputScale * out3DData[row][col][1]);

out3DData[row][col][2] = (int)(outputScale * out3DData[row][col][2]);

out3DData[row][col][3] = (int)(outputScale * out3DData[row][col][3]);

    }

}

 

五:本文沒有說起的內容 –邊界像素處理

沒有處理邊緣像素,對邊緣像素的處理,有兩個能夠參考的方法

其一是直接填充法– 超出邊界部分的以邊界像素填充。

其二是線性插值法– 超出邊界部分的以 i/row的像素填充。

相關文章
相關標籤/搜索