问题描述
我正试图从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)));
推荐答案
这是一个棘手的问题,因为通常没有正确的答案.虽然可能有一些错误的答案.我会尽力解释.如果答案过于罗word,您总是可以跳到摘要部分,看看是否有帮助.
当您使用Matlab的fft
(在您的情况下为fft2
)功能时,输出的第一个元素(在您的情况下为X(1,1)
)代表直流偏置.如果随后在输出上调用fftshift
,则所有内容都会以将DC偏置置于中心的方式转移.在二维情况下,看起来像这样:
When you use Matlab's fft
(or in your case fft2
) function, the first element of the output (in your case X(1,1)
) represents the DC bias. If you subsequently call fftshift
on your output, everything gets shifted around in a way that places the DC bias at the center. In the 2-dimensional case, it looks something like this:
请注意,位于块1左上角的点已移到中心.虽然这是数据的完全有效表示,但我们必须小心,因为我们已经更改了(1,1)bin的含义.如果要在这一点上尝试逆变换,则输出将是错误的!
Notice that the point that was at the top-left corner of block 1 gets moved to the center. While this is a perfectly valid representation of the data, we have to be careful because we have changed the meaning of the (1,1) bin. If I were to attempt an inverse transform at this point, the output would be wrong!
B = ifft2(fft2(A)); % B is equal to A
C = ifft2(fftshift(fft2(A))); % C is not equal to A
Gotcha#2:
ifftshift
函数应被视为fftshift
操作的逆函数.不应将其视为适用于ifft
操作的偏移.因此,我觉得函数名称很容易让人误解.
The ifftshift
function should be thought of as the inverse of the fftshift
operation. It should not be thought of as a shift that applies to ifft
operation. For this reason, I feel that the function names are very misleading.
以我的经验,最常见的情况是ifftshift
先于 一个fft
/ifft
函数,而一个fftshift
跟随fft
/ifft
功能.实际上,我要说的是,如果您发现自己做以下事情之一,则可能是您犯了一个错误:
In my experience, it is most common for an ifftshift
to precede an fft
/ifft
function, and for an fftshift
to follow fft
/ifft
function. In fact, I would go so far as to say that if you ever find yourself doing one of the following things, you have probably made a mistake:
B = ifftshift(ifft(A)); % Don't do this
C = fft(fftshift(A)); % Don't do this either
以下有用的说明可在 ifftshift
的Matlab文档中找到
The following helpful note is found in the Matlab documentation for ifftshift
例如:
B = ifftshift(fftshift(A)); % B is equal to A
C = fftshift(fftshift(A)); % C is not equal to A
Gotcha#3:
DFT具有许多有趣的特性,其中之一是真实偶数序列的DFT是真实偶数.我们经常可以将此事实用作简单的健全性检查.如果我们将一个真实的,偶数的序列放入fft
函数中,并获得不真实甚至偶数的东西,我们就会遇到问题.
The DFT has many interesting properties, one of which is that the DFT of a real, even sequence is real and even. We can often use this fact as a simple sanity check. If we put a real, even sequence into the fft
function and get back something back that is not real and even, we have a problem.
对于DFT,我们必须特别注意偶数函数的外观.序列3 2 1 0 1 2 3
看起来是偶数,对不对?左半部分是右半部分的镜像.如果序列的第四个元素表示t=0
,则此为true.但是,由于FFT算法的设置方式,第一个元素始终代表t=0
元素.
We must take careful note of what an even function looks like when it comes to the DFT. The sequence 3 2 1 0 1 2 3
appears to be even, right? The left half is a mirror image of the right half. This would be true if the fourth element of the sequence represented t=0
. However, because of the way the FFT algorithm is set up, the first element always represents the t=0
element.
我们可以通过在FFT之前执行ifftshift
操作以将中心移到第一个元素来解决该问题.请注意,对于长度相等的序列,假定元素x[N/2+1]
为中心.
We can remedy the problem by performing an ifftshift
operation before the FFT in order to shift the center to the first element. Note that for a sequence with even length, the element x[N/2+1]
is assumed to be the center.
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
如您在最后一个示例中看到的,说" 总是 使用 不正确 c4>在fft
之前."如果我的数据的第一个元素已经是t=0
元素怎么办?然后应用ifftshift
将会是错误要做的事情.
As you can see by the last example, it would be incorrect to say "always use ifftshift
before fft
." What if the first element of my data is already the t=0
element? Then applying ifftshift
would be the wrong thing to do.
通常,ifftshift
仅应在应用fft
/ifft
之前的 中使用. fft
和ifft
函数始终假定数据的第一个元素分别表示t=0
和f=0
.使用这些功能时,您应该问自己的主要问题是"t=0
(或f=0
)在我的数据中的什么位置?"和我希望他们住在哪里?"
In general, ifftshift
should only be used before applying an fft
/ifft
. The fft
and ifft
functions always assume that the first element of your data represents t=0
and f=0
respectively. The main question you should ask yourself when using these functions is "where does t=0
(or f=0
) live in my data?" and "Where do I want them to live?"
通常,只有在应用fft
/ifft
后的 后才能使用fftshift
.给出这些函数的输出,以便第一个元素分别表示f=0
和t=0
.如果要重新排列数据,使f=0
和t=0
元素出现在中间,则fftshift
是正确的答案.
In general, fftshift
should only be used after applying an fft
/ifft
. The output of these functions is given such that the first element represents f=0
and t=0
respectively. If you want to rearrange your data such that the f=0
and t=0
elements appear in the center, then fftshift
is the right answer.
如果没有更全面地了解要使用的数据代表什么,就无法说出是否需要任何ifftshift
或fftshift
函数.请注意,在许多情况下,人们可能会正确使用fft
/fft2
和ifft
/ifft2
而无需调用fftshift
或ifftshift
.
Without having a more thorough understanding of exactly what the data you are working with represents, it would be impossible to say whether any ifftshift
or fftshift
functions are necessary. Note that there are many situations in which one might use fft
/fft2
and ifft
/ifft2
correctly without ever needing to invoke fftshift
or ifftshift
.
这篇关于正确使用fft2和fftshift用于着色的形状的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!