2D R2C FFT 作为 1D FFT 使用 FFTW

Posted

技术标签:

【中文标题】2D R2C FFT 作为 1D FFT 使用 FFTW【英文标题】:2D R2C FFT as 1D FFT using FFTW 【发布时间】:2015-02-03 09:34:03 【问题描述】:

由于各种原因,我需要对实际数据输入进行 2D FFT 变换(前向和逆向)作为 1D 变换。我使用优秀的 FFTW 库。

算法应该很简单,首先我对每一行进行一维 R2C 转换,然后对每个结果列进行转换。为此,我使用了 FFTW 的高级接口:

int N = ...; int M = ...; int M2 = M / 2 + 1;
r_array = ... // fftw_malloc'd as NxM array of doubles
c_array = ... // fftw_malloc'd as NxM2 array of fftw_complex

int rank = 1;
int nfr[] = M; int nfr2[] = M2;    
int howmany = N;
int idist = M; int odist = M2;
int istride = 1; int ostride = 1;
int *inembed = nfr, *onembed = nfr2;

plan_forward_row = fftw_plan_many_dft_r2c(rank, nfr, howmany, r_array, inembed, istride, idist,  c_array, onembed, ostride, odist, FFTW_ESTIMATE);
fftw_execute(plan_forward_row);

//do something else...

int nfc[] = N;
howmany = M2;
idist = 1; odist = 1;
istride = N, ostride = N;
inembed = nfc, onembed = nfc;

plan_forward_col = fftw_plan_many_dft(rank, nfc, howmany, c_array, inembed, istride, idist,  c_array, onembed, ostride, odist, FFTW_FORWARD, FFTW_ESTIMATE);
fftw_execute(plan_forward_col);

//do something else...

//now inverse (backward)...
int nbc[] = N;
howmany = M2;
idist = 1; odist = 1;
istride = N; ostride = N;
inembed = nbc; onembed = nbc;

plan_backward_col = fftw_plan_many_dft(rank, nbc, howmany, c_array, inembed, istride, idist,  c_array, onembed, ostride, odist, FFTW_BACKWARD, FFTW_ESTIMATE);
fftw_execute(plan_backward_col);

//do something else...

int nbr[] = M2; int nbr2[] = M;    
howmany = Nx;
idist = M2; odist = M;
istride = 1, ostride = 1;
inembed = nbr, onembed = nbr2;

plan_backward_row = fftw_plan_many_dft_c2r(rank, nbr, howmany, c_array, inembed, istride, idist,  r_array, onembed, ostride, odist, FFTW_ESTIMATE);
fftw_execute(plan_backward_row);

但是,结果不正确。问题出在 R2C 输出只是复数的非冗余数组,还是我使用高级接口时出错了?

【问题讨论】:

我发现了错误,在最后一次转换中,nbr 的值应该只是M,而不是M2。另外,nembed 的所有参数都可以是NULL,本例中不必使用。 我印象深刻:您的标题实际上是 75% 的首字母缩略词。 【参考方案1】:

基本的 FFT 算法是复杂的->复杂的。通过这部分,您可以将 2d FFT 划分为两个 1d FFT 的序列。

通常的 FFT 接口做了很多优化:

    将实际输入打包到一个复杂的数组中 做复数->复数 FFT 删除多余部分

这是第 (2) 部分,您需要先调用行,然后再调用列。

【讨论】:

那会更慢,并且违背了 R2C 转换的全部目的。【参考方案2】:

为什么不直接调用2D版本的FFTW呢?

中的函数fftw_plan_dft_r2c_2d()

http://www.fftw.org/fftw3_doc/Multi_002dDimensional-DFTs-of-Real-Data.html#Multi_002dDimensional-DFTs-of-Real-Data

【讨论】:

2d 按我需要的方式工作,但是,就像我说的,我需要 2x1d。反正我早就解决了,问题是高级界面的参数之一,不记得这个例子是哪个了。

以上是关于2D R2C FFT 作为 1D FFT 使用 FFTW的主要内容,如果未能解决你的问题,请参考以下文章

传递对 fft 函数的引用时,输出数组的大小应该是多少?图像处理

犰狳复矩阵上第 2 个暗淡的 1D fft

使用 Apple Accelerate 框架选择实数和复数 2D FFT

C/C++ 中固定长度实际输入数据的高效 2D FFT

绘制图像的 2D FFT

怎样用C语言实现FFT算法啊?