OpenCV2:Mat
1.Mat基础
在计算机内存中,数字图像是已矩阵的形式保存的。OpenCV2中,数据结构Mat是保存图像像素信息的矩阵,它主要包含两部分:矩阵头和一个指向像素数据的矩阵指针。矩阵头主要包含,矩阵尺寸、存储方法、存储地址和引用次数等。矩阵头的大小是一个常数,不会随着图像的大小而改变,但是保存图像像素数据的矩阵则会随着图像的大小而改变,通常数据量会很大,比矩阵头大几个数量级。这样,在图像复制和传递过程中,主要的开销是由存放图像像素的矩阵而引起的。因此,OpenCV使用了引用次数,当进行图像复制和传递时,不再复制整个Mat数据,而只是复制矩阵头和指向像素矩阵的指针。例如:123 | cv::Mat //创建矩阵头 a "f:\\psb.jpg" ); //读入图像 cv::Mat //复制 |
cv::Mat c = a.clone();
cv::Mat d ;
a.copyTo(d);
上面代码中的c,d各自拥有自己的矩阵,改变自己的矩阵数据不会相互影响。在使用Mat中,需要记住:
- OpenCV中的内存分配是自动完成的(不是特别指定的话)
- 使用OpenCV的C++ 接口时不需要考虑内存释放问题
- Mat的赋值运算和拷贝构造函数只会拷贝矩阵头,仍然共同同一个矩阵
- 如果要复制矩阵数据,可以使用clone和copyTo函数
2.Mat存储方法
Mat中矩阵的每个元素可以使用不同的数据类型,最小的数据类型是char,占用一个字节或者8位,可以是有符号的(0到255)或者是无符号的(-127到127)。在RGB颜色空间中,使用三个char类型可以表示1600万中颜色,但在图像处理的过程中有可能会使用到float或者double来表示图像的像素。Mat的创建
构造函数
cv::Mat img(2,2,CV_8UC3,cv::Scalar(0,0,255));上述代码创建了一个2行2列的矩阵,矩阵元素使用8位无符号char类型保存,具有3通道,每个像素的初始值是(0,0,255)
构造函数的前两个参数指定了矩阵的行和列
第三个参数指定矩阵元素的数据类型以及通道数,其指定规则如下:
CV_[The number of bits per item][Signed or Unsigned][TypePrefix]C[The channel number]四部分分别指定:元素的大小,是有符号还是无符号,数据类型以及通道数最后一个参数,Scalar是short型的vector,提供矩阵的初始化。
Create方法
该方法不能为矩阵设置初始值,只是在改变尺寸时为矩阵数据重新分配内存。使用方法:img.create(4,4,CV_8UC(2));创建了一个4行4列有2个通道的矩阵
MATLAB形式的初始化
cv::Mat e = cv::Mat::eye(4,4,CV_64F);Mat e是4行4列的对角矩阵Mat z是2行2列的单位矩阵Mat o是3行3列的零矩阵
cv::Mat z = cv::Mat::ones(2,2,CV_32F);
cv::Mat o = cv::Mat::zeros(3,3,CV_8UC1);
小矩阵的初始化
对于小矩阵可以使用逗号分割的初始化函数Mat c =(Mat_<double>(3,3)<<1,2,3,0,-1,0,4,5,6);在对图像进行模板运算时,定义模板使用这种方法是很方便的。
3.Mat的输入输出
使用imread函数,向Mat对象中写入一个图像。
a = cv::imread("f:\\psb.jpg");//读入图像imread的原型如下
cv::Mat imread(const string& filename,int flags=1)filename指定要读取图像的位置flags指定图像的颜色空间 flags > 0 3通道的彩色图像 flags = 0 灰度图像 flags < 0 不作改变
也可以有以下的枚举值CV_LOAD_IMAGE_ANYDEPTH、CV_LOAD_IMAGE_COLOR、CV_LOAD_IMAGE_GRAYSCALE
使用imwrite函数,将Mat对象保存到指定的文件中。
imwrite的函数原型如下:bool imwrite(const string& filename,InputArray img,constvector<int>& params=vector<int>())filename,指定的文件img 要保存的Mat对象params 用来指定图像的保存编码方式。使用filename的扩展名来指定图像的保存格式(.jpg .png .bmp),对于不同的图像保存类型,params是不同的值
- JPEG,params用来指定图像的质量(0到100),默认的是95. CV_IMWRITE_JPEG_QUALITY
- PNG,params用来指定图像的压缩级别(0到9),压缩级别越高图像占用的空间越小,保存图像所用的时间越久。默认值是3. CV_IMWRITE_PNG_COMPRESSION
- PPM,PGM,PBM,params是一个标记(0或者1),默认的是1.CV_IMWRITE_PXM_BINARY
void createAlphaMat(Mat &mat)
{
for(int i = 0 ; i < mat.rows ; i ++) {
for(int j = 0 ; j < mat.cols ; j ++) {
Vec4b &rgba = mat.at<Vec4b>(i,j);
rgba[0] = UCHAR_MAX ;
rgba[1] = saturate_cast<uchar>((float (mat.cols - j)) / ((float)mat.cols) * UCHAR_MAX);
rgba[2] = saturate_cast<uchar>((float (mat.rows - i)) / ((float)mat.rows) * UCHAR_MAX);
rgba[3] = saturate_cast<uchar>(0.5 * (rgba[1] + rgba[2]));
}
}
}
int main()
{
Mat mat(480,640,CV_8UC4);
createAlphaMat(mat);
vector<int> compression_params ;
compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
compression_params.push_back(9);
imwrite("alpha.png",mat,compression_params);
return 0;
}
4.Mat的显示
OpenCV提供了用以窗口的形式显示图片的方法,代码如下:Mat img = imread("f:\psb.jpg");
const string name ="Hu";
namedWindow(name);
imshow(name,img);
waitKey();