01opencv---Mat

1,读取图片 Mat imread( const String& filename, int flags = IMREAD_COLOR ) 

Mat img = imread("dog.jpg");
cout << sizeof(img) << endl;

2,Mat成员变量

Mat类分为了两个部分:矩阵头(包括矩阵尺寸、存储方法、存储地址等)和指向矩阵数据部分的指针.

Mat img_copy = img; // 复制矩阵头
uchar* data = img.data; // uchar型的指针,data就是指向矩阵数据的指针
int dims = img.dims; //2
int rows = img.rows; //576  矩阵的行数
int cols = img.cols; //768  矩阵的列数
MatSize size = img.size; // 576 x 768
int channels = img.channels(); // 3,BGR三部分组成,则channels = 3
int type = img.type(); // 16,对应CV_8UC3。其中U:unsigned integer,S:signed integer,F:float
int depth = img.depth(); // 0,对应CV_8U,:矩阵中元素的一个通道的数据类型,这个值和type是相关的,将type的预定义值去掉通道信息就是depth值,
int elemSize = img.elemSize(); // 3,矩阵一个元素占用的字节数。CV_8UC3,那么eleSize=3*8/8=3 bytes
int elemSize1 = img.elemSize1(); // 1,矩阵元素一个通道占用的字节数。CV_8UC3,那么eleSize1=8/8=1 bytes = elemSize/channels
    
// step存储着各个维度占用的内存块的大小
// step的单位是byte,step1不是以byte作为单位,而是以elemSize1作为单位。elemSize1和step1实际上也很少用到
// 再次提醒,channel不计入维度,比如一个二维三通道图像,它是二维数组,而不是三维
int step = img.step; // 2304, step的数值与step[0]数值相同
int step0= img.step[0]; // 2304,代表一行元素占用内存大小,2304=768*3=cols*elemSize
int step1 = img.step[1]; // 3,代表一个元素占用内存大小, =elemSize

3,构建Mat

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

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

Mat A2 = (cv::Mat_<float>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
cout << A2 << endl;
Mat A3 = (Mat_<double>(3, 3) << 0, 1, 2, 1, 2, 3, 2, 3, 4);
cout << A3 << endl;

float K[3][3] = { 1, 0, 1, 0, 1, 1, 0, 0, 1 };
cv::Mat A4 = cv::Mat(3, 3, CV_32FC1, K);
cout << A4 << endl;

3.2通过OpenCV数据类型创建Mat类: Mat(int rows, int cols, int type) 

Mat a1(640, 640, CV_8UC3);
Mat a2(640, 640, CV_8UC1);
Mat a3(2, 2, CV_8UC3, Scalar(0, 0, 255));

 3.3 特殊矩阵 

cv::Mat Z = cv::Mat::zeros(3, 3, CV_64F); //相当于创建一张黑色的图,每个像素的每个通道都为0,Scalar(0,0,0)
cv::Mat F = cv::Mat::ones(2, 2, CV_64F);  // 相当于:Mat F = Mat(2, 2, CV_8UC3, 1);
cv::Mat Y = cv::Mat::eye(3, 3, CV_64F);

 4,拷贝和复制

4.1 浅拷贝赋值 

Mat src1 = imread("dog.jpg");
Mat dst1 = src1;

 4.2 深拷贝 clone() 

Mat src2 = imread("dog.jpg");
Mat dst2 = src2.clone();

 4.3 深拷贝 A.copyTo(B) 

Mat src3 = imread("dog.jpg");
Mat dst3;
src3.copyTo(dst3); // A.copyTo(B); B 与 A 矩阵一模一样,改变任何一个,互不影响

 4.4 掩膜操作  ??

 image_in.copyTo(image_out,mask);// 不仅把image_in这张图复制(copy to)到image_out上,且image_in对应mask中像素值为0的像素点都不会贴到image_out上 

Mat img1(300, 300, CV_32FC3, Scalar(0, 0, 1));
Mat img2(200, 200, CV_32FC3, Scalar(1, 0, 0));
Mat roi = img1(Rect(50, 50, 200, 200));
img2.copyTo(roi); //img2的类型变的大小跟roi一致,两者互不影响,另外,因为roi的地址=img1的,所以img1的200*200这一区域也会变成蓝色
imshow("img1", img1);
imshow("img2", img2);
imshow("roi", roi);
cv::waitKey(0);

 5,颜色空间转换函数 

// cvtColor(Mat src, Mat dst, int code)  code: COLOR_BGR2RGB, COLOR_RGB2BGR, COLOR_RGB2GRAY,COLOR_BGR2GRAY
// opencv默认的彩色图像的颜色空间是BGR, imshow()时的颜色空间也是BGR
Mat cvt_src = imread("dog.jpg");
imshow("cvt_src", cvt_src);
cv::waitKey(0);

Mat cvt_dst;
cvtColor(cvt_src, cvt_dst, COLOR_BGR2RGB);
imshow("cvt_dst", cvt_dst); //此时颜色空间是RGB,显示的图片颜色是不对的
cv::waitKey(0);

Mat cvt_dst2;
cvtColor(cvt_dst, cvt_dst2, COLOR_RGB2BGR);
imshow("cvt_dst2", cvt_dst2); //此时颜色空间是BGR,正常显示
cv::waitKey(0);

 6,类型转换:void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const;

 

posted @ 2022-05-24 17:15  cheng4632  阅读(25)  评论(0编辑  收藏  举报