Mat类
Mat类用来保存矩阵类型的数据,包括向量、矩阵、灰度、通道数。主要分为两部分,矩阵头和矩阵指针。
(单通道为灰度图像,3通道或4通道为彩色图像)
矩阵头中包含矩阵形状、存储方法、地址、引用次数等。矩阵指针指向存储的矩阵数据。
Mat类间赋值仅复制了矩阵头和矩阵指针,不会复制整个矩阵(浅拷贝)。
数据类型
创建
using namespace cv;// opencv的命名空间
Mat a;// 创建一个空Mat类型矩阵头a
a = imread("test.jpg");// 将a赋值为图像数据,a中的矩阵指针指向像素数据
Mat b = a;// 将a的矩阵头和矩阵指针赋值给b
创建时可以显式声明数据类型
Mat a = Mat_<double>(3,3);// 创建一个用于存放double的3*3矩阵
C1 C2 C3 Cn分别表示单通道、双通道、三通道和n通道,默认为C1
可以直接通过指定数据直接创建
Mat a(640, 480, CV_8UC1, Scalar(255));// 创建一个640*480大小,存储8位无符号整数的单通道矩阵,矩阵中每个像素都被赋值为Scalar(255)
uchar 和 CV_8U 虽然都表示8位无符号整数,但被严格区分开。CV_8U只能用在Mat内部的方法,否则会报错
Scalar中的变量个数要与通道数相等,否则不会被读取或填充为0
构造
默认构造函数
Mat a = Mat();
利用矩阵尺寸和数据类型构造
Mat(int rows, int cols, int type);// 行,列,数据类型
利用Size结构构造。先列后行,顺序与其他相反
Mat(Size size(int cols, int rows), int type);// 列,行,类型
利用已有的Mat进行构造,m为已构造好的Mat类型数据。传递的是地址,修改新矩阵,旧矩阵也会受影响。
a = Mat(const Mat &m);// 如希望二者独立,可使用Mat x = y.clone(),即深拷贝
构造已有Mat的子类
Mat a = Mat(const Mat &m, const Range &rowRange, const Range &colRange = Range::all());
// 子矩阵,行range类数据,列range类数据。range默认为全部// 例如
Mat a = Mat(3,4,CV_8U);
Mat m(a, Range(2,3), Range(2,3));// 从a中截取第二行到第三行、第二列到第三列给m
// 或
Range rowRange = Range(2,3);// 创建Range变量
Range colRange = Range(2,3);
Mat m(a, rowRange, colRange);
快速构造
Mat a = Mat::eye(3,3,CV_8U);// 构建一个单位矩阵,主对角元素为1
// 1 0 0
// 0 1 0
// 0 0 1
Mat b = Mat::diag(Mat_<int>(1,3)<<1,2,3);// 构造一个对角矩阵,参数必须是Mat类型的一维变量,存放的是对角元素的赋值
// 1 0 0
// 0 2 0
// 0 0 3
// Mat_<int>(1,3)<<1,2,3 中创建了一个一行三列的Mat,用<<将其赋值为[1, 2, 3]
Mat c = Mat::ones(3,3,CV_8U);// 全1
Mat d = Mat::zeros(3,3,CV_8U);// 全0
以枚举或数组进行赋值
Mat a = (Mat_<int>(3, 3)<<1, 2, 3, 4, 5, 6, 7, 8, 9);// 枚举赋值
// 1 2 3
// 4 5 6
// 7 8 9int arr[] = {1, 2, 3, 4, 5, 6, 7, 8};
Mat b = Mat(2, 4, CV_32SC1, arr);// 数组赋值
Mat c = Mat(2, 2, Cv_32SC2, arr);
数组赋值可以灵活控制通道数
运算
运算中要求矩阵类型相同,并且常数与矩阵运算时保留矩阵类型
Mat a = (Mat_<int>(3, 3)<<1, 2, 3, 4, 5, 6, 7, 8 ,9);
Mat b = (Mat_<int>(3, 3)<<9, 8, 7, 6, 5, 4, 3, 2, 1);
Mat c = (Mat_<double>(3, 3)<<1.0, 2.1, 3.2, 4.0, 5.1, 6.2, 2, 2, 2);
Mat d = (Mat_<double>(3, 3)<<2, 2, 2, 6.2, 5.1, 4.0, 3.2, 2.1, 1.0);
Mat e, f, g, h, i, j, k;
e = a + b;// 对应位相加
f = c - d;// 对应位相减
g = 2 * a;// 对应位乘以常数
h = a * b;// 矩阵乘法
i = a.dot(b);// 矩阵点乘
j = a.mul(b);// 矩阵对应位相乘
k = a / 2;// 对应位除以常数
Mat类元素常用属性
Mat a = Mat::ones(3, 3, CV_8UC1);// 3*3的8位无符号整数单通道全1矩阵
a.cols; // 列数
a.rows; // 行数
a.step; // 以字节为单位的矩阵有效宽度
a.elemSize(); // 每个元素的字节数
a.total(); // 元素个数
a.channels(); // 通道数
a.size(); // 矩阵大小
a.type(); // 矩阵数据类型