【OpenCV学习笔记】1.Mat类

1.Mat类的构造函数

Mat(int rows,int cols,int type);
//rows-行数,cols-列数,type-类型
//数据类型包括CV_8UC(n)、CV_8SC(n)、CV_16SC(n)、CV_16UC(n)、CV_32SC(n)、CV_32FC(n)等,n为通道数,imshow显示类型为CV_8UC1
Mat(Size(int cols,int rows),int type);
//Size第一个元素为列数(宽),第二个为行数(高)
Mat m;
m.create(int rows,int cols,int type);
m.create(Size(int cols,int rows),int type);
//使用Mat中的成员函数create完成Mat对象的构造
//examples:构造2行三列的矩阵
Mat m = Mat(2,3,CV_32FC1);
Mat m = Mat(Size(3,2),CV_32FC1);
Mat o = Mat::ones(2,3,CV_32FC1);//全是1的矩阵
Mat o = Mat::zeros(Size(3,2),CV_32FC1);//全是0的矩阵
Mat m = (Mat_<int>(2,3) << 1,2,3,4,5,6);//矩阵初始化

2.单通道Mat类基本操作

2.1.获得单通道Mat基本信息

Mat m = (Mat_<int>(2,3) << 1,2,3,4,5,6);
cout << "行数" << m.rows <<endl;
cout << "列数" << m.cols <<endl;
cout << "尺寸" << m.size() <<endl;
cout << "通道数" << m.channels() <<endl;
cout << "面积" << m.total() <<endl;//与通道数无关
cout << "维数" << m.dims <<endl;//单通道二维,多通道三维

2.2.访问单通道Mat对象中的值

//1.使用at
m.at<float>(r,c);//访问对象m第r行第c列的值
m.at<float>(Point(r,c));//访问对象m第r行第c列的值
//Point(c,r)第一个元素为列坐标,第二个元素为行坐标

//2.使用ptr
m.ptr<int>(r);//得到矩阵m第r行行首地址
//examples:访问m中所有值
for(int r=0; r<m.rows; r++)
{
    
    
	const int * ptr = m.ptr<int>(r);//得到矩阵m第r行行首地址
	//打印第r行所有值
	for(int c=0; c<m.cols; c++)
	{
    
    
	cout << ptr[c] <<",";
	}
	cout << endl;
}

//3.使用isContinuous和ptr
if(m.isContinuous())//isContinuous返回值为true,说明行与行间存储连续
{
    
    
	int * ptr = m.ptr<int>(0);//得到矩阵第一个值地址
	for(int n=0; n<m.cols*m.rows; n++)
		cout << ptr[n] <<","
}

//4.step和data:使用较少,不详细了解

3.多通道Mat类基本操作

3.1.向量类Vec

在了解多通道Mat对象之前,需要先了解向量类Vec。

Vec<Typename _Tp,int _cn>;//构造_cn X 1的列向量,数据类型为_Tp
//examples
Vec<int,3> vi(21,32,14);//构造长度为3,int类型,初始化21,32,14的列向量
cout << "访问第0个元素" << vi[0] <<endl;

另外,OpenCV为向量类的声明取了别名

typedef Vec<uchar,3> Vec3b;
typedef Vec<int,2> Vec2i;
typedef Vec<float,4> Vec4f;
typedef Vec<double,3> Vec3d;

单通道矩阵每个元素是一个数值,多通道矩阵每个元素可以看作一个向量。

3.2.构造多通道Mat对象

Mat(int rows, int cols, CV_32FC(n));
//构造由n个rows X cols二位浮点型数据组成的三维矩阵,n=1为单通道矩阵
//examples:
Mat mm = (Mat_<Vec3f>(2,2) << Vec3f(1,11,21),Vec3f(2,12,31),
								Vec3f(5,18,27)Vec3f(7,15,61);

3.3.访问多通道Mat对象中的值

//1.使用at
mm.at<Vec3f>(r,c);//获得第r行第c列的元素,即一个Vec3f
第0列 第1列
第0行 [1,11,21] [2,12,31]
第1行 [5,18,27] [7,15,61]
//2.使用ptr
mm.ptr<Vec3f>(r);//获得第r行首元素地址
//examples:
for(int r=0; r<mm.rows; r++)
{
    
    
	Vec3f* ptr = mm.ptr<Vec3f>(r);//得到行首地址
	for(int c=0; c<mm.cols; c++)
	{
    
    
	cout << ptr[c] <<",";
	}
	cout << endl;
}
//3.使用isContinuous和ptr
//4.step和data
//与上述类似,不再赘述

3.4.分离、合并通道

  • 分离通道:将多通道矩阵所有向量第一个值组成的单通道矩阵作为第一通道,所有向量第二个值组成的单通道矩阵作为第二通道,以此类推。
    以mm为例,三个通道分别是:

在这里插入图片描述

  • 合并通道:将多个尺寸相同、数据类型相同的单通道矩阵合并为一个三维矩阵
//使用split函数分离多通道,分离后的单通道矩阵被存放在vector容器中
vector<Mat> planes;
split(mm, planes);
//利用merge函数合并单通道矩阵
void merge(const Mat * mv, size_t count, OutputArray dst)
//examples:
Mat plane0 = (Mat_<int>(2,2) << 1,2,3,4);
Mat plane1 = (Mat_<int>(2,2) << 11,12,13,14);
Mat plane2 = (Mat_<int>(2,2) << 21,22,23,24);//三个单通道矩阵
Mat plane[] = {
    
    plane0, plane1, plane2};//用三个单通道矩阵初始化一个数组
Mat mat;
merge(plane, 3, mat);//合并

猜你喜欢

转载自blog.csdn.net/weixin_44496838/article/details/102814029