我正在尝试使用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
据我所知,没有对称的价值观。为什么呢?
如果有人能给我一个提示,那就太好了。
问候
狼
答案 0 :(得分:1)
该链接具有误导性。纯实数信号的DFT(通常)不会导致输出样本的一半为零。它只是对它们施加(共轭)对称性。
因此,在您的过滤器代码中,您只需要操作一半的输出值。每次操作输出bin n 时,还需要操作bin Nn (其中 N 是DFT的长度),以便保持对称性,当您应用逆DFT时,它将为您提供真实的结果。
我的建议是首先解决一个更简单的问题 - 一维过滤器。一旦你有了正确的,那么它应该很容易扩展到3D。
答案 1 :(得分:0)
如果你想在逆FFT之后得到严格的实际结果(减去使用有限大小算术的常用数值噪声),你必须确保你输入完整IFFT的输入数据完全是共轭对称的(后半部分是向量是前半部分的镜像复共轭。您似乎没有强制您的数据那样。