我是一个完整的信号处理新手,我提前道歉,问一个无能为力的问题。
是否可以重用现有的1D FFT算法来计算2D逆FFT算法?
答案 0 :(得分:3)
是强> 的。实际上,2D FFT是列式逐行FFT,然后是行式(反之亦然)。这正是我所做的in the past
从线性代数意义上讲;将1D DFT视为unitary linear transform F. 方阵X的2D FFT简单
F*X*F'
如果您没有1D IFFT,请从FFT中创建一个:IFFT(x) == conj( FFT( conj( x ) )
。这是从unitarity:
注意:对于来自1D FFT的2D IFFT的组合,有4个级别的共轭。中间两个相互撤消,可以跳过。
如果fft为unitary,则应保留norms。 Many libraries和tools忽略了这一点,并在前向变换上产生了一个sqrt(N)比例因子,它们在逆变换时会撤消。
答案 1 :(得分:0)
看一下我写的java中的这个解决方案.. FFT很棘手,但是为了理解目的我尽可能简单地写了这个。我不会发布复杂的类,但它非常标准 - 只需要一个实数组件的双精度和虚数的双精度 - 并且对复数有很多数学运算。
对于direction参数,传递-1表示正向,1表示反向。这就是所有反向关系归结为此实现。当然,您知道反转2D - 您只需对行进行1D逆,然后对列进行应用。 (反之亦然)。
//performs the FFT on a single dimension in the desired direction through recursion
private static Complex[] RecursiveFFT(Complex[] input, double direction)
{
int length = input.length;
int half_length = input.length / 2;
Complex[] result = new Complex[length];
if(length==1)
{
result[0] = input[0];
}
else
{
Complex[] sum = new Complex[half_length];
Complex[] diff = new Complex[half_length];
Complex temp = new Complex(0.0, direction*(2*Math.PI)/length).GetExponential();
Complex c1 = new Complex(1,0);
Complex c2 = new Complex(2,0);
for(int index=0;index<half_length;index++)
{
sum[index] = input[index].Add(input[index+half_length]).Divide(c2);
diff[index] = input[index].Subtract(input[index+half_length]).Multiply(c1).Divide(c2);
c1 = c1.Multiply(temp);
}
Complex[] even = RecursiveFFT(sum,direction);
Complex[] odd = RecursiveFFT(diff,direction);
for(int index=0;index<half_length;index++)
{
result[index*2] = even[index];
result[index*2 + 1] = odd[index];
}
}
return result;
}
答案 2 :(得分:0)
是。二维矩阵的变换只是所有行的各个变换的组合,并且在所有行被变换之后,所有列的各个变换。
然而,FFT中存在许多性能问题。特别是,转换数组的列可能会遇到缓存抖动问题。执行单个转换的效率低于在支持它的机器上使用SIMD并行性。因此,编写一个具有性能细节的二维实现通常比编写一维FFT中的二维FFT更好。