0

FFTW ライブラリで 3D FFT を実行しようとしていますが、逆変換に問題があります。

最初に、次の方法で序文の変換を行います。

fftwf_plan_dft_3d(_dimensions[0], _dimensions[1], _dimensions[2], (fftwf_complex*)_inputBuffer, (fftwf_complex*)_outputBuffer, FFTW_FORWARD, FFTW_ESTIMATE);

私のデータは実際のデータですが、複雑から複雑への変換のみをサポートする opencl fft に後で置き換えたいため、複雑から複雑への変換を使用しています。

3D フーリエ空間では、非常に単純なローパス フィルターを実行します。

for all x, y, z:

// global position of the current bin
int gid = (y * w + x) + (z * w * h);

// position of the symmetric bin
vec3 conPos(M - x - 1, N - y - 1, L - z - 1);

// global position of the symmetric element
int conGid = (conPos.y * w + conPos.x) + (conPos.z * w * h);

if (sqrt(x * x + y * y + z * z) > 500)
{
    complex[gid].real = 0.0f;
    complex[gid].imag = 0.0f;
    complex[conGid].real = 0.0f;
    complex[conGid].imag = 0.0f;
}

最後に逆変換:

fftwf_plan_dft_3d(_dimensions[0], _dimensions[1], _dimensions[2], (fftwf_complex*)_inputBuffer, (fftwf_complex*)_outputBuffer, FFTW_BACKWARD, FFTW_ESTIMATE);
// normalization ...

結果は私が期待するものではありません。逆変換後、虚数部は想定どおりにすべてゼロではありません。

私が見る限り、実際のデータの順方向変換の後、合計バッファー サイズの半分のみが使用され、残りの半分には共役複素数値はありません。(参照: c2c with real data ) この場合、後方変換の前に自分でそれらを計算する必要がありますが、fftw ドキュメントで半分が計算され、どれが計算されないかのヒントを見つけることができませんでした。

この対称性をフーリエ空間で表示するために、非常に単純な 2D-Test-Case を作成しました。

int w = 4;
int h = 4;
int size  = w * h;

cl_float rawImage[16] = ...; // loading image

fftwf_complex *complexImage = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * size);
fftwf_complex *freqBuffer = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * size);

for (int i = 0; i < size; i++)
{
    complexImage[i][0] = rawImage[i]; complexImage[i][1] = 0.0f;
}

fftwf_plan forward = fftwf_plan_dft_2d(w, h, complexImage, freqBuffer, FFTW_FORWARD, FFTW_ESTIMATE);

fftwf_execute(forward);

for (int y = 0; y < h; y++)
{
    for (int x = 0; x < w; x++)
    {
        int gid = y * w + x;
        qDebug() << gid << "real:" << freqBuffer[gid][0] << "imag:" << freqBuffer[gid][1];
    }
}

これにより、次の出力が得られます。

gid
0    real 3060 imag 0 
1    real 510 imag 510 
2    real 0 imag 0 
3    real 510 imag -510 
4    real 510 imag 510 
5    real 0 imag -510 
6    real 0 imag 0 
7    real -510 imag 0 
8    real 0 imag 0 
9    real 0 imag 0 
10   real 0 imag 0 
11   real 0 imag 0 
12   real 510 imag -510 
13   real -510 imag 0 
14   real 0 imag 0 
15   real 0 imag 510 

私が見る限り、対称値はありません。なんで?

どなたかヒントを頂ければ幸いです。

ご挨拶

4

2 に答える 2

1

逆 FFT の後で厳密に実数の結果が必要な場合 (有限サイズの演算を使用することによる通常の数値ノイズを差し引いたもの)、完全な IFFT に供給する入力データが完全に共役対称であることを確認する必要があります (ベクトルの後半は前半の鏡像複素共役)。データをそのように強制したようには見えません。

于 2012-04-29T20:19:33.540 に答える
1

そのリンクは誤解を招くものです。実数のみの信号の DFT では、(一般に) 出力サンプルの半分がゼロになることはありません。それは単にそれらに(共役)対称性を課すだけです。

したがって、フィルター コードでは、本来あるべき出力値の半分しか操作していません。出力ビンnを操作するたびに、逆 DFT を適用したときに実数のみの結果が得られる対称性を維持するために、ビンNn ( Nは DFT の長さ) も操作する必要があります。

私のアドバイスは、最初にもっと単純な問題、つまり 1D フィルターに取り組むことです。それが正しければ、3D に簡単にスケールアップできるはずです。

于 2012-04-29T18:18:00.777 に答える