OpenCV(二) Mat简介(原理)

关于MAT


在对图像进行处理时,首先需要将图像载入到内存中,而Mat就是图像在内存中的容器,管理着图像在内存中的数据。
Mat是C++ 的一个类,由于OpenCV2中引入了内存自动管理机制,所以不必手动的为Mat开辟内存空间以及手动的释放内存。
Mat中包含的数据主要由两个部分构成

1.矩阵头(矩阵尺寸、存储方法、存储地址等信息)(大小固定)
2.一个指向存储图像所有像素值的矩阵(根据所选的存储方法不同的矩阵可以是不同的维数)的指针

在图像处理中,对图像的处理不可能是在一个函数中完成的,这就需要在不同的函数间传递Mat
同时,图像处理的计算量是很大,除非万不得已就不要去传递比较大的Mat。这就要求使用某种机制来实现Mat的快速传递
Mat中主要有矩阵头和一个指向矩阵的指针,矩阵头是一个常数值,但是矩阵保存了图像所有的像素值,通常会比矩阵头大几个数量级,因此传递Mat是主要的消耗是在矩阵复制上


为了解决这个问题,OpenCV中引入了计数机制
每个Mat都有自己的信息头,但是共享同一个矩阵,也就是在传递Mat时,只复制矩阵头和指向矩阵的指针。

   1:      Mat a,c ; 
   2:      a = imread("d:\\test.jpg",1) ;
   3:      Mat b(a) ; //拷贝构造函数
   4:      a = c ; //复制运算符
 
 
上面代码中3个Mat对象a,b,c指向同一个矩阵,由于都指向了同一个矩阵某一个对象对矩阵进行操作时也会影响到其他对象读取到的矩阵
多个对象同时使用一个矩阵,那么当不需要该矩阵时, 谁来负责清理 ?   
简单的回答是,最后一个使用它的对象
通过引用计数机制,无论什么时候Mat对象的信息头被复制了,都会增加矩阵的引用次数加1;
反之,当一个Mat的信息头被释放后,引用计数就会被减1;当计数被减到0时,矩阵就会被释放。
有些时候还是需要拷贝矩阵本身的,这时候可以使用clonecopyTo

通过clone和copyTo创建的Mat,都有自己的矩阵,修改其中一个的矩阵不会对其他的造成影响。








mat的数据存储


Mat_<uchar>对应的是CV_8U,
Mat_<char>对应的是CV_8S,
Mat_<int>对应的是CV_32S,
Mat_<uint>对应的是CV_32U,
Mat_<float>对应的是CV_32F,
Mat_<double>对应的是CV_64F

这里还需要注意一个问题,很多OpenCV的函数支持的数据深度只有8位和32位的,
所以要少使用CV_64F,但是vs的编译器又会把float数据自动变成double型,有些不太爽。
还有个需要注意的问题,就是流操作符<<对于Mat的操作,仅限于Mat是2维的情况。

Mat的存储是逐行的存储的。


Mat的创建

方式有两种:

1.Mat(行,列,类型(值))
2. 调用create(行,列,类型)
// make a 7x7 complex matrix filled with 1+3j.
1. Mat M(7,7,CV_32FC2,Scalar(1,3));
// and now turn M to a 100x60 15-channel 8-bit matrix.
 2. M.create(100,60,CV_8UC(15));  // C代表channel通道数

要是想创建更高维的矩阵,要写成下面的方式:
int sz[] = {100, 100, 100}; 
Mat bigCube(3, sz, CV_8U, Scalar::all(0));  



 
 
 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值