2014-04-06 128 views
0

我想用MATLAB使用兩種方法使用高斯濾波器卷積圖像:使用1D FFT的可分離卷積和使用2D FFT的不可分離卷積。我期待可分離卷積更快。但是,它不適用於小圖像,但適用於2D更快的較大圖像。我不確定這是否是我的實現問題,或者是因爲我沒有這個概念。使用一維FFT與二維FFT分離卷積

這是我的代碼:

img1 = randi([1,256],128,128);  

% Create a Gaassian filter 
rf1 = fspecial('gaussian', [1 128], 1.0); 
cf1 = transpose(rf1); 
gf1 = cf1 * rf1;  

rc1 = round(conv2(img1, gf1, 'same')); 
rc1 = fft2dconv(img1, gf1); 
rc2 = fft1dconv(img1, rf1, cf1); 


function o = fft1dconv(img, rowf, colf) 

% Zero-Pad 
imgsize = size(img); 
rsize = size(rowf); 
csize = size(colf); 

img = padarray(img, [imgsize(1)/2, imgsize(2)/2]); 
rowf = padarray(rowf, [2*imgsize(1)-rsize(1), 2*imgsize(2)-rsize(2)], 'post'); 
colf = padarray(colf, [2*imgsize(1)-csize(1), 2*imgsize(2)-csize(2)], 'post'); 


% Seperable convolution using 1D FFT 
tic; 
result = fft(transpose(fft(img))) .* fft(transpose(fft(colf))); 
result = result .* fft(transpose(fft(rowf))); 
o = transpose(round(real(ifft2(result)))); 
toc; 


% Remove Pad 
o = o(imgsize(1)+1:2*imgsize(1),imgsize(2)+1:2*imgsize(2)); 

end 


function o = fft2dconv(img, filter) 

%zero-pad 
imgsize = size(img); 
fsize = size(filter); 

img = padarray(img, [imgsize(1)/2, imgsize(2)/2]); 
filter = padarray(filter, [2*imgsize(1)-fsize(1), 2*imgsize(2)-fsize(2)], 'post'); 

% Non-Seperable convolution using 2D FFT 
tic; 
o = round(real(ifft2(fft2(img) .* fft2(filter)))); 
toc; 

% Remove Pad 
o = o(imgsize(1)+1:2*imgsize(1),imgsize(2)+1:2*imgsize(2)); 

end 

以及哪些是時序結果:

Elapsed time is 0.003315 seconds. 
Elapsed time is 0.004369 seconds. 

對於4×4圖像,所述可分離方法要快得多,但對於較大的圖像。事實並非如此,我不知道爲什麼。任何幫助將非常感激。

+0

只是一些猜測。 (我不知道足以驗證這些說法)MATLAB的'fft2'還執行分離性檢查(實際上也是一種SVD低秩逼近)。在內部,'fft2'使用ATLAS或FFTW,這兩者都是市面上最快的FFT實現。 (一些較早的版本使用IPP)最後,MATLAB內部使用的C實現(當與ATLAS和FFTW接口時)不需要執行轉置操作 - 它只是「告訴」底層庫以轉置的方式讀取數組。 – rwong

回答

0

我建議你profile你的代碼,看看是怎麼回事。它可能是您正在執行的其他一些操作,而不是自己的核心FFT計算。

進入MATLAB並輸入profile viewer。一旦你這樣做,在那個窗口運行你的命令並讓它完成。一旦完成,它將識別你的代碼的密集部分,你可以從中找出如何優化它。你說得對,分離式濾波器速度更快。

+0

@ user115188哇!一個從過去的鬼!你最終搞清楚爲什麼時機關閉了嗎? – rayryeng