图像存储容器Mat类
Mat类
简介
- Mat类用来保存矩阵类型的数据信息,包括向量、矩阵、灰度或彩色图像等数据。
- Mat类分为矩阵头(元数据)和指向存储数据的矩阵指针两部分。矩阵头中包含矩阵的尺寸、存储类型、地址和引用次数等。矩阵头的大小是一个常数,不会随着矩阵尺寸的大小而改变
构造
常用
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)
- rows:矩阵的行数
- cols:矩阵的列数
- type:矩阵中存储的数据类型
- size:二维数组变量尺寸,通过 Size(cols,rows) 进行赋值
- s:给矩阵中每个像素赋值的参数变量,例如 Scalar(0,0,255)
例如:
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)等主对角位置处为1diag()
:构建对角矩阵,其参数必须是Mat类型的一维变量,用来存放对角元素的数值ones()
:构建一个全为1的矩阵,参数含义与eye()
相同zeros()
:构建一个全为0的矩阵,参数含义与eye()
相同
例如:
cv::Mat a = cv::Mat::eye(3, 3, CV_8UC1);
cv::Mat b = (cv::Mat_<int>(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);
复制
浅拷贝
- 所谓浅拷贝,就是只建立了一个能够访问图像数据的变量,通过浅拷贝创建的数据变量访问的数据与原变量访问的数据相同,如果通过任意一个变量更改了数据,另一个变量读取数据时会读取更改之后的数据
Mat A = Mat_<uchar>::zeros(3, 3);
Mat B(A); // 复制矩阵头,命名为B
Mat C = A; // 复制矩阵头,命名为C
深拷贝
- 深拷贝在创建变量的同时会在内容中分配新的地址用于存储数据,因此原变量访问的数据地址和新变量访问的数据地址不相同
Mat img;
Mat img_copy1, img_copy2;
img_copy1 = img.clone();
img.copyTo(img_copy2);
赋值
在构造时赋值
cv::Mat kernel(3, 3, CV_8UC1, Scalar(0, 255, 0));
- 如果 Scalar 结构中变量的个数大于通道数,则位置在大于通道数之后的数值将不会被读取;如果 Scalar 结构中变量的个数小于通道数,则会以0补充
枚举法赋值
cv::Mat kernel = (cv::Mat_<float>(3, 3) << 0, 1, 0,
1, 0, 1,
0, 1, 0);
- 在采用枚举法时,输入的数据个数一定要与矩阵元素个数相同
利用数组进行赋值
float a[8] = {5, 6, 7, 8, 1, 2, 3, 4};
cv::Mat b = cv::Mat(2, 2, CV_8UC3, a);
- 由数组赋值给矩阵的过程是首先将矩阵中第一个元素的所有通道依次赋值,之后再赋值下一个元素
常用成员
成员函数
elemSize()
:每个元素的字节数total()
:矩阵中元素的个数channels()
:图像通道数type()
:矩阵的类型size()
:矩阵的尺寸
成员变量
cols
:矩阵的列数rows
:矩阵的行数step
:以字节为单位的矩阵的有效宽度data
:指向矩阵的数据单元的指针dims
:矩阵的维度