【发布时间】:2017-02-24 22:57:54
【问题描述】:
对于我的工作,我需要对大图像执行离散傅立叶变换 (DFT)。在当前示例中,我需要 1921 x 512 x 512 图像的 3D FT(以及 512 x 512 图像的 2D FFT)。现在,我正在使用 numpy 包和相关的函数np.fft.fftn()。下面的代码 sn-p 以以下方式示例性地显示了相同大小/稍小的 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 都准瞬间完成。
但是对于 1921x512x512,np.fft.fftn() 需要大约 5 分钟。由于我猜 scipy 的实现速度并没有快多少,并且考虑到在 MATLAB FFT 上相同大小的网格在大约 5 秒内完成,我的问题是是否有一种方法可以将这个过程加速到或几乎达到 MATLAB 时间。我对 FFT 的了解有限,但显然 MATLAB 使用了 FFTW 算法,而 python 没有。使用一些 pyFFTW 包我得到类似时间的任何合理机会?此外,1921 似乎是一个不幸的选择,只有 2 个质因数(17、113),所以我认为这也起作用。另一方面,512 是非常适合的 2 的幂。如果可能的话,是否也可以在不填充零到 2048 的情况下实现类似 MATLAB 的时间?
我问是因为我将不得不大量使用 FFT(在一定程度上这种差异会产生巨大影响!),如果没有可能减少 python 中的计算时间,我必须切换到其他更快的实现。
【问题讨论】:
-
如果 pyfftw 失败,请尝试与 R 或 octave 的 fft 实现进行比较。如果其中任何一个工作得更快,您可以从 python 调用这些实现(不知道惩罚有多大)
标签: python performance numpy fft