I remember the beginning of contact with OPENCV is because an algorithm inside a 2-dimensional dynamic array, then look at the core this part is also a cursory, with the increase in use, the structure of the mat more and more like, also feel the need to warm so that the new, so this time to see the mat.
The biggest advantage of mat and STL very similar, are the memory of dynamic management, do not need to manually manage the memory, for some large-scale development, sometimes invested in lpimage memory management time even more than the time to focus on the implementation of the algorithm, this is obviously inappropriate. In addition to some embedded occasions must use the C language, I strongly like you at any time recommend Mat.
Mat This class has two parts of data. One is the matrix header, this part of the size is fixed, including the size of the matrix, the way it is stored, the address of the matrix storage, and so on. The other part is a pointer to the matrix that contains the pixel values.
[CPP] view plain copy 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
It is important to note that copy such operations only copy the matrix header and that pointer, not the matrix itself, which means that the data pointers of the two matrices point to the same address, which requires special attention from the developer. For example, the above program, A, B, C point to the same piece of data, their header is different, but for a operation also affects the results of B, C. Just raised the issue of automatic memory release, then when I no longer use a when the memory freed, then the operation of B and C is not very dangerous. Don't worry, the great god of OpenCV for we have already considered this question, is when the last mat no longer uses the time only then releases the memory, we will be relieved to use on the line.
If you want to create a mat that does not affect each other, it is a true copy operation that requires the use of the function clone () or CopyTo ().
When it comes to data storage, this has always been a matter of concern,mat_<uchar> corresponds to the cv_8u,mat_<uchar> corresponds to the cv_8u,mat_<char> corresponding to the Cv_8s,mat_ <int> corresponds to the cv_32s,mat_<float> corresponding to the cv_32f,mat_<double> corresponds to the cv_64f, the corresponding data depth is as follows:
cv_8u-8-bit unsigned integers (0..255)
cv_8s-8-bit signed integers ( -128..127)
cv_16u-16-bit unsigned integers (0..65535)
cv_16s-16-bit signed integers ( -32768..32767)
cv_32s-32-bit signed integers ( -2147483648..2147483647)
cv_32f-32-bitfloating-point Numbers (-flt_max. Flt_max, INF, NAN)
cv_64f-64-bitfloating-point Numbers (-dbl_max. Dbl_max, INF, NAN)
It is also important to note that many OPENCV functions support data depths of only 8-bit and 32-bit, so use less cv_64f, but the VS compiler will automatically turn the float data into a double type, which is not very cool.
Another problem to be aware of is that the stream operator << The mat operation is limited to the 2-dimensional case of the mat.
It is also necessary to say that the store of mat is stored on a row-by-line basis.
Besides, there are two ways to create a Mat: 1. Call Create (row, column, type) 2.Mat (row, column, type (value)). For example:
[CPP] view plain copy//Make a 7x7 complex matrix filled with 1+3j. Mat M (7,7,cv_32fc2,scalar (1,3)); And now turn M to a 100x60 15-channel 8-bit matrix. The old content would be deallocated m.create (100,60,CV_8UC (15));
If you want to create a higher-dimensional matrix, write the following way
[CPP] view plain copy//Create a 100x100x100 8-bit array int sz[] = {100, 100, 100}; Mat Bigcube (3, SZ, cv_8u, Scalar::all (0));
For a row or column operation of a matrix, the method is as follows: (note to create a new mat for column operations, I think it should be related to column address discontinuity) [CPP] view Plain copy//Add the 5-th row, multiplied by 3 t o the 3rd row m.row (3) = M.row (3) + M.row (5); Now copy the 7-th column to the 1-st column//m.col (1) = M.col (7); This won't work Mat M1 = M.col (1); M.col (7). CopyTo (M1);
The following things are more violent, for foreign data, such as you accept a picture from somewhere else, but it can not be the mat structure, and only a pointer to the data, see how the next code is how to deal with, focus Oh, pro
[CPP] view plain copy void Process_video_frame (const unsigned char* pixels, int width, int height, int step) {Mat img (height, width, cv_8uc3, pixels, step); Gaussianblur (IMG, IMG, Size (7,7), 1.5, 1.5); }
Pro, there is wood is very simple ...
There is also a way to initialize the data quickly, as follows:
[CPP] view plain copy double M[3][3] = {{A, B, C}, {D, E, F}, {g, H, i}}; Mat M = Mat (3, 3, cv_64f, M). INV ();
You can also convert the original iplimage format image directly to the mat structure using the mat (iplimage), or you can invoke functions such as zeros (), ones (), and Eye () as Matlab to initialize.
If you need to release the pointer and memory of the data in advance, you can call release ().
For data acquisition, of course, calling At<float> (3, 3) is the best format. Other methods I seldom try, I dare not introduce.
The last thing
to mention is the expression of the mat, which is also very much, subtraction, transpose and inverse, how I remember I introduced it before. That's not much to say ~