在opencv2.0前,opencv使用C语言实现相关函数,那个时候存储图像的文件类型是IplImage,需要程序员手动管理内存。
在opencv2.0后,opencv引入了C++,Mat类就是其中一个变化。
Mat类似于STL中的容器类,能够动态管理内存。Mat类两部分数据,第一个是数据头(matrix header),它的占用的空间大小恒定,它包含了像素矩阵的大小,存储文件的方式,像素矩阵存储的地址等等。第二个是指向像素矩阵的指针,指正指向的大小不恒定,根据图像的变化而变化。
由于图像处理,往往会涉及大规模的数据,如果像拷贝其他数据结构一样拷贝Mat,会产生非常高的数据开销。所以,Mat类的不同实例的拷贝,只拷贝数据头。
1
2
3
4
5 |
<span style= "font-size: 14pt;" >Mat A, B; A= imread( "1.jpg" ,CV_LOAD_IMAGE_COLOR); B=A; Mat C(A); </span> |
上述代码,A B C都指向同一块像素矩阵。这里有一个叫做引用机制(reference counting machanism)的东西,就是说如果有多个同时复制的Mat对象,只当最后一个Mat对象被删除时,像素矩阵才会随着一起删除。
如果想要把像素矩阵也复制过去可以这样:
1
2
3
4
5 |
<span style= "font-size: 14pt;" >Mat A,B; A=imread( "1.jpg" ,CV_LOAD_IMAGE_COLOR); A.copyto(B); //B=A.clone(); </span> |
Mat的构造函数:
1
2
3 |
<span style= "font-size: 14pt;" >Mat M(2, 2, CV_8UC3, Scalar(255,0,255)); //注意只有二维的Mat才能用<<输出 cout<< "M=" <<endl<< " " <<M<<endl; </span> |
参数的输入是:
这里的注意2,2指的创建一个2*2的二维数组;
CV_8UC3是:CV_[The number of bits per item][Signed or Unsigned][Type Prefix]C[The channel number]
代表3个通道,注意在数组中,这三个通道的数据是连着的,也就是
[第一个像素的三个通道的值 第二个像素的三个通道的值(第一行结束); 第三个像素的 第四个的]
Mat类还有很多IplImage结构体所没有的优点,待发掘。
原文:http://www.cnblogs.com/wangpei0522/p/3748716.html