Answers:
我假设这是在常规CPU上完成的,一个内核,执行一个简单的线程,没有花哨的硬件。如果还不止这些,可以通过调整更简单系统的推理来解决。如果没有专门讨论的系统,或者没有涵盖各种可能性的完整教科书或研究论文,那么要说的更多。
我不会担心2的幂次方。没关系 具有蝶形单位的FFT算法以及所有存在的因数均为3或不只是2的小数。对于素数数据序列,也有一些聪明的算法。由于其无常的性质,我不喜欢引用Wikipedia,但是无论如何:
对于所有N(即使是素数N),都具有O(N log N)复杂度的FFT
可以在GPL库FFTW中找到针对任意N的FFT实现。
就认真的工程而言,唯一可信赖的方法是构建和测量,但是我们当然可以从理论中得到一个想法,以了解变量之间的关系。我们需要估算每种方法涉及多少算术运算。
即使多年来差异已大大缩小,但在大多数CPU上,乘法运算仍然比加法运算慢。因此,我们只计算乘法。对加法进行会计处理还需要更多的思考和跟踪工作。
一个简单的卷积,实际上是使用卷积核进行乘法和加法,对每个输出像素重复,需要进行W²·K²乘法,其中W是图像一侧的像素数(为简单起见,假设为正方形),K为大小卷积核的大小,如沿一侧的像素。使用内核和输入图像的相同大小部分,需要K²乘法来计算一个输出像素。对所有输出像素重复此操作,其编号与输入图像中的编号相同。
(N mults)直接 =W²·K²
为了在傅立叶空间中完成这项工作,我们必须对傅立叶进行变换。这是通过将FFT分别应用于每一列,然后应用于每一行来完成的。N个数据点的FFT大约需要2N·log(N)乘;我们希望N为W,即一列或一行的长度。这里的所有对数均以二为底。
有W行和W列,因此在完成所有FFT之后,我们完成了2W·(2W·log(W))乘法。将其加倍,因为在乘以内核的傅立叶变换之后,我们必须对数据进行傅立叶逆变换以返回到敏感图像。那是8W²·log(W)。当然,必须乘以内核的傅立叶变换,再进行W²乘法。(完成一次,每行输出像素,每行或任何其他内容一次。)这些是复数乘法,因此是4W²实数乘法。
所以,除非我搞砸了(也许我做了),否则我们有
(N mults)傅立叶 =4W²·(2·日志(W)+ 1)
我们什么时候想直接做事?当K足够小时,使W²·K²小于4W²·(2·log(W)+1)。W²的公因数很容易排除。由于我们正在处理理想化的估算值,因此我们可以删除“ +1”。+1可能会由于不计算增加数,循环开销等而在与实际实现有关的错误中丢失。留下:
K² < 8·log(W)
这是在频率空间方法上选择直接方法的近似条件。
请注意,两个相同大小图像的相关性就像与大小为K = W的内核进行卷积一样。傅立叶空间始终是这样做的方法。
可以对此进行完善和讨论,以解决开销,操作码流水线,浮点数与定点数之间的问题,并通过GPGPU和专用硬件将其扔掉。