什么是Mat

Mat是Opencv2.0版本之后引入的一个C++类,为了在内存中存放图像而建。由两个数据部分组成:矩阵头(包含矩阵尺寸,存储方法,存储地址等信息)和一个指向存储所有像素值的矩阵(根据所选存储方法的不同矩阵可以是不同的维数)的指针。矩阵头的尺寸是常数值,但矩阵本身的尺寸会依图像的不同而不同,通常比矩阵头的尺寸大数个数量级。因此,当在程序中传递图像并创建拷贝时,大的开销是由矩阵造成的,而不是信息头。
Opencv作为一个大的图像处理库,我们运行是图像处理算法,难免会有图像的拷贝,对于大的图像,会造成很大的内存开销,降低程序的运行速度。为了解决这个问题,Opencv使用了引用计数机制——每个Mat有自己的信息头,但是共享一个矩阵。拷贝构造函数只是拷贝信息头和矩阵指针而不拷贝矩阵。感觉这个很棒。

如何构造一个Mat实例

官方文档上有几十种构造函数,下面是一个构造的小实例
方法一:

Mat A, C;                                 // 只创建信息头部分
A = imread("test.jpg", CV_LOAD_IMAGE_COLOR); // 这里为矩阵开辟内存

Mat B(A);                                 // 使用拷贝构造函数

C = A;

方法二:

Mat D (A, Rect(10, 10, 100, 100) ); // 使用矩形构造
Mat E = A(Range:all(), Range(1,3)); // 指定行和列构造

方法三:

Mat F = A.clone(); 通过clone()和copyTo()方法构造
Mat G;
A.copyTo(G);

Mat类中一些方法、属性含义

  • uchar * data

指针,指向Mat数据矩阵的首地址

  • int dims

Mat矩阵的维度,比如说二维就相当于平面的x,y。三维就是x,y,z。

  • MatSize size()

是一个结构体,其中包含了矩阵的宽高

template<typename _Tp> class Size_
{
public:
    typedef _Tp value_type;

    //! various constructors
    Size_();
    Size_(_Tp _width, _Tp _height);
    Size_(const Size_& sz);
    Size_(const Point_<_Tp>& pt);

    Size_& operator = (const Size_& sz);
    //! the area (width*height)
    _Tp area() const;
    //! true if empty
    bool empty() const;

    //! conversion of another data type.
    template<typename _Tp2> operator Size_<_Tp2>() const;

    _Tp width, height; // the width and the height
};
  • int channels()

表示矩阵拥有的通道数,比如RGB的通道数为3,灰度图只有一种信息通道数为1

  • int depth()

表示每个像素每个通道的精度,级别从0-6,数值越大,精度越高。源代码中枚举值为enum{CV_8U=0,CV_8S=1,CV_16U=2,CV_16S=3,CV_32S=4,CV_32F=5,CV_64F=6}。8,16,32,64分别表示位数,U表示无符号,S表示有符号。

Mat类的一些使用方法

  • 获取宽高、深度、通道数、维数
int width = mat.cols;
int height = mat.rows
int depth = mat.depth();
int channels = mat.channels();
int dims = mat.dims;