2017-06-16 172 views
0

我想在c中從頭開始實現高斯模糊。我有一個程序創建一個結構並加載一個.bmp文件,創建一個高斯模糊濾鏡(前兩個for-loops),然後將高度,寬度和實際像素信息發送給另一個應用濾鏡的函數到圖像(下面的4個嵌套for循環)。應用後,它會輸出修改後的.bmp文件。目前它稍微有效,但它不能一直工作。我無法調整模糊的強度(所有模糊的水平看起來都一樣)。它也似乎錯過了圖像周圍像素的外邊緣。高斯模糊實現不完全工作

當我創建過濾器,我使用:

double sigma = 10.0; 
double r, s = 2.0 * sigma * sigma; 
double sum = 0.0; 

但它看起來相同的適馬是否爲1,10,100 - 我的理解是,它應該得到更加模糊與更大的西格瑪。

創建過濾器:

// generate 5x5 kernel 
for (int x = -2; x <= 2; x++) 
{ 
    for(int y = -2; y <= 2; y++) 
    { 
     r = sqrt(x*x + y*y); 
     gKernel[x+2][y+2] = (exp(-(r*r)/s))/(M_PI * s); 
     sum += gKernel[x + 2][y + 2]; 
    } 
} 

// normalize the Kernel 
for(int i = 0; i < 5; ++i) 
    for(int j = 0; j < 5; ++j) 
     gKernel[i][j] /= sum; 

,然後應用過濾器:

for (i = 1; i < bmp->height - 1; i++) 
{ 
    for (j = 1; j < bmp->width - 1; j++) 
    { 
     sum = 0.0; 
     for (p = 0; p < 5; p++) 
     { 
      for (q = 0; q < 5; q++) 
      { 
       sum += bmp->pixels[(i + p) * bmp->width + j + q] * gKernel[p][q]; 
      } 
     } 
     bmp->pixels[(i - 1) * (bmp->width) + j] = (unsigned char) sum ; 
    } 
} 

任何幫助,非常感謝!感謝您的時間。

+0

歡迎來到Stack Overflow。遵循SO約定使您更有可能獲得幫助。請閱讀如何提供一個MCVE。 https://stackoverflow.com/help/mcve – Gene

+0

當您增加西格瑪時,是否增加了您的過濾器內核大小? –

+0

否 - 你的意思是爲x的西格瑪生成一個x x內核,然後x + 5的x + 5內核生成一個y + 5的西格瑪?我只測試了5的內核大小5.當我增加西格瑪時,我應該增加這個值嗎? – kab403

回答

1

它錯過了邊緣點,因爲你已經告訴它這樣做。它也被硬編碼爲寬度爲5個像素的內核。

邊緣始終是過濾的問題。通常最好是擴大圖像,用鏡像填充。然後應用沒有特殊代碼的濾波器來處理邊緣條件。 寬*高* N * N方法非常慢。對於大型濾波器,您需要使用FFT進行濾波。這是一種更先進的技術。

+0

鑑於電腦總是按照你告訴他們的方式做,所以我認爲這是真的我告訴它錯過邊緣:)我只需要弄清楚如何解決它。從上面的評論中,我會看看用sigma值增加內核大小是否能解決問題 - 我沒有意識到這是一個問題。我會尋找填充和FFT。謝謝你的幫助! – kab403

0

今天早些時候我想到了這一點 - 多虧了那些迴應,你們都會有很多幫助!基本上,當我增加代碼以增加內核的大小時,我增加了西格瑪,我能夠調整圖像出現的模糊程度。我還添加了代碼來處理邊緣情況 - 在該筆記中,我正在使用if-else if-else語句,但我試圖找出填充。

現在我有:

// generate nxn kernel 
for (int i = 0; i < kSize; i++) 
{ 
    for(int j = 0; j < kSize; j++) 
    { 
     gKernel[i][j] = exp(-(i*i+j*j)/(2*sigma*sigma))/(2*M_PI*sigma*sigma); 
     sum += gKernel[i][j]; 
    } 
} 

你能想象的所有「5的上面現在被替換成 'kSize'。當我應用濾鏡時,我調整for循環從0到bmp-> width/height,然後調整我將像素置於循環體內的位置(這是if-else if-else語句進入的位置玩,儘管我會盡快改變)。再次感謝!