(二)Mat类

构造函数

Mat m(3, 2, CV_8UC3, Scalar(0, 0, 255));
std::cout << m << std::endl;

创建一个行数为3,列数为2,图像元素是8位无符号整型,且有3个通道,图像所有像素值被初始化为(0,0,255)
opencv中默认的颜色顺序为BGR。使用cout输出上述m变量:
在这里插入图片描述
通过构造函数来创建Mat对象的方式有很多,可自行查看源代码。

matlab风格创建

Mat z = Mat::zeros(2, 3, CV_8UC1);
Mat z = Mat::ones(2, 3, CV_8UC1);
Mat z = Mat::eye(2, 3, CV_8UC1);

zeros和ones分别创建一个值为0,1的矩阵
eye创建一个单位矩阵。

对于单通道图像,矩阵的元素是基本数据类型,对于多通道图像,矩阵元素不再是一个值,可以用向量来表示:
例如8U类型的RGB彩色图像可以使用Vec3b,3通道float类型的矩阵可以使用Vec3f。

	Vec3b color;	//使用color变量来描述RGB颜色
	color[0] = 0;	//B分量
	color[1] = 0;	//G分量
	color[2] = 255;	//R分量

像素值读写

cv::Mat img = cv::imread("C:/Users/Administrator/Desktop/fapiao.jpg");
int channel = img.channels();
Vec3b value = img.at<Vec3b>(10, 20);
Vec3b tmp(255, 255, 255);
img.at<Vec3b>(10, 20)= tmp;

通过at函数可以读取和设置图片的像素值

#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
	cv::Mat img = cv::imread("C:/Users/Administrator/Desktop/fapiao.jpg");
	for (int i = 0; i < img.rows; i++)
	{
		for (int j = 0; j < img.cols; j++)
		{
			Vec3b pixel;
			pixel[0] = i % 255; //Blue
			pixel[1] = j % 255; //Green
			pixel[2] = 0; //Red
			img.at<Vec3b>(i, j) = pixel;
		}
	}

	cv::imshow("image", img);
	cv::waitKey(0);
	return 0;
}

遍历图像,不推荐使用at函数,该函数效率较低。

	for (MatIterator_<Vec3b> it = img.begin<Vec3b>(); it != img.end<Vec3b>(); it++)
	{
		it[0] = 255;
		it[1] = 255;
		it[2] = 222;
	}

上述为通过迭代器进行遍历修改。

	for (int i = 0; i < img.rows; i++)
	{
		//获取第 i 行首像素指针
		Vec3b* p = img.ptr<Vec3b>(i);
		for (int j = 0; j < img.cols; j++)
		{
			p[j][0] = 222;//b
			p[j][1] = 222;//g
			p[j][2] = 222;//r
		}
	}

上述为通过指针对图片进行读取修改,该种方式效率较高

选取图像部分区域

Mat类提供了很多方法来选取图像的部分区域,需要注意的是,这些方法并不申请新的内存空间,而是与原对象共享内存空间,因此执行效率高。

Mat mat = Mat::eye(6, 6, CV_32S);
Mat matr = mat.row(1);
Mat matc = mat.col(2);

row或者col获取Mat的某一行或者某一列

Mat mat = Mat::eye(6, 6, CV_32S);
Mat matb = mat(Range::all(),Range(0,3));

使用range获取行或者列某个范围,Range::all()表示所有

Mat mat = Mat::eye(6, 6, CV_32S);
Mat mata =  mat.diag(1);

diag用于获取对角线元素
0:获取主对角线
大于0:主对角线下方元素
小于0:主对角线上方元素

Mat_

Mat_类继承自Mat类,可以用于简化Mat类读写像素值时每次都需要写模板类型。

Mat m = Mat::eye(3, 3, CV_8UC1);
Mat_<uchar> m_ = (Mat_<uchar>)m;
for (int i = 0; i < m.rows; i++)
{
	uchar* p = m_.ptr(i);
	for (int j = 0; j < m.cols; j++)
	{
		double tmp = (i + j) % 255;
		m_(i, j) = tmp;

	}
}

Mat内存管理

mat类实际用于存放矩阵数据的是一个uchar类型的data指针,为了节约内存,data采用引用计数的方式进行管理,就类似于智能指针。
在这里插入图片描述

Mat a(100, 100, CV_8UC1);
Mat b = a;
Mat c = a(Rect(50, 60, 40, 40));

在这里插入图片描述
矩阵头存储Mat类基本信息,包括行数,列数,通道数等,上面abc三个mat对象有各自的矩阵头,但是共享矩阵数据内存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

vegetablesssss

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值