2011-08-09 52 views
2

我對圖像處理非常陌生,並發現FFT卷積加速了大內核大小的卷積。FFT卷積 - 如何應用內核

我的問題是,如何在使用kissFFT時將內核應用於頻率空間中的圖像?

我已經做了以下內容:

//I have an image with RGB pixels and given width/height 

const int dim[2] = {height, width}; // dimensions of fft 
const int dimcount = 2; // number of dimensions. here 2 
kiss_fftnd_cfg stf = kiss_fftnd_alloc(dim, dimcount, 0, 0, 0); // forward 2d 
kiss_fftnd_cfg sti = kiss_fftnd_alloc(dim, dimcount, 1, 0, 0); // inverse 2d 

kiss_fft_cpx *a = new kiss_fft_cpx[width * height]; 
kiss_fft_cpx *r = new kiss_fft_cpx[width * height]; 
kiss_fft_cpx *g = new kiss_fft_cpx[width * height]; 
kiss_fft_cpx *b = new kiss_fft_cpx[width * height]; 
kiss_fft_cpx *mask = new kiss_fft_cpx[width * height]; 

kiss_fft_cpx *outa = new kiss_fft_cpx[width * height]; 
kiss_fft_cpx *outr = new kiss_fft_cpx[width * height]; 
kiss_fft_cpx *outg = new kiss_fft_cpx[width * height]; 
kiss_fft_cpx *outb = new kiss_fft_cpx[width * height]; 
kiss_fft_cpx *outmask = new kiss_fft_cpx[width * height]; 

for(unsigned int i=0; i<height; i++) { 
    for(unsigned int l=0; l<width; l++) { 
     float red = intToFloat((int)Input(i,l)->Red); 
     float green = intToFloat((int)Input(i,l)->Green); 
     float blue = intToFloat((int)Input(i,l)->Blue); 

     int index = i * height + l; 

     a[index].r = 1.0; 
     r[index].r = red; 
     g[index].r = green; 
     b[index].r = blue; 
    } 
} 

kiss_fftnd(stf, a, outa); 
kiss_fftnd(stf, r, outr); 
kiss_fftnd(stf, g, outg); 
kiss_fftnd(stf, b, outb); 
kiss_fftnd(stf, mask, outmask); 


kiss_fftnd(sti, outa, a); 
kiss_fftnd(sti, outr, r); 
kiss_fftnd(sti, outg, g); 

當我再次設置圖像我得到原始圖像回RGB值。所以這個轉換是有效的 如果我想應用內核,我應該怎麼做,例如 9x9框模糊(1/9,1/9,... 1/9)。

我已閱讀了關於快速卷積的一些內容,但它們都不同,具體取決於FFT的實現。是否有一種「列表」在應用過濾器之前必須注意哪些事項?

的方式,我認爲:

的IMAGESIZE必須是2的冪; 我必須創建一個與圖像大小相同的內核。將9箇中間值設置爲1/9,其餘設置爲0,然後將此內核轉換爲頻域,然後將源圖像與它相乘,然後再轉換源圖像。但這並不奏效:DD

+0

這聽起來像你有正確的想法。當你在最後一句話中說「那真的沒用」時,你的意思是什麼? –

+0

好吧,逆變換後的圖像看起來像垃圾。我仍然認出這個圖像,但是有很多顏色,灰度倒轉的圖像和其他一些東西,所以不是很有用^^ – Marco

+0

我已經閱讀了一些關於FFT卷積的更多內容,有人說我需要填充出源圖片,爲什麼我需要做到這一點,以及哪些大小? – Marco

回答

3

在頻域中執行的卷積實際上是一個循環卷積。因此,當內核的非零元素到達圖片的邊緣時,它將環繞幷包含來自圖片另一側的像素,這可能不是您想要的。爲了解決這個問題,只需在內核中輸入零個元素,就像你在內核中有非零元素一樣(實際上少一個元素)。對於3x3內核,您需要在每個維度中添加3-1 = 2個零像素。