if you pass on an already existing Mat object, which has already allocated the required space for the matrix, this will be reused.
The idea is that each Mat object has its own header, however the matrix may be shared between two instance of them by having their matrix pointers point to the same address. Moreover, the copy operators will only copy the headers and the pointer to the large matrix, not the data itself.
出于效率考虑,复制Mat对象只是赋值Mat 头指针 —— 通过引用计数器来实现 —— 最后使用的对象负责清空Mat内存
Mat A, C; // creates just the header parts A = imread(argv[1], CV_LOAD_IMAGE_COLOR); // here we‘ll know the method used (allocate matrix) Mat B(A); // Use the copy constructor C = A; // Assignment operator
ABC 指向同一块内存地址,只是各个Mat头不同,所以对其中一个进行更改也会在在其他对象中显现
可以使用Mat头指向图像中的一块子区域,ROI
create a region of interest (ROI) in an image you just create a new header with the new boundaries:
Mat D(A,Rect(10,10,100,100));// using a rectangle
Mat E= A(Range::all(),Range(1,3)); // using row and column boundaries
Creating a Mat object explicity
for debugging purposes it’s much more convenient to see the actual values. You can do this using the << operator of Mat. Be aware that this only works for two dimensional matrices. —— 注意,只适用于二维矩阵
Mat M(2,2, CV_8UC3, Scalar(0,0,255)); cout << "M = " << endl << " " << M << endl << endl;The Scalar is four element short vector. Specify this and you can initialize all matrix points with a custom value.
int sz[3] = {2,2,2}; Mat L(3,sz, CV_8UC(1), Scalar::all(0));使用C++数组来创建 一个多维数组Specify its dimension, then pass a pointer containing the size for each dimension and the rest remains the same.
Create a header for an already existing IplImage pointer:IplImage* img = cvLoadImage("greatwave.png", 1); Mat mtx(img); // convert IplImage* –> Mat
MATLAB style initializer: —— Matlab Style ,太残暴了Mat E = Mat::eye(4, 4, CV_64F); cout << "E = " << endl << " " << E << endl << endl; Mat O = Mat::ones(2, 2, CV_32F); cout << "O = " << endl << " " << O << endl << endl; Mat Z = Mat::zeros(3,3, CV_8UC1); cout << "Z = " << endl << " " << Z << endl << endl;
For small matrices you may use comma separated initializers:
Mat C = (Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0); cout << "C = " << endl << " " << C << endl << endl;
Create a new header for an existing Mat object and clone() or copyTo() it.
Mat RowClone = C.row(1).clone(); cout << "RowClone = " << endl << " " << RowClone << endl << endl;
You can fill out a matrix with random values using the randu() function. You need to give the lower and upper value for the random values:Mat R = Mat(3, 2, CV_8UC3); randu(R, Scalar::all(0), Scalar::all(255));
输出格式
In the above examples you could see the default formatting option. OpenCV, however, allows you to format your matrix output:
- Default
cout << "R (default) = " << endl << R << endl << endl;- Python
cout << "R (python) = " << endl << format(R,"python") << endl << endl;- Comma separated values (CSV)
cout << "R (csv) = " << endl << format(R,"csv" ) << endl << endl;- Numpy
cout << "R (numpy) = " << endl << format(R,"numpy" ) << endl << endl;- C
cout << "R (c) = " << endl << format(R,"C" ) << endl << endl;