图像存储容器Mat类


Mat类

简介

  • Mat类用来保存矩阵类型的数据信息,包括向量、矩阵、灰度或彩色图像等数据。
  • Mat类分为矩阵头(元数据)和指向存储数据的矩阵指针两部分
  • 矩阵头中包含矩阵的尺寸、存储类型、地址和引用次数等。矩阵头的大小是一个常数,不会随着矩阵尺寸的大小而改变
  • 在绝大多数情况下,矩阵头大小远小于矩阵中数据量的大小,因此图像复制和传递过程中主要的开销是存放矩阵数据。为了解决这个问题,在OpenCV中复制和传递图像时,只是复制了矩阵头和指向存储数据的指针

例如,赋值运算符并没有从一个对象(Mat A)到另一个对象(Mat B)复制内存内容;而只是对其引用(相应内容的存储地址)的复制。之后,一个对象(A 或 B)的改变对两个对象都有影响

Mat A, C;
A = imread("test.jpg");
Mat B(A);   // 复制构造函数
C = A;      // 赋值运算
/* A,B,C指向同一数据块 */

构造函数

常用

  • cv::Mat()
  • cv::Mat(int rows, int cols, int type)
  • cv::Mat(Size size, int type)
  • cv::Mat(int rows, int cols, int type, const Scalar &s)
  • cv::Mat(Size size, int type, const Scalar &s)
Mat img;  // 创建无初始化矩阵
Mat img1(20, 10, CV_8UC1);  // 创建20行10列(10*20)类型为8位的单通道矩阵
Mat img2(Size(20, 10), CV_8UC3);  // 创建大小为20*10类型为8位的3通道矩阵
Mat img3(20, 10, CV_8UC1, Scalar(0, 255, 0));  // 创建大小为10*20的8位单通道矩阵
Mat img4(Size(10, 20), CV_8UC1, Scalar(255));  // 创建大小为10*20的8位单通道矩阵

其他

  • eye():构建一个单位矩阵,前两个参数为矩阵的行数和列数,第三个参数为矩阵的存储类型或通道数。如果行和列不相等,则在矩阵的(1,1),(2,2),(3,3)等主对角位置处为1
  • diag():构建对角矩阵,其参数必须是Mat类型的一维变量,用来存放对角元素的数值
  • ones():构建一个全为1的矩阵,参数含义与eye()相同
  • zeros():构建一个全为0的矩阵,参数含义与eye()相同
cv::Mat a = cv::Mat::eye(3, 3, CV_8UC1);
cv::Mat b = (cv::Mat_(1, 3) << 1, 2, 3);
cv::Mat c = cv::Mat::diag(b);
cv::Mat d = cv::Mat::ones(3, 3, CV_8UC1);
cv::Mat e = cv::Mat::zeros(4, 2, CV_8UC3);

复制

  • 使用函数clone()copyTo()复制一幅图像的矩阵
Mat A, C;
Mat B = A.clone();
A.copyTo(C);

常用成员函数和成员变量

成员函数

  • elemSize():每个元素的字节数
  • total():矩阵中元素的个数
  • channels():访问图像通道数
  • type():矩阵的类型

成员变量

  • cols:矩阵的列数
  • rows:矩阵的行数
  • step:以字节为单位的矩阵的有效宽度
  • data:指向矩阵的数据单元的指针