一、Mat对象
在OPCV2.0版本之前还未引进Mat对象,使用的是IpImage。属于C语言风格的数据结构,由于需要开发者自行分配内存与管理内存,所以很容易导致内存泄漏。
在OPCV2.0之后引进了Mat对象这一图像数据结构,可自动分配内存,不存在内存泄漏的问题。
关于Mat对象:
1.Mat是一个类。用来储存图像信息的内存对象。由两部分数据组成:矩阵头(包括矩阵尺寸、存储方法、存储地址等信息)和一个指向所有像素值的矩阵(根据所选存储方法不同,矩阵可以是不同的维数)的指针。
2.Opecv采用了计数机制,让每一个Mat对象有自己的信息头,但共用一个矩阵。这通过让矩阵指针指向同一个地址实现,而拷贝构造函数只复制信息头和矩阵指针,而不复制矩阵。
可以理解为一个包含图片所有信息的多维数组。
二.Mat常用方法
常用方法:
API | 作用 |
void copyTo(Mat mat) | 拷贝一个Mat |
void converTo(Mat dst,int type) | 数据类型转换 |
Mat clone() | 拷贝一份 |
int channels() | 通道数 |
int depth() | 位深 |
bool empty() | 是否是空 |
uchar* ptr(i=0) | 获取按行的指针 |
常用构造函数:
构造函数 | 作用 |
Mat () | 无参构造函数创建Mat对象 |
Mat(int rows, int cols, int type) | 使用行,列,类型三个参数创建Mat对象 |
Mat(Size size, int type) | 使用大小与类型参数的创建Mat对象 |
Mat (int rows, int cols, int type, const Scalar &s) | 使用行,列,类型,与颜色三个参数创建Mat对象 |
Mat(Size size, int type, const Scalar &s) | 使用大小、类型、Scalar向量三个参数的构造函数创建Mat对象 |
三.实例与代码
实例1:生成一张与输入图片大小一致的纯色图
代码:
Mat src,dst;
//从电脑中读取一张照片
Mat src = imread("D:/嵌入式学习/OPCV/图片/背景.jpg", IMREAD_UNCHANGED);
//如果没有找到图片则显示打开错误否则显示图片
if (src.empty())
{
printf("打开错误\r");
return -1;
}
namedWindow("原图",CV_WINDOW_AUTOSIZE);
imshow("原图",src);
/*生成一张什么都没有的图像,颜色是RGB(127, 0, 255),大小、类型与原图像相同*/
dst = Mat(src.size(), src.type());//创建一张空白图像
dst = Scalar(127, 0, 255); //设置各颜色的值或者灰度
namedWindow("测试", CV_WINDOW_AUTOSIZE);
imshow("测试", dst);
相关API:
API | 作用 | ||||||
imread(参数一,参数二) 参数一:图片保存的路径 参数二:
| 读取一张图片并且是否做修改 | ||||||
src.empty() | Mat 对象是否为空 | ||||||
src.size() | 保存在src中图片的大小 | ||||||
src.type() | 保存在src中图片的类型 | ||||||
Scalar(通道1,通道2,通道3,通道4) | 设置每个通道的数值,不给参数默认为0. 例程中是给RGB三个通道赋值 |
结果:
实例2:复制一张原图并转换为灰度图再输出原图与灰度图的通道数
代码:
Mat dst_2;
//dst =src.clone();//复制一张原图
src.copyTo(dst);//复制一张原图
cvtColor(src,dst,CV_BGR2GRAY);//转化为灰度图
//获取并输出通道数
printf("原图通道数:%d \r\n输出图通道数:%d\r\n", src.channels(), dst.channels());
namedWindow("测试", CV_WINDOW_AUTOSIZE);
imshow("测试", dst);
相关API:
API | 作用 |
cvtColor(参数一,参数二,参数三) 参数一:输入图 参数二:输出图 参数三:转换方式 (在OPENCV中 RGB格式写为BGR) | 对图片进行颜色空间转换 |
src.channels() | 获取通道数 |
结果:
实例3:获取图像像素的地址
代码:
const uchar* firstROW=dst.ptr<uchar>(0);//第一行第一个元素的值
const uchar* firstROW2 = dst.ptr<uchar>(1);//第一行第二个元素的值
const uchar* firstROW3 = &dst.ptr<uchar>(30)[1];//第31行第二个元素的值 要加取地址符号
int cols = dst.cols;//获取列数
int rows = dst.rows;//获取行数
printf("第一个行像素值:%d\n", *firstROW);
printf("第一行第二个像素值:%d\n", *firstROW2);
printf("第31行第一个像素值:%d\n", *firstROW3);
printf("行数:%d", rows);
printf("列数:%d", cols);
相关API:
API | 作用 |
dst.ptr<uchar>(x )(y ); | 获取某个像素的地址 |
dst.cols | 获取行数 |
dst.rows | 获取列数 |
结果: