I am trying to do a 3D FFT with the FFTW library, but I have some difficulties with the inverse transformation.
At first I do the foreword transformation via:
fftwf_plan_dft_3d(_dimensions[0], _dimensions[1], _dimensions[2], (fftwf_complex*)_inputBuffer, (fftwf_complex*)_outputBuffer, FFTW_FORWARD, FFTW_ESTIMATE);
Although my data is real data I am using the complex to complex transformation, as want to replace it later by an opencl fft which only supports complex to complex transformations.
In 3D fourier space I do a very simple low pass filter:
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;
}
At last the inverse transformation:
fftwf_plan_dft_3d(_dimensions[0], _dimensions[1], _dimensions[2], (fftwf_complex*)_inputBuffer, (fftwf_complex*)_outputBuffer, FFTW_BACKWARD, FFTW_ESTIMATE);
// normalization ...
The Result is not as I would expect it. After the inverse transformation the imaginary parts are not all zero as they are supposed to be.
As far as I see it, after the forward transformation of real data only the half of the total buffer size is used and there are no conjugate complex values in the other half. (see: c2c with real data) If this is the case I have to compute them on my own before the backward transformation, but I could not found a hint in the fftw docs which half is computed and which is not.
I have written a very simple 2D-Test-Case to view this symmetry in the fourier space:
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];
}
}
This gives me the following output:
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
As far as I see it there are no symmetric values. Why?
It would be nice if someone could give me a hint.
Greetings
Wolf