获得比 DFT 更快的 2D 频率幅度的方法?

信息处理 图像处理 傅里叶变换
2022-02-08 15:27:49

我正在制作一个小程序,它可以获取图像的 DFT,以大致了解图像的整体方向。它通过在雷达扫描类型模式中旋转一条线来做到这一点,跟踪哪个角度具有最高的频率幅度总和。(它实际上只做虽然因为测试线在原点上是对称的)0180

无论如何,我想知道,有没有一种比 2D DFT 计算成本更低的方法来获得 2D 图像的频率幅度?

我知道它是可分离的,所以可以比天真的操作做得更好 - 我认为它变成我也知道 FFT 可以在而不是中进行一维 DFT 。最后,我知道它可以大规模并行化,因此可以在 CPU 或 GPU 上(大规模)多线程。O(N4)O(N3)O(NlogN)O(N2)

撇开这些不谈,有没有比进行完整的 2D DFT 获得 2D 图像的频率幅度的计算成本更低的方法?

1个回答

请注意,对于简单的2D DFT而不是O(N2logN)O(N4)

也就是说,既然你提到你想沿着类似雷达的模式的波束获取频谱信息,听起来你真的对计算每个这样的波束的 1D FFT 更感兴趣。在这种情况下,对于个光束,计算复杂度将是MO(MNlogN)

作为说明,让我们处理下图:

输入图像

我们将使用以下示例 matlab 代码从中提取一组M

% Number of beams to extract
M = 200;

% Convert the input image "img" to polar coordinates
c = size(img)/2+1;
N = max(size(img));
angles = 2*pi*[0:M-1]/M;
radius = [0:floor(N/2)-1];
imgpolar = zeros(length(radius), length(angles));
for ii=1:length(radius)
  xi = min(max(1, floor(c(2)+radius(ii)*cos(angles))), size(img,2));
  yi = min(max(1, floor(c(1)-radius(ii)*sin(angles))), size(img,1));
  imgpolar(ii,:) = img(sub2ind(size(img), yi, xi));
end
% Compute the FFT for each beam angle
ImgFD = fft(imgpolar,[],1);

figure(1);
freqs = [0:size(ImgFD,1)-1]/size(ImgFD,1);
surf(angles, freqs, 10*log10(abs(ImgFD)+1), 'EdgeColor', 'None');
view(2);
colormap("gray");
xlabel('Beam angle (radians)');
ylabel('Normalized frequency');

产生:

光束光谱

可以将其折叠为作为光束角度函数的振幅总和,以给出:

SumAmplitudes = sum(abs(ImgFD),1);
figure(2);
hold off; plot(angles, 10*log10(SumAmplitudes+1));
xlabel('beam angle (radians)');
ylabel('Sum of amplitudes (dB)');

作为光束角函数的振幅总和

作为旁注,如果您可以使用沿这些光束的幅度平方和(而不是幅度之和),那么由于Parseval 定理,您可以直接在空间域中执行此操作(这将使计算复杂度降低到O(MN),主要是转换为极坐标)。使用以下代码可以看到等价(对于幅度平方和):

% Compare the result of square amplitude summation in the frequency domain vs spatial domain
SumFD = sum(abs(ImgFD).^2,1)/size(ImgFD,1);
SumSD = sum(abs(imgpolar).^2,1);

figure(3);
hold off; plot(angles, 10*log10(SumFD+1), 'b');
hold on;  plot(angles, 10*log10(SumSD+1), 'r:');
xlabel('beam angle (radians)');
ylabel('Sum of squared amplitudes (dB)');
legend('Frequency domain', 'Spatial domain', "location", "southwest");

请注意在空间域和频域中计算的曲线的重叠:

作为波束角函数的振幅平方和

更新

如果您实际上正在计算 2D 频率图中类似雷达的波束,正如您在另一篇文章中所建议的那样,那么您最好回到执行 2D FFT,这将是有序的O(N2logN). 然后,您可以将频率系数之和转换为极坐标形式,这将增加一个小的O(N2),所以结果仍然以 2D FFT 为主。