您的位置:首页 > 编程语言 > MATLAB

【学习OpenCV】与matlab风格一致的函数

2015-01-12 15:12 429 查看
matlab被广泛用于算法的仿真,往往是整个项目的最上层设计时使用到的工具;而具体的高效的代码实现则要借助C\C++,而opencv提供了很多这方面的接口函数,里面有一部分是与matlab相对应的,这一点更进一步方便了算法的代码实现过程。当然,首先不考虑代码的效率,因为本来opencv就不见得具有多高的效率,更何况是再进一步封装成matlab风格的接口呢?但对于项目开发还是有一定的便利性的。

1、用得最多的莫过于——imread、imshow

区别在于数据结构:matlab中是N维数组,CV中是Mat类

2、矩阵运算

这里有大量的矩阵运算、矩阵变换函数,因为matlab名字就是矩阵实验室,在矩阵运算的效率上非常可观。其本质也是C++,估计CV会用到相似的算法,正如乔布斯说的:好的艺术家抄袭,伟大的艺术家剽窃。

如,两矩阵点乘、减法;矩阵乘方;等等。参考:/article/9487320.html

3、矩阵赋值

matlab中又一使用率很高的操作——zeros、ones、eye,CV中Mat下有对应方法

另外,matlab中a=[1,2,3;4,5,6],CV中则麻烦一点 Mat a = (Mat_<double>(2,3) << 1, 4, 2, 5, 3, 6);

4、矩阵元素寻访

matlab中B(5:9, :) ,CV中B(Range(4, 9), Range::all())

注意,Range的区间定义为:[left,right),右边界不是刚好等于right噢,实际是right-1,如上面的例子是取B的第5到第9个行,在matlab中下标是从1开始算的,所以直接是5:9,但在opencv里,下标从0开始,其数组下标范围是 i = 4:8,由于Range的区间定义,所以应写为 Range(4,9)

opencv这样定义Range区间主要是为了更好地表示单一一行或者一列,如,表示第10行,记为Range(10,11),如果按照我们习惯应该是Range(10,10),这样明显存在歧义不利于编程

还需要注意的是,matlab里面我们可以这样来赋值:

B(5:9,:) = C(5:9,:);
但opencv里不行,这样做没有任何意义,B的值不会改变,要用copyTo方法:

C(Range(4,9),Range::all()).copyTo(B(Range(4,9),Range::all()));


往往“简单易用”与“效率”是矛盾的,那Range方法又是不是中看不中用呢?下面做个小测试,跟指针方式访问相比较:

建立两个Mat

Mat D(h,w,CV_64F,cv::Scalar(0));
Mat E(h,w,CV_64F,cv::Scalar(0));
具体任务是把D的第1~500行、第5~700列的值拷贝至E的相同位置,分别通过指针访问Mat和Range访问Mat的方式实现,测量运行5000次的平均耗时:

double tcnt=0;
for(int cnt=0;cnt<5000;cnt++)
{
tt.interval();  //定时函数

D(Range(0,500),Range(4,700)).copyTo(E(Range(0,500),Range(4,700)));

tcnt += tt.interval();
}
cout<<"ptr time: "<<tcnt/5000<<endl;
指针方式:

double tcnt=0;
for(int cnt=0;cnt<5000;cnt++)
{
tt.interval();  //定时函数

double* ptr1 = (double*)E.data;
double* ptr0 = (double*)D.data;
for(int y=0;y<500;y++)
{
for(int x=4;x<700;x++)
{
*(ptr1 + y*w+x) = *(ptr0 + y*w+x);
}
}

tcnt += tt.interval();
}


结果显示,Range比指针的效率更高!!!不过也就高出10%,两者效率还是比较相近的,当然实际中采用Range会提高代码的可读性

5、高级操作

奇异值分解

矩阵求逆

(to be continued)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: