2013-10-25 58 views
3

我正在嘗試從Trucco/Verri文本「3D計算機視覺的入門技巧」中看到的着色算法重新創建經典形狀,但我很難理解fft函數在matlab中。實質上,我需要使用可積性約束來獲得圖像的深度(Z)。在這種情況下,我不確定何時使用fftshift。這是我迄今爲止的代碼。基於http://www.mathworks.com/matlabcentral/newsreader/view_thread/285244 我基本上包裹了所有fft2s在fftshifts,但我不認爲這是正確的用法。有人可以向我解釋使用情況和我做錯了什麼嗎?謝謝。基本上,我試圖將我的p和q(基於像素強度的更新值)轉換爲傅里葉域,以便在方程C中使用它們。然後,我想將方程C轉換回時間域,因爲那會給我深度。我也想根據傅里葉域中的C更新P和Q.正確使用fft2和fftshift用於形狀陰影

wx = (2.* pi .* x) ./ m; 
    wy = (2.* pi .* y) ./ n; 
    wx = ifftshift(wx); wy=ifftshift(wy); 

    Cp = fftshift(fft2(fftshift(p))); 
    Cq = fftshift(fft2(fftshift(q))); 
    C = -1i.*(wx .* Cp + wy .* Cq)./(wx.^2 + wy.^2); 
    Z = abs((ifft2(ifftshift(C)))); 
    p = ifftshift(ifft2(ifftshift(1i * wx .* C))); 
    q = ifftshift(ifft2(ifftshift(1i * wy .* C))); 
+0

如果你可以多說一點你正在做的事情,這將有所幫助。就目前而言,您的代碼將無法運行,並且沒有任何關於這些代碼片段的含義。 – nispio

+0

嗨,我添加了一些代碼的解釋,我希望現在更清楚,基本上我想將p和q轉換爲傅立葉域,在傅立葉域中創建另一個方程C,然後返回到時域和方程C應該給Z. – user2009114

回答

13

這是一個棘手的問題,因爲通常沒有正確的答案。雖然可能有一些錯誤的答案。我會盡力解釋。如果答案有點太羅嗦,你總是可以跳到摘要部分,看看它是否有幫助。

陷阱

疑難雜症#1:

當您使用Matlab的fft(或你的情況fft2)功能,輸出的第一個元素(在你的情況X(1,1))表示DC bias。如果您隨後在輸出端上撥打fftshift,則所有情況都會以DC偏置爲中心的方式轉移。在二維情況下,它看起來是這樣的:

2-Dimensional fftshift

請注意,這是在框的左上角點被移到中央。雖然這是一個完全有效的數據表示,但我們必須小心,因爲我們有更改了(1,1)箱的含義。如果我在這一點上嘗試進行逆變換,那麼輸出結果就會錯誤!

B = ifft2(fft2(A));   % B is equal to A 
C = ifft2(fftshift(fft2(A))); % C is not equal to A 

疑難雜症#2:

ifftshift功能應該被認爲是作爲fftshift操作的逆操作。不應該認爲這是一種適用於ifft操作的轉變。出於這個原因,我覺得這個函數的名字很具誤導性。

以我的經驗,這是最常見的一種ifftshift上一頁fft/ifft功能,併爲fftshift遵循fft/ifft功能。事實上,我會走這麼遠說,如果你發現自己在做下面的事情之一,你可能已經犯了一個錯誤:

B = ifftshift(ifft(A));  % Don't do this 
C = fft(fftshift(A));   % Don't do this either 

以下有益音符在Matlab documentation for ifftshift

發現

注意:ifftshift將取消fftshift的結果。如果矩陣X包含奇數個元素,則必須完成ifftshift(fftshift(X))以獲得原始的X。簡單地執行fftshift(X)兩次將不會產生X

例如:

B = ifftshift(fftshift(A)); % B is equal to A 
C = fftshift(fftshift(A));  % C is not equal to A 

疑難雜症#3:

的DFT具有許多有趣的性質,其中之一是一個真實的,即使序列的DFT是真實的,即使。我們經常可以將這個事實用作簡單的完整性檢查。如果我們在fft函數中放入一個真正的,甚至是連續的序列,並找回那些並非真實甚至是不真實的東西,那我們就有問題了。

當涉及到DFT時,我們必須仔細注意偶函數的樣子。序列號3 2 1 0 1 2 3似乎是偶數,對吧?左半部分是右半部分的鏡像。如果序列的第四個元素代表t=0,則此將爲。但是,由於FFT算法的設置方式,第一個元素始終表示t=0元素。

我們可以通過在FFT之前執行ifftshift操作來解決該問題,以便將中心移至第一個元素。請注意,對於長度均勻的序列,假定元素x[N/2+1]爲中心。

A1 = [ 3 2 1 0 1 2 3 ];  % A1 real, even sequence about A1(4) 
B1 = fft(ifftshift(A1));  % B1 is a real, even sequence 
C1 = fft(A1);     % C1 is _not_ a real, even sequence 
abs(B1) == abs(C1)    % B1 and C1 differ only in phase 

A2 = [ 0 1 2 3 3 2 1 ];  % A2 real, even sequence about A2(0) 
B2= fft(ifftshift(A2));  % B2 is _not_ a real, even sequence 
C2= fft(A2);     % C2 is a real, even sequence 
abs(B2) == abs(C2)    % B2 and C2 differ only in phase 

你可以通過最後一個例子中看到的,這將是不正確說 「總是使用ifftshiftfft之前。」如果我的數據的第一個元素已經是t=0元素,該怎麼辦?然後申請ifftshift將是錯誤事情要做。

摘要

一般而言,ifftshift應該只用於之前施加fft/ifft。函數fftifft始終假定數據的第一個元素分別代表t=0f=0。在使用這些功能時,您應該問自己的主要問題是「t=0(或f=0)在我的數據中的位置?」和「我希望他們住在哪裏?「

一般來說,fftshift應該只施加fft/ifft後使用。這些函數的輸出被賦予這樣的第一要素分別爲f=0t=0代表。如果你想重新排列數據,使得f=0t=0元素出現在中央,然後fftshift是正確的答案。

不具有正是你正在使用的數據代表了更深入的瞭解,這將是很難說是否有任何ifftshiftfftshift個功能是必要的。請注意,有很多情況下,您可以正確使用fft/fft2ifft/ifft2而無需調用fftshiftifftshift

+0

如果矩陣具有偶數維,似乎fftshift(fftshift(A))等於原始矩陣A. ifftshift(ifftshift(A))也是一樣。 – Arturo

+0

最後一個例子中的錯字? B2 = fft(ifftshift(A)); - > B2 = fft(ifftshift(A2)); – Dov

+0

@Dov我想是的,謝謝。固定。 – nispio