OpenCV数据载入、显示与保存

一、图像存储器

OpenCV提供了一个Mat类用于存储矩阵数据。Mat类用来保存矩阵类型的数据信息,包括向量、矩阵、灰度或彩色图像等数据。

Mat类分为矩阵头和指向存储数据的矩阵指针的两部分。矩阵头中包含矩阵的尺寸、存储方法、地址和引用次数。矩阵头的大小是一个常数,不随着矩阵尺寸的大小而改变。

创建Mat类:

Mat a;    //创建一个名为a的矩阵头
a = imread("j2.png");//向a中赋值图像数据,矩阵指针指向像素数据
Mat b = a;    //复制矩阵头,并命名为b

从上面的程序可以看出,虽然a和b有各自的矩阵头,但是其矩阵指针指向的矩阵数据是相同的,通过任意一个矩阵头修改矩阵中的数据,另一个矩阵头指向的数据也会随之发生改变。但是,当删除a变量时,b变量并不会指向一个空数据,因为矩阵头中引用次数标记了引用某个矩阵数据的次数,只有当矩阵数据引用次数为0时才会释放矩阵数据。

Mat类可以存储的数据类型包括:double、float、uchar、unsigned char以及自定义的模板等。

声明一个指定类型的Mat类:

Mat A = Mat_<double>(3,3);//创建一个3*3的矩阵用于存放double类型数据

opencv中的数据类型:

数据类型 具体类型
CV_8U 8位无符号整数
CV_8S 8位符号整数
CV_16U 16位无符号整数
CV_16S 16位符号整数
CV_32S 32位符号整数
CV_32F 32位浮点整数
CV_64F 64位浮点整数

在Opencv中,如果用8位无符号整数存储16位图像,会造成严重的图像颜色失真或造成数据的错误。对于图像来说,只有数据类型是不够的,还需要定义图像数据的通道数,例如灰度图像数据是单通道数据,彩色图像数据是3通道或者4通道数据。因此,opencv定义了通道数标识,C1、C2、C3、C4分别表示单通道、双通道、三通道和四通道。

Mat a(640,480,CV_8UC3);//创建一个640*480的3通道矩阵用于存储彩色图像
Mat b(3,3,CV_8UC1);//创建一个3*3的8位无符号整数的单通道矩阵

1、Mat的赋值

(1)构造时赋值

这种方法是在构造的同时进行赋值,需要注意的是赋值的位数要等于通道数

Mat (int rows
     int cols
     int type
     const Scalar & s 
)
//rows:矩阵的行数
//cols:矩阵的列数
//type:存储数据的类型
//s:给矩阵中每个像素赋值的参考变量

Mat a(2,2,CV_8UC3,Scalar(0,0,255));//创建一个3通道矩阵,每个像素都是0,0,255

(2)、枚举法赋值

这种赋值方式是将矩阵中的所有元素一一列举,并用数据流的形式赋值给Mat类。

Mat a =(Mat_<int>(3,3) << 1,2,3,4,5,6,7,8,9);

(3)、利用数组赋值

float a[8] = {5,6,7,8,1,2,3,4};
Mat b = Mat b = Mat(2,2,CV_32FC2,a);

2、Mat类支持的运算

Mat类变量支持矩阵的加减乘除运算,也可以实现Mat类矩阵的內积和对应位乘法。

需要注意的是,当两个Mat类变量进行加减运算时,必须保证两个矩阵中的数据类型是相同的。

3、Mat类元素的读取

Mat类矩阵在计算机中存储的方式:先存储第一个元素的每个通道的数据,之后再存储第二个元素每个通道的数据。每一行的元素都按照这种方式进行存储。

Mat类矩阵常用的属性:

属性 作用
cols 矩阵的列数
rows 矩阵的行数
step 以字节为单位的矩阵的有效宽度
elemSize() 每个元素的字节数
total() 矩阵中元素的个数
channels() 矩阵的通道数

(1)通过at方法读取Mat类矩阵的元素

Mat类数据的读取分为单通道和多通道。

单通道:

Mat a = (Mat_<uchar>(3,3) << 1,2,3,4,5,6,7,8,9);
int value = (int)a.at<uchar>(0,0);

通过at方法读取元素需要在后面跟上“<数据类型>”,如果此处的数据类型与矩阵的数据类型不同,就会出现因数据类型不匹配而产生的报错信息。该方法以坐标的形式给出需要读取的元素坐标(行,列)。

多通道:

在opencv中,针对三通道矩阵,定义了Vec3b、Vec3s、Vec3w、Vec3d、Vec3f、Vec3i共六种类型用于表示同一个元素的3个通道数据;定义中的数字表示通道的个数,最后一位是数据类型的缩写。 b是uchar类型的缩写,s是short类型的缩写,w是ushort类型的缩写,d是double类型的缩写,f是float类型的缩写,i是int 类型的缩写。相应的二通道和四通道的定义也是类似的。

Mat b(3,4,CV_8UC3,Scalar(0,0,1));
Vec3b vc3 = b.at<Vec3b>(0,0);
int first = (int)vc3.val[0];
int second = (int)vc3.val[1];
int third = (int)vc3.val[2];

(2)通过指针ptr读取Mat类矩阵中的元素</

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值