web-dev-qa-db-ja.com

位相と大きさからフーリエ変換を取得-MATLAB-MathWorks日本

フーリエ変換Fの振幅と位相は、次のように定義されます。

Mag = sqrt(Real(F)^2 + Imaginary(F)^2)

そして

Phase = arctan(Imaginary(F)/Real(F))

私は、グレースケールイメージマトリックスを取り込み、マトリックスでfft2()を実行し、変換からマグニチュードと位相を計算するMATLABコードを記述しようとしました。次に、フーリエ変換の虚数部と実数部を計算します。これは、最初の2つの方程式を次のように整理することによって行われます。

Real = Mag/sqrt(1 + tan(Phase)^2)

そして

Imaginary = Real*tan(Phase)

そして最後にfft2を組み合わせて逆にします:

F = Real + i*Imaginary
image = ifft2(F)

入力と同じ画像が表示されることを期待していますが、ゴミが表示されます。私の数学は間違っていますか?私のmatlab mfileコードは次のとおりです。

function y = forwardBackwardFFT(image)

F = fft2(image);
mag = sqrt(real(F).^2 + imag(F).^2);
phase = atan(imag(F)./real(F));

re = sqrt((mag.^2)./(1 + tan(phase).^2));
im = re.*tan(phase);
F = re + i*im;
f = ifft2(F);

subplot(1,2,1);
imshow(image);
Title('Original Image');

subplot(1,2,2);
imshow(f);
Title('Image after forward and backward FFT');
y = f;

どうもありがとう :)

19
Dave Anderson

関数は2つのことを一度にテストしようとしています:(1)画像のFFTと逆FFT、および(2)複素数を実数部と虚数部に分解し、振幅と位相に変換してから、それらを再び組み合わせます。一度に全部を試してみてそれがうまくいかないのではないかと思うのではなく、これら2つの関数をそれぞれ個別にテストする必要があります。

ifft(fft(image))が元の画像を返すかどうかをテストするには、すべての複素数操作を削除するかコメント化します。

_function y = forwardBackwardFFT(image)

F = fft2(image);
%# stuff removed
f = ifft2(F);

subplot(1,2,1);
imshow(image);
title('Original Image');

subplot(1,2,2);
imshow(f, []);
title('Image after forward and backward FFT');
y = f;
_

これは機能するです。したがって、問題はあなたの複雑な数値操作にあります。 phase = 0またはphase = pi/2の場合に何が起こるかを考えます。 0の正接は0であり、ゼロによる除算になります。 tan(pi/2)は無限大です。

機能するコードをいくつか示します。

_mag =  sqrt(real(F).^2 + imag(F).^2);
phase = atan2(imag(F),real(F));

re = mag .* cos(phase);
im = mag .* sin(phase);
F = re + 1i*im;
_

(ほぼゼロの)虚数成分を取り除くために、結果の逆変換された画像を表示するためにimagesc(abs(f))を実行する必要があります。

複素数の大きさと位相を取得するより慣用的な方法は、単に次のようにすることです:

_mag = abs(F);
phase = angle(F);
_

お役に立てれば。

19
nibot