Mat是一个类,有两个数据部分组成,矩阵头(包含矩阵尺寸,存储方法,存储地址等信息)和
一个指向所有存储像素值的矩阵(根据所选存储方法的不同矩阵可以是不同的维数)的指针。
矩阵头的尺寸是常数值,但矩阵本身的尺寸会依照图像的不同而不同,通常比矩阵头的尺寸大
数个数量级。因此,当在程序中创建图像并拷贝时,大的开销是由矩阵造成的,而不是信息头。
OpenCV使用引用计数机制,其思路是让每个Mat对象有自己的信息头,但共享同一个矩阵。这
通过让矩阵指针指向同一个地址而实现。而拷贝构造函数只拷贝信息头和矩阵指针,而不拷贝矩阵。
Mat A, C; //创建信息头部分 A = imread(argv[1], CV_LOAD_IMAGE_COLOR); //为矩阵开辟内存 Mat B; //使用拷贝构造函数 C = A; //赋值运算符
拷贝矩阵本身(不只是信息头和矩阵地址),使用函数clone()或者copyTo()
要点:
1.OpenCV函数中输出图像的内存分配是自动完成的
2.使用OpenCV的C++接口时不需要考虑内存释放问题
3.赋值运算符可拷贝构造函数只拷贝信息头
4.使用函数clone()或copyTo()来拷贝一副图像的矩阵
存储方法:
需要指定颜色空间和数据类型,RGB颜色空间是最常见的颜色空间
显示地创建一个Mat对象
Mat()构造函数:
Mat m(2, 2, CV_8UC3, Scalar(0, 0, 255)); cout << "m=" << endl << m << endl
对于二维多通道图像,首先要定义其尺寸,即行数和列数
然后,需要制定元素的存储类型以及每个点的通道数,为此有下面规则定义
CV_[The number of bits per itemk][Sigued of Unsigned][Type prefix][The channel numger]
Eg. CV_8UC3 8位的unsigned char型,每个像素由3个元素组成3条通道
Scalar 是个short型的vector,指定这个能够使用指定的定制化值来初始化矩阵
如果需要更多的通道数,可以使用大写的宏并把通道数放入小括号中
创建一个超过二维的的矩阵,指定维数,然后传递一个指向一个数组的指针,这个数组包含每个维度的尺寸
为已存在lpllmage指针创建信息头
IplImage* img = cvLoadImage("greatwave.png", 1); Mat mtx(img); // convert IplImage* -> Mat
create()函数:不能为矩阵设置初始值,只是在改变尺寸时重新为矩阵开辟内存。
m.create(4, 4, CV_8UC(2)); cout << "m=" << endl << m << endl;
初始化:zeros(),eye().ones()
Mat E = Mat::eye(4, 4, CV_64F); cout << "E=" << endl << E << endl; Mat Z = Mat::zeros(4, 4, CV_64F); cout << "Z=" << endl << Z << endl; Mat O = Mat::ones(4, 4, CV_64F); cout << "O=" << endl << O << endl;
对于小矩阵可以使用逗号分隔的初始化函数
Mat C = (Mat_<int>(3, 3) << 1, 0, -1, 2, 1, 0, 3, 2, 1); cout << "C=" << endl << C << endl;
格式化打印
函数randu():对一个矩阵实行随机数填充,需要指定随机数的上届和下届
Mat R = Mat(3, 2, CV_8UC3); randu(R, Scalar::all(0), Scalar::all(255)); cout << "R=" << endl << R << endl;
输出:
默认方式
cout << "R=" << endl << R << endl;
读取,修改和保存图像
图像读取:imread()
imread(imageName,CV_LOAD_IMAGE_COLOR)
图像颜色空间的转换cvtColor
cvtColor(image,gray_image,CV_BGR2GRAY)
图像保存至硬盘(using imwrite)
imwrite("C:... .jpg",gray_name)