Mat类由两个数据部分组成:矩阵头(包含矩阵尺寸,方法,地址等信息)和一个指向存储所有像素值的指针。矩阵头的尺寸是常数值,但矩阵本身的尺寸会依图像的大小而不同。因此,在程序中传递、创建、拷贝图像时,开销由矩阵,而不是信息头决定。由于图像处理算法的计算量很大,在使用Mat类时,尽量采用浅拷贝,避免深拷贝图像数据,以提高程序的运行效率。
一、Mat对象的创建
1.构造函数
(1)创建单通道图像
Mat myMat(256, 256, CV_8UC1, Scalar(255));
(2)创建三通道图像
Mat myMat(256, 256, CV_8UC3, Scalar(0, 0, 255));
(3)多维数组的创建与使用
int sz[3] = { 16,256,256 }; //定义一维数组,保存多维数组的维度和尺寸
Mat L(3, sz, CV_8UC(1), Scalar(0)); //定义维度为3,尺寸为16X256X256的数组,并初始化为0
Mat myMat(256, 256, CV_8UC(1), Scalar(0));//定义二维矩阵,并初始化为0
//对三维数组的第16个二维子矩阵赋值
for (int i = 15; i <16; i++)
{
for (int j = 0; j < 256; j++)
{
uchar* p = L.ptr<uchar>(i,j);
for (int k = 0; k < 256; k++)
{
p[k] = 255;
}
}
}
//将三维数组的第16个二维子矩阵赋值给二维矩阵
for (int i = 0; i < 256; i++)
{
uchar* pImg = myMat.ptr<uchar>(i);
for (int j = 0; j < 256; j++)
{
pImg[j] = L.ptr<uchar>(15,i)[j];
}
}
imshow("原图", myMat); //显示二维矩阵
2.初始化创建
Mat E = Mat::eye(4, 4, CV_64F); //初始化为对角阵
Mat O = Mat::ones(2, 2, CV_32F);//所有元素初始化为1
Mat Z = Mat::zeros(3,3, CV_8UC1);//所有元素初始化为0
3.Create函数
Mat myMat;
myMat.create(3, 3, CV_8UC3);//用create函数创建Mat对象时,没有提供初始化方法
4.拷贝构造
(1)浅拷贝
Mat img1(img) ;//仅是创建了Mat的头部分,img1与img共享数据区
Mat img1 = img;//仅是创建了Mat的头部分,img1与img共享数据区
ROI创建Mat对象也属于浅拷贝,具体使用方法如下:
Mat img(256, 256, CV_8UC3, Scalar(0,0,255));
Mat roiImg(img, Rect(0, 0,128, 128)); //采用Rect生成ROI
//Mat roiImg = img(Range(0,128),Range(0,128)); //采用Range生成ROI
Mat img1(128, 128, CV_8UC3, Scalar(255, 0, 0));
img1.copyTo(roiImg);
imshow("ROI操作", img);
waitKey(0);
(2)深拷贝
Mat img(256, 256, CV_8UC3, Scalar(0,0,255));
Mat img1;
img.copyTo(img1); //采用copyTo方法进行深拷贝
//Mat img1 = img.clone(); //采用clone方法进行深拷贝
imshow("深拷贝", img1);
waitKey(0);
二、采用Mat类读取、修改、保存和显示图像
#include "stdafx.h"
#include <opencv.hpp>
using namespace cv;
int main()
{
Mat image, gray_image;
image = imread("D:\\Downloads\\Pictures\\lena.jpg", IMREAD_COLOR);//读取图像,OpenCV4类型定义与以前版本不同
cvtColor(image, gray_image, COLOR_BGR2GRAY);//转换图像,OpenCV4类型定义与以前版本不同
imwrite("D:\\Downloads\\Pictures\\lenaGray.jpg", gray_image);//储存图像
imshow("Original image", image); //显示原始图像
imshow("Gray image", gray_image);//显示灰度图像
waitKey(0);//采用imshow显示图像时,必须使用waitKey才能保证图像正常显示
return 0;
}
三、Mat类的控制台显示
#include "stdafx.h"
#include <opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat R(3, 2, CV_8UC3); //定义Mat对象
randu(R, Scalar::all(0), Scalar::all(255)); //用伪随机数给Mat对象赋值
cout << "R=" << endl << R << endl; //将Mat对象在控制台输出
system("pause");
return 0;
}