Mat对象与IplImage对象
- Mat对象OpenCV2.0之后引进的图像数据结构、自动分配内存、不存在内存泄漏的问题,是面向对象的数据结构。分了两个部分,头部与数据部分
- IplImage是从2001年OpenCV发布之后就一直存在,是C语言风格的数据结构,需要开发者自己分配与管理内存,对大的程序使用它容易导致内存泄漏问题,下面是IplImage结构体的定义:
1 | typedef struct _IplImage |
Mat对象使用
基本概念
通道
把图像分解成一个或多个颜色成分!
- 单通道:一个像素点只需一个数值表示,只能表示灰度,0为黑色
- 三通道:RGB模式,把图像分为红绿蓝三个通道,可以表示彩色,全0表示黑色
- 四通道:在RGB基础上加上alpha通道,表示透明度,
alpha=0
表示全透明 - 双通道:双通道图像不常见,通常在程序处理中会用到,如傅里叶变换,可能会用到,一个通道为实数,一个通道为虚数,主要是编程方便
通过画图板的各种格式可以保存出不同的类型
深度
深度即位数(比特数)
位深:一个像素点所占的总位数,也叫像素深度、图像深度等
位深 = 通道数 × 每个通道所占位数
256色图:n位的像素点可以表示2^n种颜色,称2^n色图,n=8时为256色图
8位RGB与8位图:前者的位数指每个通道所占的位数,后者指整个像素点共占的位数
8位RGB是一个24位图,也称为真彩
Mat对象构造函数
Mat()
无参数构造方法Mat(int rows, int cols, int type)
创建行数为 rows,列数为 col,类型为 type 的图像Mat(Size size, int type)
创建大小为 size,类型为 type 的图像Mat(int rows, int cols, int type, const Scalar& s)
创建行数为 rows,列数为 col,类型为 type 的图像,并将所有元素初始化为值sMat(Size size, int type, const Scalar& s)
创建大小为 size,类型为 type 的图像,并将所有元素初始化为值 sMat(const Mat& m)
将m赋值给新创建的对象,此处不会对图像数据进行复制,m和新对象共用图像数据,属于浅拷贝Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP)
创建行数为rows,列数为col,类型为type的图像,此构造函数不创建图像数据所需内存,而是直接使用data所指内存,图像的行步长由 step指定Mat(Size size, int type, void* data, size_t step=AUTO_STEP)
创建大小为size,类型为type的图像,此构造函数不创建图像数据所需内存,而是直接使用data所指内存,图像的行步长由step指定Mat(const Mat& m, const Range& rowRange, const Range& colRange)
创建的新图像为m的一部分,具体的范围由rowRange和colRange指定,此构造函数也不进行图像数据的复制操作,新图像与m共用图像数据Mat(const Mat& m, const Rect& roi)
创建的新图像为m的一部分,具体的范围roi指定,此构造函数也不进行图像数据的复制操作,新图像与m共用图像数据
例如:Mat M(2,2,CV_8UC3, Scalar(0,0,255))
这些构造函数中,很多都涉及到类型type。type可以是CV_8UC1
,CV_16SC1
,CV_64FC4
等其中前两个参数分别表示行(row)跟列(column)、第三个CV_8UC3
中的8表示每个通道占8位、U表示无符号、C表示Char类型、3表示通道数目是3,第四个参数是向量表示初始化每个像素值是多少,向量长度对应通道数目一致
如果你需要更多的通道数,需要用宏 CV_8UC(n)
,例如:Mat M(3,2, CV_8UC(5))
创建行数为 3,列数为 2,通道数为 5 的图像。
Mat对象常用方法
部分复制:一般情况下只会复制Mat对象的头和指针部分,不会复制数据部分
1
2Mat A= imread("XXX");
Mat B(A) // 只复制头信息,浅拷贝
完全复制:如果想把Mat对象的头部和数据部分一起复制,可以通过如下两个API实现
1
2
3Mat F = A.clone();
Mat G;
A.copyTo(G);
Mat对象分为头部与数据部分,赋值操作和拷贝构造函数只会复制头部,要想用深拷贝只能使用clone()
、 copyTo(Mat dst,int type)
!
1 |
|
这是创建的5*5的矩阵
关于Scalar
查看源码opencv3源码, 发现Scalar做成了模板类,其中有如下构造函数:可以看到,Scalar是一个由长度为4的数组作为元素构成的结构体,Scalar最多可以存储四个值,没有提供的值默认是0。
Scalar常用的使用场景如下:
1 | Mat M(7,7,CV_32FC2,Scalar(1,3)); |
上面的代码表示:创建一个2通道,且每个通道的值都为(1, 3),深度为32,7行7列的图像矩阵。CV_32F表示每个元素的值的类型为32位浮点数,C2表示通道数为2,Scalar(1,3)表示对矩阵每个元素都赋值为(1, 3),第一个通道中的值都是1,第二个通道中的值都是3.dst = Scalar(127, 0, 255)
上述代码中颜色转换过来就是这样的:
Mat对象使用-四个要点
输出图像的内存是自动分配的
使用OpenCV的C++接口,不需要考虑内存分配问题
赋值操作和拷贝构造函数只会复制头部分
使用clone与copyTo两个函数实现数据完全复制
绘制形状与文字
Point与Scalar
Point表示2D平面上一个点,其成员就是 x,y 坐标
Scalar表示四个元素的向量,表示 RGB 三个通道
代码
1 |
|
随机线条
- 本文作者: Tim
- 本文链接: https://zouchanglin.cn/2018/08/30/536300354.html
- 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 许可协议。转载请注明出处!