图像在计算机中就是一堆点的数值,按顺序存储构成矩阵,opencv提供了一个 Mat 类来管理图像矩阵。
Mat类由两部分组成:
- 矩阵头:包含矩阵尺寸,存储方法,存储地址等信息。
- 图像矩阵指针:指向存储所有像素值的矩阵的指针。
为什么不直接在Mat中直接存储图像矩阵?
因为opencv处理对象时图片和视频,数据量都比较大,所以opencv采取的方法时,只在内存中保持一份图像矩阵,Mat类中只保持一个指向该内存的指针,达到图像矩阵共享的目的,节省存储资源的消耗。
另外,在做处理时很多方法牵涉到Mat对象复制操作,,对图像矩阵的操作都是比较重量级的,如果Mat对象中持有图像矩阵,那复制操作处理的数据就会很大,耗时很长,影响算法性能。采用持有矩阵头+图像矩阵指针的方式,在复制时,只需要复制矩阵头和指针即可,效率很高。
需要注意的时,多个Mat对象指向同一个图像矩阵时,某个Mat对象对图像矩阵的操作也会影响其他Mat对象。
图像矩阵什么时候被释放?
opencv采用引用计数的方式管理图像矩阵的释放,即每当新的Mat对象指向图像矩阵时,矩阵的计数器就会增加,Mat对象不再指向该矩阵时,矩阵的计数器就减少,当计数器达到零时,矩阵就会被释放。
如何存储图像像素值
如何存储图像像素值涉及两个方面:颜色空间、使用的数据类型。
- 颜色空间:对一个给定的颜色,如何组合颜色元素以对该颜色进行编码。
- 灰度空间:最简单的颜色空间,只处理黑色和白色,对它们进行组合可以产生不同程度的灰色;
- 彩色图像颜色空间:把颜色分成三个或者四个基元素,通过组合基元素可以产生所有的颜色。
- RGB:是最常用的一种颜色空间,基色是红色、绿色和蓝色,有时为了表示透明颜色也会加入第四个元素 alpha (A)。
- HSV和HLS:把颜色分解成色调、饱和度和亮度/明度。这是描述颜色更自然的方式,比如可以通过抛弃最后一个元素,使算法对输入图像的光照条件不敏感。
- YCrCb:JPEG图像格式中广泛使用。
- CIE Lab*是一种在感知上均匀的颜色空间,它适合用来度量两个颜色之间的距离。
- 数据类型:颜色元素的数据类型,决定控制颜色显示的精度。最小的数据类型是 char ,占一个字节或者8位,可以是有符号型(0到255之间)或无符号型(-127到+127之间)。尽管使用三个 char 型元素已经可以表示1600万种可能的颜色(使用RGB颜色空间),但若使用float(4字节,32位)或double(8字节,64位)则能给出更加精细的颜色分辨能力。但同时也要切记增加元素的尺寸也会增加了图像所占的内存空间。
Mat对象创建
opencv提供了很多Mat对象的创建方法,可以控制图像矩阵的维度、存储元素的数据类型和通道数、初始值。
- 维度:二维时直接传入行列数;多维时,传入维度数、个维度尺寸组成的数据。
- 数据类型:CV_(每个项目的位数)(有符号或无符号)(类型前缀)(通道数)。
- 初始值:初始元素值结构体,用来指定元素每个通道的值。
//4行 3列 8位无符号Char型 3通道 元素通道默认值为(0,0,255)
Mat mat = new Mat(4, 3, CvType.CV_8UC3, new Scalar(0, 0, 255));
注意:opencv的java sdk里面好像不支持创建多维(大于2维)Mat,所以有相关需求的还是采用jni的方式直接调用opencv的C/C++方法。
其他还有很多灵活方便的Mat创建方法,这里不再赘述,请参考官方文档
网友评论