OpenCV联合C++/Qt 学习笔记(一)----Mat容器
本文介绍了OpenCV中Mat类的核心功能和使用方法。Mat类是OpenCV中表示多维数组(特别是图像数据)的主要数据结构,支持多种数据类型(如CV_8U、CV_32F等)和创建方式。文章详细说明了Mat类的创建与赋值方法,包括矩阵初始化、单位矩阵/对角矩阵生成等,并介绍了矩阵元素的读取方式(如at方法)和常用属性(如rows、cols等)。最后,总结了Mat类支持的各种运算操作,包括四则运算、矩
·
一、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]更多推荐
所有评论(0)