带fftw库的3d c2c fft

带fftw库的3d c2c fft,3d,fft,fftw,3d,Fft,Fftw,我正在尝试使用FFTW库进行3D FFT,但在进行逆变换时遇到了一些困难 首先,我通过以下方式进行前言转换: fftwf_plan_dft_3d(_dimensions[0], _dimensions[1], _dimensions[2], (fftwf_complex*)_inputBuffer, (fftwf_complex*)_outputBuffer, FFTW_FORWARD, FFTW_ESTIMATE); 虽然我的数据是真实数据,但我正在使用复杂到复杂的转换,正如我所希望的那样

我正在尝试使用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 ...
结果并不像我预期的那样。经过逆变换后,虚部并非都是零

在我看来,在对真实数据进行前向转换之后,只使用了总缓冲区大小的一半,而在另一半中没有共轭复数值。(请参阅:)如果是这种情况,我必须在反向转换之前自己计算它们,但我在fftw文档中找不到提示,其中一半是计算的,而另一半不是

我已经编写了一个非常简单的2D测试用例来查看傅里叶空间中的对称性:

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];
    }
}
在我看来,没有对称值。为什么?

如果有人能给我一个提示就好了

问候


沃尔夫

这种联系具有误导性。仅实信号的DFT(通常)不会导致一半输出样本为零。它只是对它们施加(共轭)对称性

因此,在您的过滤器代码中,您只处理了应该处理的输出值的一半。每次操纵输出bin n时,还需要操纵bin n-n(其中n是DFT的长度),以保持对称性,从而在应用逆DFT时,只得到真实结果


我的建议是先解决一个简单得多的问题——1D过滤器。一旦你做到了这一点,那么它应该很容易扩展到3D。

如果你想在逆FFT后得到一个严格的真实结果(减去使用有限大小算法产生的通常数值噪声),你必须确保你输入的完整IFFT的输入数据是完全共轭对称的(向量的后半部分是前半部分的镜像复共轭)。似乎你没有强迫你的数据是那样的。

这听起来很合理。这是否意味着在1D FFT的情况下,我只需要从n=0到n/2,因为在每一步中,我过滤复[n]和复[n-n]?@Derhanderk:我不知道你在问什么。一个长度为N的1D DFT只有N/2+1个独立的输出样本;关系是y[N]=y[N-N]*(其中“*”表示)。好的,就我所见,对于1D FFT,我的低通必须做以下工作:
如果振幅>值,那么y[N]=0;y[N-N-1]=0;end
对于n=0到n-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