Opencv Mat数据结构学习

来源:互联网 发布:烤蝎子有毒吗 知乎 编辑:程序博客网 时间:2024/04/29 05:06

1,定义:

       Mat用来存储多维矩阵的数组,能够动态的管理内存,代替了之前c语言写的lplimage这个存储结构。矩阵数据结构分为两部分,一部分是数据头,存储着矩阵首地址,存储方式,大小等信息,这部分大小固定;二部分是数据部分,都是像素值,根据图像深度不同,像素值取值范围不同。

2,基本属性:

       data:就是数组内的每一个元素,data本身是一个指针, 指向矩阵数据。
       dims:矩阵的维数,3*4*5的矩阵就是三维矩阵,dims=3
       rows:矩阵行数
       cols:矩阵列数
       channels:图像通道数。所谓通道,通俗的讲就是一个元素由几个数字表示。比如在RGB颜色空间中,一个像素由(0,0,255)类似于这样的值构成,这个图像就是三通道的。再比如灰度图,灰度图的灰度由0~255之间的数字表示,所以是单通道,也有三通道的灰度图,只不过三个通道的数值相等。
       type:他是一系列数值,表示了矩阵中元素的类型、通道个数。但是不直接使用数值来表示type,而是使用命名规则。如CV_(位数)+(数据类型)+(通道个数),位数包括额数值有8、16、32、64。数据类型U表示无符号整数,S代表有符号整数,F代表浮点数。通道数用C1、C2、C3、C4表示。
       depth:表示一个通道的数据类型。也是一系列预定的值。CV_8UC3,表示3通道,每个通道表示数8位无符号整数。通道信息就是CV_8U。有0-6七个不同的数值。
       elemSize:矩阵中一个像素所使用的字节数。如CV_8UC3,计算方式是3*8/8=3bytes
       elemSize1:矩阵元素一个通道所使用的字节数。上述例子就是8/8=1bytes。
每个元素的调用方法如下:
      void pic_info(Mat a) {
           cout << “dims:” << a.dims << endl
                  << “rows:” << a.rows << endl
                  << “cols:” << a.cols << endl
                  << “channels:” << a.channels() << endl
                 << “type:” << a.type() << endl
                 << “depth:” << a.depth() << endl
                 << “eleSize:” << a.elemSize() << endl
                 << “eleSize1:” << a.elemSize1() << endl
                 << “step[0]:” << a.step[0] << endl
                 << “step[1]:” << a.step[1] << endl;
     }

3,矩阵的声明、赋值操作

(1)声明和拷贝

       Mat a;      //这就声明了一个矩阵,系统分配了头部信息,但是并没有为数据部分开辟空间。
       a = imread(“C://Users//Administrator//Desktop//a.jpg”);//这里一定是绝对路径。
                       //如果放在工程文件下的话,应该放在Debug文件夹下.
       Mat b(a);  //这是拷贝构造函数
       Mat c = a;//这两种做法只是把指针指向了a的数据区,三个矩阵同时使用一个数据区。
                       // 只有三个矩阵都删除的时候,数据区空间才会回收,所以不用担心野指针问题。

(2)如果想建立和a相同数组元素且独立的数据空间,就需要如下做法:

       Mat b,c;
       b = a.clone();
       a.copyTo(c);//这两种方法都是可以的。

(3)如果想显示的建立Mat矩阵。

       Mat a(2, 2, CV_8UC3, Scalar(0, 0, 255));//因为是三通道矩阵,所以Scalar中提供三个数字。一般不使用数组赋值,这里数组赋值是浅拷贝,如果赋值完成奖数组释放,那么矩阵中的元素就是乱码。
       int size[] = {100, 23, 23};//这种赋值类型的数组不用定义数组大小.
       Mat b(3, size, CV_8UC3, Scalar::all(0));//第一个参数表示维度数,第二个数组表示每个维度上的数量。

4,step,求元素在内存中的存储位置

       step是一个数组,数组的长度等于dims参数大小。以二维3*4 CV_8UC3的矩阵为例,
       step[0] = 4*8*3/8 = 12
       step[1] = 8*3/8 = 3
       addr(1,2) = data + step[0]*1 + step[1]*2;

5,显示图像

       Mat a = imread(“a.jpg”); namedWindow(“ABC”); imshow(“ABC”, a);
       如果图片不能显示,
       可能原因:

       (1)没有使用绝对路径或者照片不存在
       (2)结尾处没有使用waitKey();
0 0
原创粉丝点击