2011-10-01 271 views
1

我正在爲一個類編寫一個C++程序來進行頻域卷積,並且我注意到最終結果在角落有錯誤。所以我在MATLAB中試了一下,得到了完全相同的結果。例如頻域中的圖像卷積(MATLAB)

使用攝影師從http://engronline.ee.memphis.edu/eece7214/images/Downlodable.htm

我做

a = imread('cameraman.pgm'); 
h = ones(25,25)/25/25; 
a(512,512) = 0; 
h(512,512) = 0; 
c = ifft2(fft2(a).*fft2(h))/256; 
c = c(1:256, 1:256); 
c = real(c); 
imwrite(c,'test2.png') 

我看了一眼位於C提取左上角前,我發現這是同樣的答案imfilter(A,H)除了它從角落翻譯了一點。岡薩雷斯的數字圖像處理沒有說到這一點,谷歌已經離開了我的眼睛流血搜索沒有幫助(大家重複岡薩雷斯提出了相同的指示提取左上角)。

與主要問題無關,我也想知道爲什麼我必須在這個MATLAB代碼中除以256。在我的C++代碼中,我不需要縮放結果,而且我得到了與這個MATLAB代碼相同的答案。我做了一點玩弄一維向量(做conv和ifft(fft * fft)),我認爲'錯誤'是從輸出顯示'完整'卷積在頂部左角而不是「相同」卷積。但即使是這種情況,我不知道如何確定代碼「提取這部分只是爲了'相同',而不是'全''的左上角256x256部分」

編輯: 更多的使用谷歌搜索已通過http://jeremy.fix.free.fr/IMG/pdf/fftconvolution.pdf產生了可能的解決方案。它有很多我以前從未見過的數學符號,但從我可以收集的內容來看,如果你正在卷積一個nxn和一個mxm,提取m:(m + n-1)以從fft近似。我仍然希望聽到比我更專業的人的聲音,所以不要根據此更新選擇不發表評論!

回答

2

MATLAB從1到N索引數組。
規範C使用(和大多數C矩陣數學庫)索引從0到N-1的數組。 這可能是一個偏差的來源。

作爲一個身份,裸ifft(fft(x))算法在某處需要1/N的比例因子。一些C庫將1/N放在fft()中。許多人在ifft()中建立了這個比例因子。有些人在兩者中都放了1/sqrt(N)。有些不添加內置比例因子,要求用戶根據需要進行縮放以獲取身份。

0

您需要將它移動一半的窗口大小。 在這種情況下,你應該這樣做: c = c(13:256 + 12,13:256 + 12);代替: c = c(1:256,1:256);

由於您將信號從1提升到256,所以您用零填充信號但沒有得到任何用處 - 您仍然在邊緣發生抖動,並且在丟失的右角上出現有價值的信號。