use*_*114 4 matlab fft shape computer-vision ifft
我试图从Trucco/Verri文本"3D计算机视觉的入门技术"中看到的着色算法重建经典形状,但我很难理解matlab中的fft函数.基本上,我需要使用可积性约束来获得图像的深度(Z).在这种情况下,我不确定何时使用fftshift.这是我到目前为止的代码.基于http://www.mathworks.com/matlabcentral/newsreader/view_thread/285244 我基本上将所有的fft2都包裹在fftshifts中,但我不认为这是正确的用法.有人可以向我解释一下使用情况以及我做错了什么吗?谢谢.基本上,我试图将我的p和q(基于像素强度的更新值)转换为傅里叶域,以便在方程C中使用它们.然后我想将方程C转换回时域因为那会给我Z的深度.我还想根据傅里叶域中的C更新P和Q.
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)));
Run Code Online (Sandbox Code Playgroud)
nis*_*pio 14
这是一个棘手的问题,因为一般来说没有正确的答案.可能有一些错误的答案.我会尽力解释.如果答案有点过于冗长,您可以随时跳到摘要部分,看看它是否有帮助.
陷阱#1:
当您使用Matlab fft(或在您的情况下fft2)函数时,输出的第一个元素(在您的情况下X(1,1))表示DC偏差.如果您随后调用fftshift输出,则所有内容都会以将DC偏置置于中心的方式移动.在二维情况下,它看起来像这样:

请注意,块1左上角的点移动到中心.虽然这是数据的完全有效表示,但我们必须小心,因为我们已经改变了(1,1)bin 的含义.如果我此时尝试逆变换,输出将是错误的!
B = ifft2(fft2(A)); % B is equal to A
C = ifft2(fftshift(fft2(A))); % C is not equal to A
Run Code Online (Sandbox Code Playgroud)
陷阱#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
Run Code Online (Sandbox Code Playgroud)
以下有用的注释可在Matlab文档中找到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
Run Code Online (Sandbox Code Playgroud)
陷阱#3:
DFT有许多有趣的属性,其中之一是真实的偶数序列的DFT是真实的和偶数的.我们经常可以将此事实用作简单的健全性检查.如果我们在fft函数中放入一个真实的,均匀的序列并找回一些不真实甚至是回归的东西,那么我们就会遇到问题.
我们必须仔细记录在DFT时偶数函数的样子.序列3 2 1 0 1 2 3似乎是均匀的,对吧?左半部分是右半部分的镜像.如果序列的第四个元素表示,则这是真的t=0.但是,由于FFT算法的设置方式,第一个元素始终代表t=0元素.
我们可以通过ifftshift在FFT之前执行操作来解决该问题,以便将中心移位到第一元素.请注意,对于具有偶数长度的序列,该元素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
Run Code Online (Sandbox Code Playgroud)
正如您在上一个示例中所看到的,说" 始终使用之前" 是不正确的.如果我的数据的第一个元素已经是元素怎么办?然后申请将是错误的事情.ifftshiftfftt=0ifftshift
通常,ifftshift只应在应用fft/ 之前使用ifft.在fft和ifft函数总是假设你的数据的第一个元素代表t=0和f=0分别.使用这些功能时你应该问自己的主要问题是" 我的数据中存在t=0(或f=0)在哪里?" 和"我想让他们住在哪里?"
通常,fftshift只应在应用fft/ 后使用ifft.给出这些函数的输出,使得第一个元素分别代表f=0和t=0.如果要重新排列数据,使得元素f=0和t=0元素出现在中心,那么这fftshift是正确的答案.
如果没有更准确地了解您正在使用的数据代表什么,就不可能说出是否需要任何ifftshift或fftshift功能.请注意,在许多情况下,可以使用fft/ fft2和ifft/ ifft2正确而无需调用fftshift或ifftshift.