从OpenCV2的Mat说起

 从OpenCV2的Mat说起

tkorays(http://blog.csdn.net/tkorays)

我回忆所见远比我当前耳目所得更有价值。

 

        在使用OpenCV的过程中,有一个类是你必然每次都要用到的,它就是Mat。可以这么说OpenCV里最重要的一个类就是Mat了。“工欲善其事,必先利其器”,Mat就是我们的器。

        这里我们不会去深入探讨Mat的源码,而是从使用的角度来探讨下Mat这个类,继而展开,讨论下与Mat相关的一些数据结构以及操作等。

 

Mat基本

 

1.      Mat的内存管理问题

Mat的内存分配与释放都是由OpenCV自动管理的,因此我们可以不用太关心内存分配与释放问题。对于使用过的Mat可以让程序自己去释放,如果你觉得不安心,也可以手动释放。

OpenCV里多个Mat的头可能指向同一个数据块,我们不用担心释放了对其他数据是否造成影响,OpenCV引入了计数机制,最终,数据是由最后一个使用数据的Mat来释放。因此,每释放一个Mat,计数器减一,直到为0则释放数据块。

2.      你真的会复制Mat数据?

当你复制一个Mat的时候需要想想,你是只复制了Mat头、而指针还是指向原来的数据块,或者不仅复制了头、数据块也被复制到一个新的存储空间?注意下,如果多个Mat指向同一个数据块时,你对某一个Mat操作是会影响其他Mat的,一不小心你就干了件蠢事了。

因此,在必要的时候你应该使用copyTo或者clone将数据块复制过去。

3.      Mat的数据指针

你知道怎么获取Mat里面的原始数据吗?答案很简单,这个数据指针就是*data,它是一个uchar类型的指针。因此你完全可以对它进行“暴力”地操作。比如对一个已经分配内存的Mat我可以重写它的数据memcpy(M.data,(void*)data,size_of_the_data);

4.      Mat的数据获取

方法一:at法。使用Mat::at<Type>(inti,int j),对于3通道可以这样:Mat::at<Vec3b>(int i,int j)[int k];其他通道类似。

方法二:使用数据指针*data。

方法三:使用迭代器。注意迭代器扫描速度比较慢,但是不容易出错。

5.      输出数据自动内存分配

在一些语句中,我们没必要对Mat的内存进行事先分配,实际上,在一些输出的语句中,OpenCV能根据已知条件自动为我们分配内存。如cvtColor的输出,VideoCapture的>>输出。如果我们已经指定了大小,则这些函数操作不会再重新分配。部分带有函数不支持自动内存分配,如cv::mixChannels, cv::RNG::fill。

 

 

Mat拓展

 

1.      与OpenCV 1.x里面的C数据结构的转换

Mat操作符

图1  Mat操作符

 

从上图我们可以看到Mat支持的一些运算符,其中一些可以帮助我们将Mat转化为IplImage、CvMat、CvMatND这些低版本的数据结构。使用方法:

如:

IplImage* img =&M.operator IplImage();

CvMat* img =&M.operator CvMat();

2.      智能指针类Ptr

任务繁重时候,你可能会对C版本的内存管理吐槽一番。不支持自动内存管理在很多时候不是很方便,或者说它阻碍了我们的开发进度,我们需要对每个分配的内存进行检查,是否释放了。

而OpenCV提供了Ptr这样一个类模板,可以包装其他没有考虑到内存管理的类,实现内存自动管理。因此上面的代码可以写成:

Ptr<IplImage>img = &M.operator IplImage();

这里Ptr用来对老版本的数据结构进行指针操作,更安全有效,可以防止内存的不正常使用。所以是不是觉得处理那些没有考虑内存自动管理的类时就方便多了?

Boost库和现在的c++11标准里都有这样的类(shared_ptr)。

3.      Mat_类

Mat_是继承自Mat的一个模板类,它继承了Mat的大部分功能,而它还实现了()操作符。使用M(i,j)即可获得元素,代码比Mat的at更加简洁。

4.      Matx类

Matx是一个比较小的矩阵类,它的类型大小在编译时就是可以确定的。因此它的灵活性也就降低了。Matx也可以像Mat_一样通过M(i,j)这样的方式获取元素。


by tkorays(http://blog.csdn.net/tkorays


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值