Opencv中常用类的介绍

大纲

  1. Mat类
  2. Point类
  3. Scalar类
  4. Size类
  5. Rect类

一、Mat类
Mat是Opencv中的通用矩阵类型,我们通常将它作为图片的容器,它包含了矩阵头(包含矩阵尺寸,储存方法,储存地址等信息)和指向储存所有点值的指针。其创建方法如下:

1.使用Mat()构造函数
对于二维多通道的Mat类型,我们通常可以用如下形式来构建:

Mat test(2,3,CV_8UC3,Scalar(0,22,23));

前两个参数给出了矩阵的行列信息,第三个参数给出了矩阵的通道数目以及位深,最后一个参数则是给元素赋初值(可以暂时忽略,后续赋值)
2.使用create()成员函数
利用Mat类的成员函数来进行Mat类的初始化,使用方法如下:

Mat test;
test.create(4,4,CV_BUC2);

可以看到这种初始化方法和前一种看起来差别不大,但要注意使用这种方式的话无法对Mat赋初值,默认所有值为205,所以这种方法一般适用于后续改变矩阵尺寸时开辟内存空间
3.使用函数初始化特定矩阵
这种方法和Matlab中创建数组的方法一致,可以用于建立全零、全一、对角阵,使用方法如下:

Mat E=Mat::eye(4,4,CV_64F);
Mat O=Mat::ones(2,2,CV_32F);
Mat Z=Mat::zeros(3,3,CV_8UC1);

4.小矩阵直接赋值
当所需矩阵较小时,可以通过”<<"运算符对其直接初始化赋值,使用方法如下:

Mat C=(Mat_<double>(3,3)<<0,1,2,3,4,5,6,7,8);

5.通过已有矩阵赋值
通过clone()函数对已有的矩阵或者数组进行深复制(不是新建信息头),将其赋值给待初始化的数组。

//通过已有数组赋值
float b[4]={5,6,7,8};
Mat c = Mat(2,2,CV_32F,b).clone();
//抽取矩阵某一行赋值
Mat C = (Mat_<double>(3, 3) << 0, 1, 2, 3, 4, 5, 6, 7, 8);
Mat RowClone = C.row(1).clone();

在矩阵创建完成之后,我们通常还需要对矩阵进行访问以改变矩阵元素的值,矩阵元素的访问方式有以下几种。
1.按坐标模式访问

int ROWS = 100; // height
int COLS = 200; // width
Mat img(ROWS , COLS , CV_8UC3);    
for (int i=0; i<ROWS ; i++)  
{  
     for (int j=0; j<COLS ; j++)  
     {  
          Vec3b& pixel = img.at<Vec3b>(i, j);
 			//也可直接用img.at<Vec3b>(i, j)[0]这样的方式操作,无需外加Vec模板类
 			pixel[0] = 255;
			pixel[1] = 0;
			pixel[2] = 0;
    }  
}  

这一方式就是通过at函数来得到像素,img::at(i,j)为一个像素点的像素值数组,是一个大小为3的数组,从0~2为之赋值即可。这种方式简单易懂,也不会发生指针越位的问题,十分安全。但是在Debug的时候效率相较于接下来的两种访问方式就偏低了,Release情况下效率差不多。实际上查看at成员函数的源代码发现,这一方法实际上就是返回_Tp类型指针,指向img.data+i*step[0]+j,也就是和下述指针访问原理相同。
at<>数据类型和Mat数据类型对应如下:

Mat_<uchar>---------CV_8U
Mat<char>-----------CV_8S
Nat_<short>---------CV_16S
Mat_<ushort>--------CV_16U
Mat_<int>-----------CV_32S
Mat_<float>----------CV_32F
Mat_<double>--------CV_64F

标准指针访问

int ROWS = 100; // height
int COLS = 200; // width
Mat img(ROWS , COLS , CV_8UC3);  
for (int i=0; i<ROWS ; i++)   
{   
	Vec3b* it = img.ptr<Vec3b>(i);  //同上,这一步也不是必须的,只是好看
	for (int j=0; j<COLS ; j++)   
		{   
	     	it[j][0] = 255;
			it[j][1] = 0;
			it[j][2] = 0;
			//这里用的是数组写法,也可用(*it)[0]来表示
	    }   
}   

这种方法就是获取矩阵每一行的指针,再逐渐加一到行末,直到访问完所有数据。
指针块模式

int ROWS = 100; // height
int COLS = 200; // width
Mat img(ROWS, COLS, CV_8UC3);
cout << img.step[0];  //给出每行数据所占字节数
cout << img.step[1];  //给出每个元素的字节数
for (int i = 0; i < ROWS; i++)
{
	uchar* it = img.data + i * img.step[0]; // 每行数据的起始位置
	for (int j = 1; j < COLS; j++)
	{
		it[0] = 0;
		it[1] = 0;
		it[2] = 255;
		it += img.step[1];  
	}
}

这一方法与前一种指针的方法其实差不多,同样是获得指针,只不过是通过step的方法准确定位到了每一行每一列的指针,可以直接对每个通道进行赋值。
Point类
Point类常常是用与描述二维坐标系下点的位置,其使用方式如下:

Point point1= Point(1,2);
Pointe point2;
point2.x=2;
point2.y=1;

可以看出Point类(实际就是Poin2i)是专门用于描述二维整型坐标的,如果需要三维则需用到Point3,需要浮点型则要用到Point2f,其他更多参见参考文献3.
Scalar类
Scalar是一个含四元素的数组,通常用于储存像素的色彩空间信息,如果用不带四个参数也可以只输入三个参数,系统会默认用户只想使用三个参数,像是使用RGB颜色值定义的图片就只需要三个参数。使用范例如下:

Scalar color(233,233,233);

Size类
Size类是一个常用于描述图片尺寸的二元素数组,实质上也就是一个模板列,其成员变量包括width和height,都需要为int。常用初始化如下:

Size size(600,800)   //Size(width,height)

Rect类
Rect类一般是用于在图像中圈出某一块矩形区域,成员变量包括矩形区域左上角的坐标x、y(需要注意这里x指列数,y指行数)、矩形区域的宽度width、高度height。常用成员函数包括返回矩形面积的area(),判断点是否在矩形区域内的contain()等等,初始化方式为:

Rect rec1(0,0,600,800);  //Rect(x,y,width,height);
Rect rec2(point,size);

参考文献
Opencv Mat类型三种访问方式
Opencv 访问像素点三种方式
Opencv 数据类型
OpenCV的Rect矩形类简介和使用

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值