MATLAB中的fft2与OpenCV C++中的dft速度比较

3

我想知道为什么OpenCVC++中的dft函数在处理二维矩阵时比fft2慢很多。

下面的C++代码来自文档

void fft2(const Mat in, Mat &complexI) {
    Mat padded;
    int m = getOptimalDFTSize(in.rows);
    int n = getOptimalDFTSize(in.cols); 
    copyMakeBorder(in, padded, 0, m - in.rows, 0, n - in.cols, BORDER_CONSTANT, Scalar::all(0));

    Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
    merge(planes, 2, complexI);
    dft(complexI, complexI);
}

int main(){
    Mat a(5000, 5000, CV_32F);
    randn(a, 0, 1);
    Mat res;
    clock_t start = clock();
    fft2(a,res);
    cout << clock() - start;
}

MATLAB 代码:

mat1 = rand(5000,5000);
tic, a = fft2(mat1); toc

两种代码的结果相同;然而,C++代码需要1502毫秒,而MATLAB代码只需要660毫秒。看来在OpenCV中缺少一些优化。我想知道如何加速OpenCV代码。
我正在使用Visual Studio 2015和OpenCV 2.4.10以及MATLAB R2016a进行工作。计算机是Windows 7,32 GB RAM,Intel Xeon 3.4 GHz。两个测试都在同一台机器上进行。
我找到了一堆FFT代码,但它们似乎很难应用于矩阵。有没有适用于矩阵的简单解决方案?

fft2 是一种类似于矩阵操作的函数,已经预编译过了(因此 open fft2 不会显示任何有用的代码),因此非常快。至于为什么它比 C++ 代码更快,我不知道。你可能想阅读 为什么 MATLAB 在矩阵乘法中如此快? - Adriaan
你可以询问为什么FFTPACK及FORTRAN是快速的,而且你也可以在C中调用FFTPACK。 - percusse
1
@Adriaan 这个链接有一些很好的解释。我会检查 timeit。 - smttsp
那还有fftw。如果可用,Matlab总是使用成熟的Fortran库而不是内部编码。 - percusse
Matlab使用FFTW进行优化,结合Intel MKL库使其运行速度非常快。 - Ahmed Fasih
显示剩余2条评论
1个回答

1

OpenCV的FFT实现可能没有Matlab的优化。
如果您需要FFT性能,则可以查看专用FFT库,例如FFTW


我能否只获取FFTW上对应的.c和.h文件?或者您认为我应该完全安装它。看起来这样做相当复杂,不是吗?另外,如果我安装了它,需要转移到另一个操作系统时更改会容易吗? - smttsp
@smttsp 我会按照安装说明进行操作。FFTW 算法有点像黑魔法,它会在运行时选择最优的代码路径,以适应你的 CPU 和 RAM,并找到你所请求的 FFT 大小的最快子程序。在我看来,这值得花费一点前期设置时间! - Ahmed Fasih

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接