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;