学习目标:
熟知Mat类,能够创建、赋值,了解其成员函数和常见的运算操作。
学习内容:
- Mat类的概述
- Mat类的创建
- Mat类的成员函数说明
- Mat常见的矩阵操作
一、Mat类的概述
1.Mat类有两个数据部分:矩阵头(包含矩阵的大小,存储方法和存储地址等)和一个指针,指向包含像素值的矩阵地址。矩阵头的存储空间是常数,矩阵本身的尺寸随着图像大小改变。
2.矩阵的拷贝、赋值运算符通常只赋值矩阵头和矩阵指针,但不是矩阵本身,即采用浅拷贝来提高效率
二、Mat类的创建
1.构造方法
Mat img(3,2, CV_8UC3, Scalar(0,0,255))
创建一个Mat类型的变量img,它是一个3行2列的矩阵,元素是8位无符号整数且有三个通道,初始化为Scalar(0,0,255)即红色图像。
- Mat类中type类型,CV_8UC1,CV_16SC3,CV_64FC4,其中8U表示8位无符号整数,16S表示16位有符号整数,64F表示64位浮点数,C表示通道数,C1表示一个通道的图像,即灰度图,C4表示4个通道的图像。
- openCV中用Scalar(0,255,0)表示颜色,默认颜色顺序为BGR。
2.create()
使用create创建Mat对象时不能初始化。
Mat img;
img.create(3,2,CV_8UC1)
3.直接赋值
m = (Mat_<int>(2,3) << 1,2,3,4,5,6); // 直接赋值
4.浅拷贝
矩阵相互赋值,只创建矩阵头,共享数据部分。
Mat img1( img ); //img和myMat共享图像数据
Mat myMat= img1; //仅创建头部分,共享数据部分
5.深拷贝
使用clone()和copyTo()实现深拷贝
Mat img = myMat.clone()
Mat G;
img.copyTo(G);
6.使用eye()、ones()、zeros()初始化Mat
Mat A = Mat:: eye(4,4,CV_64F) //初始化为对角矩阵
Mat B = Mat:: ones( 2, 2, CV_8U) //所有元素初始化为1
Mat C = Mat:: zeros( 3, 3, CV_8UC1) //所有元素初始化为0
三、Mat类的成员函数
- col(int i) //获取第i列数据,返回也是Mat类型
- row(int j) //获取第j行数据,返回也是Mat类型
- size() //矩阵尺寸[rows, cols]
- total() //rows* cols,而非矩阵元素数
- channels() //图像通道数
- rowRange()和colRange() // 读取连续几行或者几列
- m.rowRange(2,4)
- 遍历像素函数at()
- 格式为:myMat.at<float>(i, j) 获取矩阵第i行第j列的元素
- 获取矩阵行首元素指针ptr(),格式为mymat.ptr<int>(i) 指向第i行首元素的指针
- m.isContiuous()每一行是否连续存储的。
四、Mat常见的运算操作
设为A,B为Mat类型,s是Scalar类型,a是一个实数。下面列出关于Mat的常用运算:
- 矩阵加减: A+B,A-B,A+s,A-s,s+A,s-A,-A.
- 矩阵乘以实数: A*a,a*A
- 逐元素乘除: A.mul(B),A/B,a/A
- 矩阵乘法: A*BmaxVal; Point minPos,m
- 矩阵倒置: A.t()
- 矩阵的逆: A.inv()
- 矩阵比较: A comp B,A comp a,a comp A。这里comp包括 >, >=,==,!=,<=,<。得出的结果是一个单通道8位的矩阵,元素的值为255或0。
- 矩阵位操作: A logic B, A logic s,s logic A。这里logic包括:&,|,^
- 向量的差乘和内积: A.cross(B),A.dot(B);
以上方法均为Mat的内部方法,可以直接调用。