As a data type in OpenCV, Mat is often used to store images, and the mat type eliminates manual allocation and deallocation of the Iplimgae type, and automatically allocates releases instead. The Mat class consists of two pieces of data: One is the matrix header (including the matrix size, storage method, storage address, etc.). ), and the other is a pointer to the matrix that stores the pixel values.
There are two types of mat duplication in OpenCV,
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
mat d (a (1010 100100) ); //using a Rectanglemat e = A (range::all (), range< Span class= "P" > (1,3//using row and column boundaries
The above class simply creates a new matrix header, which, in common with the pixel matrix a,b,c, modifies the pixel values of one of the items, and the other changes, which can be understood as providing different ways to read the same underlying data. The benefit of doing so is to reduce the computational cost.
If you want to manipulate only a subset of the pixels, you can create a read section of the header matrix
Of course, OpenCV also provides a method for deep replication
Mat F = a.clone (); Mat G; A.copyto (G);
Creation of the Mat
Cv::mat::mat Constructor:
Mat M (2,2, CV_8UC3, Scalar (0,0,255)); cout << "m =" << Endl << "" << M << endl << Endl;
Cv::mat::create function:
M.create (bis, CV_8UC (2)); cout << "m =" << Endl << "" << M << endl << Endl;
MATLAB style Initializer:cv::mat::zeros, Cv::mat::ones, Cv::mat::eye
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 some small kernel you can customize the following:
Mat C = (mat_<double> (3,3) << 0,-1, 0,-1, 5,-1, 0,-1, 0); cout << "c =" << Endl << "" << C << endl << Endl;
When the image is analyzed and manipulated, it is often necessary to traverse or manipulate the pixel values of an area. Summed up a bit more commonly used in the following methods.
1. Use PTR pointers to access mat pixels
for (int j = 1; j < myimage.rows-1; ++j) { const uchar* previous = myimage.ptr<uchar> (j-1); Const uchar* Current = myimage.ptr<uchar> (J ); Const uchar* Next = myimage.ptr<uchar> (j + 1); uchar* output = result.ptr<uchar> (j); for (int i = nchannels; i < nchannels * (myimage.cols-1); ++i) { *output++ = saturate_cast<uchar> (5 * cu) Rrent[i] -current[i-nchannels]-current[i + nchannels]-previous[i]-next[i]);} }
2. using the Mat::at function
int main () { Mat img = imread ("lena.jpg"); Imshow ("Lena Original", IMG); if (Img.channel () > 1) {for (int row = 0, row < img.rows; row++) {for (int col = 0; col < img.co ls col++) { /* Note that the Mat::at function is a template function that needs to indicate the type of the parameter, because this is a graph with a red-blue-green three-channel, so its parameter type can pass a vec3b, which is a Vec (a vector that holds 3 Uchar data) ). The index overload is provided here, [2] is the return of the third channel, here is the Red channel, the first channel (Blue) returns with [0] * /if (img.at<vec3b> (row, col) [2] > 128) C12/>img.at<vec3b> (row, col) = vec3b (255, 255, 255); }}} else {for (int row = 0, row < img.rows; row++) {for (int col = 0; col < img.cols; col++) { if (img.at<vec3b> (row, col) >) img.at<vec3b> (row, col) = 255; }} } Imshow ("Lena Modified", IMG); Cvwaitkey (); return 0;}
Mat type data manipulation and traversal in OPENCV