opencv矩阵转eigen_Armadillo,Eigen,OpenCV 矩阵操作比较(Compare Armadillo, Eigen and OpenCV)...

本文通过对比实验,探讨了OpenCV、Armadillo和Eigen在矩阵运算,尤其是SAD(Sum of Absolute Difference)计算上的性能差异。结果显示,Eigen和直接数组操作的效率相当,Armadillo稍慢,而OpenCV在特定操作上效率较低。
摘要由CSDN通过智能技术生成

有的时候写出来的程序慢也许并不是算法有问题,而是用的库比较慢;也可能并不是库本身慢,而只是你的写法不够高效。在经历了无数次令人蛋疼的等待后,我决定比较一下这几个所谓的高效的线性代数库(OpenCV虽然目标是计算机视觉,但也提供了比较丰富的代数计算能力),看看它们的性能到底怎么样。

有人已经做过类似的事情了,比如  OpenCV vs. Armadillo vs. Eigen on Linux revisited,这哥们比较了这几个库在各种矩阵运算方面的效率,总结的比较齐全。但是,在计算机视觉领域这些还不够,比如经常使用的相似性度量(Similarity

Measure)的计算。当然后很多种方法,这里就考虑最基本的SAD(Sum of Absolute Difference)方法吧,简单来说就是把两个矩阵(或者向量)相减,求个绝对值,再加起来。这个计算看起来挺简单的,不过比较的结果令我比较意外。

先把代码贴出来吧。

//  PerformanceTest.h

#pragma warning(disable:4344)

#define DEIGEN_NO_DEBUG

#define DNDEBUG

#include 

#include 

#include 

#include 

#include 

#include 

#include "Timer.h"

using namespace std;

//  PerformanceTest.cpp

#include "PerformanceTest.h"

int main(void)

{

Timer timer;        //  timer

double elapsedTime; //  time in millisecond

double res;         //  SAD value

int i;              //  loop variable

float bnd = 1e5;    //  loop times

//  Armadillo

arma::mat armaA(4, 1);

arma::mat armaB(4, 1);

timer.start();

for (i = 0; i 

{

res = arma::accu(arma::abs(armaA - armaB));

//res = 0;

//for (int idx = 0; idx 

//{

//  res += abs(armaA(idx, 0) - armaB(idx, 0));

//}

}

elapsedTime = timer.getElapsedTimeInMilliSec();

cout<

//  Eigen

Eigen::Vector4d eiA;

Eigen::Vector4d eiB;

Eigen::Vector4d eiC;

timer.start();

for (i = 0; i 

{

res = (eiA - eiB).cwiseAbs().sum();

//res = 0;

//for (int idx = 0; idx 

//{

//  res += abs(eiA(idx,0) - eiB(idx, 0));

//}

}

elapsedTime = timer.getElapsedTimeInMilliSec();

cout<

//  OpenCV

cv::Mat ocvA(4, 1, CV_64F);

cv::Mat ocvB(4, 1, CV_64F);

timer.start();

for (i = 0; i 

{

res = cv::sum(cv::abs(ocvA - ocvB))[0];

//res = 0;

//for (int idx = 0; idx 

//{

//  res += abs(ocvA.at(idx, 0) - ocvB.at(idx, 0));

//}

}

elapsedTime = timer.getElapsedTimeInMilliSec();

cout<

//  pointer operation

double *a = (double*)_mm_malloc(4 * sizeof(double), 16);

double *b = (double*)_mm_malloc(4 * sizeof(double), 16);

int len = ocvA.rows;

timer.start();

for (i = 0; i 

{

res = 0;

for (int idx = 0; idx 

{

res += abs(a[idx] - b[idx]);

}

//cout<

}

elapsedTime = timer.getElapsedTimeInMilliSec();

cout<

//  release resource

_mm_free(a);

_mm_free(b);

return 0;

}

其中的计时函数用到的是 Franz Kafka 提供的跨平台高精度计时类,可以从以下地址下载 High Resolution Timer。

用以上代码在 release 下得到的结果如下:

arma time : 0.87827 ms

eigen time : 0.13641 ms

opencv time : 179.599 ms

array operation : 0.135591 ms

可以看出 Eigen 的时间和直接用数组运算的时间是相当的,Armadillo 的时间慢了 6~7 倍左右,而 OpenCV 已经目不忍视了,不知道 OpenCV 是怎么想的,差距有点悬殊。

下面又做了另外一组对比,把循环中的求 SAD 部分用类似于数组的方式自己计算,结果如下

arma time : 0.145423 ms

eigen time : 0.134772 ms

opencv time : 0.134362 ms

array operation : 0.139278 ms

这下计算时间基本上是相当的了。

通过这些对比得到两个结论:

1、虽然这些库在矩阵相乘等操作上可能比较高效,但是对于某些低级操作可能效率并不高

2、通过模板访问数据并不比数组效率低,性能基本相当

实验环境:

Windows 7 Ultimate SP1

Visual C++ 2008

Armadillo 3.4.4

Eigen 3.1.2

OpenCV 2.3.1

Compiled to 32-bit binary

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值