正确使用fft2和fftshift用于着色的形状 [英] Correct usage of fft2 and fftshift for shape from shading

查看:353
本文介绍了正确使用fft2和fftshift用于着色的形状的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图从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.

I am attempting to recreate a classical shape from shading algorithm seen in the Trucco/Verri text "Introductory Techniques for 3d Computer Vision", but I am having a hard time understanding the fft function in matlab. Essentially, I need to use the integrability constraint to get the depth (Z) of an image. I am not sure when to use fftshift or not in this scenario. Here is the code I have so far. Based on http://www.mathworks.com/matlabcentral/newsreader/view_thread/285244 I basically wrapped all my fft2s in fftshifts, but I don't think this is the correct usage. Could someone please explain to me the usage and what I am doing wrong? Thank you. Basically, I'm trying to take my p and q (values which are the updates based on pixel intensities) transform them into the Fourier domain so as to use them in the equation C. Then I want to transform the Equation C back to the time domain because that will give me Z the depth. I also want to update P and Q based on C in the Fourier Domain.

    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,您总是可以跳到摘要部分,看看是否有帮助.

This is a tricky question because in general there is not a right answer. There may be some wrong answers though. I will try to explain. If the answer get a little bit too wordy, you can always just skip down to the summary section and see if it helps.

Gotcha#1:

当您使用Matlab的fft(在您的情况下为fft2)功能时,输出的第一个元素(在您的情况下为X(1,1))代表

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

注意:ifftshift将撤消fftshift的结果.如果矩阵X包含奇数个元素,则必须执行ifftshift(fftshift(X))才能获得原始的X.简单地执行两次fftshift(X)不会产生X.

Note: ifftshift will undo the results of fftshift. If the matrix X contains an odd number of elements, ifftshift(fftshift(X)) must be done to obtain the original X. Simply performing fftshift(X) twice will not produce X.

例如:

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之前的 中使用. fftifft函数始终假定数据的第一个元素分别表示t=0f=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=0t=0.如果要重新排列数据,使f=0t=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.

如果没有更全面地了解要使用的数据代表什么,就无法说出是否需要任何ifftshiftfftshift函数.请注意,在许多情况下,人们可能会正确使用fft/fft2ifft/ifft2而无需调用fftshiftifftshift.

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用于着色的形状的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆