为了我的工作,我需要对大型图像执行离散傅里叶变换(DFT)。在当前示例中,我需要对一个1921 x 512 x 512的图像执行3D FT(以及512 x 512图像的2D FFT)。目前,我正在使用numpy包和相关函数np.fft.fftn()。下面的代码片段示例性地展示了在等大小/略小的2D/3D随机数生成网格上进行2D和3D FFT的时间:
import sys
import numpy as np
import time
tas = time.time()
a = np.random.rand(512, 512)
tab = time.time()
b = np.random.rand(100, 512, 512)
tbfa = time.time()
fa = np.fft.fft2(a)
tfafb = time.time()
fb = np.fft.fftn(b)
tfbe = time.time()
print "initializing 512 x 512 grid:", tab - tas
print "initializing 100 x 512 x 512 grid:", tbfa - tab
print "2D FFT on 512 x 512 grid:", tfafb - tbfa
print "3D FFT on 100 x 512 x 512 grid:", tfbe - tfafb
输出:
initializing 512 x 512 grid: 0.00305700302124
initializing 100 x 512 x 512 grid: 0.301637887955
2D FFT on 512 x 512 grid: 0.0122730731964
3D FFT on 100 x 512 x 512 grid: 3.88418793678
我遇到的问题是需要经常进行这个过程,因此每张图片的处理时间应该很短。在我的电脑上测试(中端笔记本电脑,为虚拟机分配了2GB RAM (--> 因此测试网格较小)),如您所见,3D FFT需要约5秒钟(数量级)。现在,在工作中,机器要好得多,是集群/网格架构系统,FFT速度更快。在两种情况下,2D FFT都可以几乎瞬间完成。
然而,使用1921x512x512,np.fft.fftn()需要大约5分钟。考虑到我猜测scipy的实现速度不会快多少,并且在MATLAB中同样大小的网格的FFT完成时间约为5秒,我的问题是是否有一种方法可以将此过程加速到或几乎达到MATLAB的速度。我的FFT知识有限,但显然MATLAB使用FFTW算法,而Python没有。通过一些pyFFTW包,是否有合理的机会获得类似的速度?另外,1921似乎是个不幸的选择,只有2个质因数(17、113),所以我认为这也起了一定作用。另一方面,512是一个适合的二次幂。如果不用用0填充到2048,是否可以实现类似于MATLAB的时间?我之所以问,是因为我将不得不经常使用FFT(在这种情况下,这些差异将对结果产生巨大影响!),如果在Python中无法减少计算时间,我将不得不转向其他更快的实现。