Matlab在C++中是否仍比opencv慢?

4
根据这个链接和这个链接,称opencv比matlab快得多。第一个链接是在2012年3月写的,第二个链接比那晚一点。

第一个链接中说,“用OpenCV编写的程序比用Matlab编写的类似程序运行速度要快得多。” 并给出了评分:Matlab: 2/10OpenCV: 9/10

考虑以下情况:我有两个大小为1024 * 1024浮点矩阵mat1mat2)。 我想将这些矩阵相关联。

在Matlab中,

corr2(mat1,mat2);     //70-75 ms

在OpenCV中,使用C++语言。
Mat result(1,1,CV_32F);
matchTemplate(mat1,mat2,result, CV_TM_CCOEFF_NORMED);      // 145-150 ms

据我所知,C和C++的速度大致相同。
因此,我想知道为什么在执行交叉相关时,Matlab比Opencv/C++更快。是因为我比较错了(尽管结果相同),还是Matlab的交叉相关实现比Opencv实现快一倍?
请注意,我使用的是Matlab 2013a和Visual Studio 2010。
谢谢。

OpenCV使用了多个优化库来加速计算,所以问题是:你的OpenCV二进制文件是否编译为使用它们?否则,Matlab可能会占据上风。 - karlphillip
还有一件重要的事情。MATLAB中的所有值都是浮点数,而OpenCV具有uchar、short、int、float和double等类型。这就是为什么OpenCV更快的原因,因为大多数函数都是在8位数据上执行的。 - Froyo
5个回答

2

当我阅读这篇文章时,我无法对C++进行适当的比较,因为它只是使用不同的软件包指示加速,并且我不知道C++的“执行时间”或“兆浮点数”。此外,这篇文章发表于2000年,所以我们不知道这些软件包是否最近有改进。 - smttsp
我认为你的代码速度取决于编译器和库/语言的选择。我的一些从事科学编程的朋友说,他们只需使用Intel编译器而不是Visual Studio中的标准编译器就可以获得更快的速度。关于Matlab(LAPACK或任何矩阵库)与OpenCV之间的比较,我认为多年来用于执行BLAS的库的速度并没有太大变化,但是在涉及比CORR更高级的操作时,OpenCV可能会更快。 - Niels
那么,第一个网站中的速度比较是错误的吗?至少不是 2/109/10,对吧? - smttsp
我不会给2/10和9/10的评分 :) 例如,在C++中,当你通过引用传递和通过值传递时非常清楚,而在Matlab中则不太清楚。我已经有一段时间没有在Matlab中进行任何真正的编程了,但是Mathworks可能已经改进了这一点,因为我上次使用它以来。所以,对于您链接中使用的特定代码和问题,C++可能更快。无论如何,Matlab的速度很大程度上取决于您编写代码的方式,请尝试Blaz Bratanic提供的代码示例。 - Niels
刚刚再次阅读了您的链接:“在OpenCV中,我们将获得至少30fps,从而实现实时检测”。如果他们正在从实时视频源进行实时处理并传递大量数据,则我认为他们很可能从openCV(C ++)获得更高的速度,因为他们的代码不仅取决于他们可以执行基本矩阵计算的速度。 - Niels

2

Matlab内置函数使用了mkl库,而OpenCV没有。因此,如果两个完全相同的函数在两个软件中都存在,那么Matlab比OpenCV更快(快很多)。我曾经尝试在一个大矩阵上做伪逆运算,Matlab至少比其他软件(如openblas、Armadillo和自己集成的mkl)快2倍。之后我就放弃了解为什么,直接把数据加载到Matlab中让它处理。OpenCV是迄今为止最慢的。在OpenCV中尝试对一个10000x10000的矩阵进行矩阵乘法,我的笔记本电脑上需要10分钟。而在Matlab中只需要1分钟。


除了购买“MKL”之外,是否有任何提高opencv速度的方法?如果我找到/获得MKL,我的opencv代码会像Matlab一样快吗? - smttsp
我不相信OpenCV直接支持MKL。但是,您可以使用数学库,例如Armadillo,该库可以使用MKL。然后您可以在那里尝试进行计算。OpenBLAS是MKL的替代品。根据您的问题,您可能能够获得与Matlab相当的速度。您需要尝试在您的数据上运行并进行基准测试。 - Zaw Lin
这里有更多的信息http://nghiaho.com/?p=1726,这样你就可以对性能的相对差异有一些大致的了解。但是这些基准测试非常依赖于具体问题,所以你真的需要自己尝试一下。 - Zaw Lin
有没有办法在Matlab中禁用mkl?这样,我就可以测试mkl的改进效果。感谢提供链接,它给了一些有关速度的想法。 - smttsp
我认为这是不可能的,因为它是执行计算的基本工具。你可以尝试使用ipp编译opencv,如果opencv实现了matchTemplate函数的ipp变体,那么你可能会获得类似的性能。 - Zaw Lin
@smttsp 你好,你找到在Matlab中禁用mkl的方法了吗? - olivia

1
在您的情况下,没有理由期待Matlab会变慢。您正在调用一个单独的函数,语言解释器和将数据传递给本地函数(mex函数)引起的开销只需支付一次。
如果您对小型32 * 32矩阵调用相同的函数1024次,您可能会注意到开销(除非JIT编译器找到了优化代码的巧妙方法)。

我在想,最坏的情况下,它们的速度应该是相同的,但Matlab的速度是OpenCV速度的两倍。你认为在这种情况下OpenCV为什么会如此缓慢(或者Matlab为什么如此快)? - smttsp

0

如果您将所有操作向量化并使用本地函数,Matlab可以快速运行。 但是,如果您在循环中执行某些操作,例如:

A = zeros(100,100);
for m = 1:100
    for n = 1:100
        A(m, n) = 1/(m + n - 1);
    end
end

对比。

Mat A(100, 100, CV_64F);
for (int r = 0; r < A.rows; r++)
  for (int c = 0; c < A.cols; c++) 
    A.at<double>(r, c) = 1 / (r + c - 1);

你会注意到差异。


循环在MATLAB中由于即时编译变得更快。事实上,对于这样一个基本操作,循环甚至可以比向量化的MATLAB代码更快。自己试试吧:http://pastebin.com/Ugca2aDx - Amro
顺便说一下,如果您更改迭代的顺序(首先循环n,然后是m),速度会更快。原因是MATLAB数组以列主序存储,因此您将以这种方式线性访问元素(考虑空间局部性)。 - Amro

0

对于相关函数(以及许多其他函数),Matlab使用先进的库和指令集。

然而,Matlab比你想象的更聪明。它会在运行时检查操作是否在空间域或频率域上执行得更快,然后选择最快的解决方案。

我找不到关于corr2的提及,但我找到了normxcorr2

根据图像大小,在空间域或频率域中计算交叉相关。


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