一、Mat类
1、什么是Mat类
Mat是 OpenCV 中用于表示和管理多维数组(尤其是图像数据)的核心数据结构。
2、Mat 的核心组成
3、Mat能存储的数据
- cv::Mat_<_TP>
- cv::Mat_<double>
- cv::Mat_<float>
- cv::Mat_<uchar>
- cv::Mat_<unsigned char>
4、OpenCV中规定的数据类型
| 数据类型 | 具体类型 | 取值范围 |
| CV_8U | 8位无符号整数 | 0--255 |
| CV_8S | 8位符号整数 | -128--127 |
| CV_16U | 16位无符号整数 | 0--65535 |
| CV_16S | 16位符号整数 | -32768--32767 |
| CV_32S | 32位符号整数 | -2147483648--2147483647 |
| CV_32F | 32位浮点整数 | -FLT_MAX-FLT_MAX, INF, NAN |
| CV_64F | 64位浮点整数 | -DBL_MAX-DBL_MAX, INF, NAN |
二、创建与赋值
1、三种常用创建方式
/*利用矩阵的宽、高、类型参数创建Mat类*/ Mat a(3,3,CV_8UC1); /*利用矩阵Size()结构和数据类型参数创建Mat类*/ Mat b(Size(3,3),CV_8UC1); /*利用已有Mat类创建新的Mat类*/ Mat c(b,Range(2,5),Range(2,5));/*范围从0开始,左闭右开,即Range(2,5)==>[2,5)*/2、对Mat变量赋值
- 创建时赋值
Mat c0(5, 5, CV_8UC1, Scalar(4, 5, 6)); Mat c1(5, 5, CV_8UC2, Scalar(4, 5, 6)); Mat c2(5, 5, CV_8UC3, Scalar(4, 5, 6));- 类方法赋值
/*eye:单位矩阵*/ Mat a = Mat::eye(3, 3, CV_32F); /*diag:对角矩阵*/ Mat b = (cv::Mat_<int>(1, 5) << 1, 2, 3, 4, 5); Mat c = Mat::diag(b); /*ones:元素全为1的矩阵*/ Mat d = Mat::ones(2, 3, CV_8U); /*zero:元素全为0的矩阵*/ Mat e = Mat::zeros(2, 3, CV_8U);- 枚举法赋值
Mat a = (cv::Mat_<int>(3,3) << 1, 2, 3, 4, 5, 6, 7, 8, 9); Mat b = (cv::Mat_<double>(2,3) << 1.0, 2.1, 3.2, 4.0, 5.1, 6.2);三、Mat类数据的读取
1、Mat数据在内存中的存放形式
2、Mat类矩阵的常用属性
| 属性 | 作用 |
| cols | 矩阵的列数 |
| rows | 矩阵的行数 |
| step | 以字节为单位的矩阵的有效宽度 |
| elemSize() | 每个元素的字节数 |
| total() | 矩阵中元素的个数 |
| channels() | 矩阵的通道数 |
3、Mat元素的读取
at方法读取Mat矩阵元素 at(int row, int col)
- 单通道:
int value = (int)a.at<uchar>(0,0);- 多通道:
cv::Vec3b vc3 = b.at<cv::Vec3b>(0,0); int first = (int)vc3.val[0];矩阵元素地址定位方式访问元素
/*单通道*/ (int)(*(b.data + b.step[0] * row + b.step[1] * col + channel)); /*比较直观*/ /*不用考虑数据类型*/四、Mat支持的运算
1、四则运算
- 符号运算(+、-、*、/)
- 两个矩阵相乘
- 1> 矩阵乘积----" * "
- 2> 向量内积----" .dot "
- 3> 对应位元素乘积----" .mul() "
2、提供的运算函数
| 函数名 | 作用 |
| absdiff() | 两个矩阵对应元素差的绝对值 |
| add() | 两个矩阵求和 |
| addWeighted() | 两个矩阵线性求和 |
| divide() | 矩阵除法 |
| invert() | 矩阵求逆 |
| log() | 矩阵求对数 |
| max()/min() | 两个矩阵计算最大值/最小值 |
Mat a = (cv::Mat_<int>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9); Mat b = (cv::Mat_<int>(3, 3) << 1, 2, 3, 7, 8, 9, 4, 5, 6); Mat c = (cv::Mat_<double>(3, 3) << 1.0, 2.1, 3.2, 4.0, 5.1, 6.2, 7.0, 8.1, 9.2); Mat d = (cv::Mat_<double>(3, 3) << 1.0, 2.1, 3.2, 4.0, 5.1, 6.2, 7.0, 8.1, 9.2); cout << "两个矩阵的和 = " << endl << a + b << endl; cout << "两个矩阵的差 = "<< endl << c - d << endl; cout << "矩阵数乘 = " << endl << a * 2 << endl; cout << "矩阵数除 = " << endl << d / 2.0 << endl; cout << "矩阵减数 = " << endl << a - 1 << endl; cout << "两矩阵相乘 = " << endl << c * d << endl; cout << "矩阵内积 = " << endl << a.dot(b) << endl; cout << "矩阵对应位相乘 = "<< endl << a.mul(b) << endl; cout << "两个矩阵最小值 = " << endl << min(a,b) << endl; /*************输出结果*************************************/ 两个矩阵的和 = [2, 4, 6; 11, 13, 15; 11, 13, 15] 两个矩阵的差 = [0, 0, 0; 0, 0, 0; 0, 0, 0] 矩阵数乘 = [2, 4, 6; 8, 10, 12; 14, 16, 18] 矩阵数除 = [0.5, 1.05, 1.6; 2, 2.55, 3.1; 3.5, 4.05, 4.6] 矩阵减数 = [0, 1, 2; 3, 4, 5; 6, 7, 8] 两矩阵相乘 = [31.8, 38.73, 45.66; 67.8, 84.63, 101.46; 103.8, 130.53, 157.26] 矩阵内积 = 258 矩阵对应位相乘 = [1, 4, 9; 28, 40, 54; 28, 40, 54] 两个矩阵最小值 = [1, 2, 3; 4, 5, 6; 4, 5, 6]