数字图像存储概述

数字图像存储时,我们存储的是图像每个像素点的数值,对应的是一个数字矩阵。

Mat 数据类型:

Mat的常见属性:

data  uchar型的指针。Mat类分为了两个部分:矩阵头和指向矩阵数据部分的指针,data就是指向矩阵数据的指针。

dims 矩阵的维度,例如5*6矩阵是二维矩阵,则dims=2,三维矩阵dims=3.

rows 矩阵的行数

cols 矩阵的列数

size 矩阵的大小,size(cols,rows),如果矩阵的维数大于2,则是size(-1,-1)

channels 矩阵元素拥有的通道数,例如常见的彩色图像,每一个像素由RGB三部分组成,则channels = 3

type 表示了矩阵中元素的类型以及矩阵的通道个数,它是一系列的预定义的常量,其命名规则为CV_(位数)+(数据类型)+(通道数);具体的有以下值:

CV_8UC1    CV_8UC2    CV_8UC3    CV_8UC4

CV_8SC1    CV_8SC2    CV_8SC3    CV_8SC4

CV_16UC1    CV_16UC2    CV_16UC3    CV_16UC4

CV_16SC1    CV_16SC2    CV_16SC3    CV_16SC4

CV_32SC1    CV_32SC2    CV_32SC3    CV_32SC4

CV_32FC1    CV_32FC2    CV_32FC3    CV_32FC4

CV_64FC1    CV_64FC2    CV_64FC3    CV_64FC4

这里U(unsigned integer)表示的是无符号整数,S(signed integer)是有符号整数,F(float)是浮点数。

例如:CV_16UC2,表示的是元素类型是一个16位的无符号整数,通道为2.

C1,C2,C3,C4则表示通道是1,2,3,4

type一般是在创建Mat对象时设定,如果要取得Mat的元素类型,则无需使用type,使用下面的depth

#defineCV_8U 0   #defineCV_8S 1   #defineCV_16U 2   #defineCV_16S 3   #defineCV_32S 4   #defineCV_32F 5   #defineCV_64F 6   #defineCV_USRTYPE1 7

depth

矩阵中元素的一个通道的数据类型,这个值和type是相关的。例如 type为 CV_16SC2,一个2通道的16位的有符号整数。那么,depth则是CV_16S。depth也是一系列的预定义值,

将type的预定义值去掉通道信息就是depth值:

CV_8U CV_8S CV_16U CV_16S CV_32S CV_32F CV_64F

elemSize

矩阵一个元素占用的字节数,例如:type是CV_16SC3,那么elemSize = 3 * 16 / 8 = 6 bytes

elemSize1

矩阵元素一个通道占用的字节数,例如:type是CV_16CS3,那么elemSize1 = 16  / 8 = 2 bytes = elemSize / channels

Mat的存储:

OpenCV1基于C接口定义的图像存储格式IplImage*,直接暴露内存,如果忘记释放内存,就会造成内存泄漏。

从OpenCV2开始,开始使用Mat类存储图像,具有以下优势:

(1)图像的内存分配和释放由Mat类自动管理

(2)Mat类由两部分数据组成:矩阵头(包含矩阵尺寸、存储方法、存储地址等)和一个指向存储所有像素值的矩阵(根据所选存储方法的不同,矩阵可以是不同的维数)的指针。Mat在进行赋值和拷贝时,只复制矩阵头,而不复制矩阵,提高效率。如果矩阵属于多个Mat对象,则通过引用计数来判断,当最后一个使用它的对象,则负责释放矩阵。

(3)可以使用clone和copyTo函数,不仅复制矩阵头还复制矩阵。

Mat创建

1、使用Mat构造函数

Mat test(2,2,CV_8UC3,Scalar(0,0,255));

2、使用Mat构造函数2

int sizes[3] = {2,2,2};

Mat test(3,sizes,CV_8UC3,Scalar::all(0));

3、为已存在的IplImage指针创建信息头

IplImage* img = cvLoadImage("1.jpg",1);

Mat test(img);

4、利用create函数

Mat test;

test.create(4,4,CV_8UC2);

5、采用Matlab形式的初始化方式

(1)Mat me = Mat::eye(4,4,CV_64F);

(2)Mat mo = Mat::ones(2,2,CV_32F);

(3)Mat mz = Mat::zeros(3,3,CV_8UC1);

注:元素类型,即CV_[位数][带符号与否][类型前缀]C[通道数]

Mat中相关成员的意义:

1、data

Mat对象中的一个指针,指向存放矩阵数据的内存(uchar* data)

2、dims

矩阵的维度,3*4的矩阵维度为2维,3*4*5的矩阵维度为3维

3、channels

矩阵通道,矩阵中的每一个矩阵元素拥有的值的个数,比如说 3 * 4 矩阵中一共 12 个元素,如果每个元素有三个值,那么就说这个矩阵是 3 通道的,即 channels = 3。常见的是一张彩色图片有红、绿、蓝三个通道。

4、depth

深度,即每一个像素的位数,也就是每个通道的位数。在opencv的Mat.depth()中得到的是一个0 – 6的数字,分别代表不同的位数:enum { CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6 },可见 0和1都代表8位, 2和3都代表16位,4和5代表32位,6代表64位。

5、elemSize

矩阵中每个元素的大小,每个元素包含channels个通道。如果Mat中的数据的数据类型是CV_8U那么elemSize = 1;是CV_8UC3那么elemSize = 3,是CV_16UC2那么elemSize = 4。

6、elemSize1

矩阵中每个元素通道的大小,即elemSize/channels,也就是depth对应的位数。

7、step

是一个数组,定义了矩阵的布局,参考下图,下图是一个4*3的图片,假设通道数为3,那么step[0] ==4*3,step[1]==3


图1



图2

注:对于三维来说,第一维是面的大小,第二维是行的大小,第三维是元素的大小,step0是第一维

8、step1

step1也是一个数组,为step/elemSize1,若矩阵有n维,则step1[n-1] = channels。

9、type

矩阵元素的类型,即创建Mat时传递的类型,例如CV_8UC3、CV_16UC2等。

你可能感兴趣的:(数字图像存储概述)