Learning OpenCV Everyone will encounter an object called Mat, this object is very magical, support a variety of operations. Many beginners are so dizzy brain swelling, its various usage too much too miscellaneous, engage beginners overwhelmed, feel powerless, nowhere to start feeling. Here we first want to radical reform, from the reason of the Mat object, and then the mat various magic usage one by one combing summary.
Mat Object Origin:
When OpenCV 1.0 was released without a Mat object, it was a C-style data structure iplimage to represent in-memory image objects, but OpenCV developers created a lot of iplimage data structures when analyzing and computing complex image processing algorithms. Occasionally finally forget to release memory, so the algorithm has a memory leak, causing developers to waste a lot of effort to find this error, this is not related to the image processing algorithm, but it is plagued by many OPENCV developers. Intel found that its own library was so slag, the masses are not satisfied, decided to start from OPENCV 2.0 use a new Memory object mat to represent in-memory image objects. It is a C + +-style data structure that automates memory allocation and recycling, so that OPENCV developers no longer have to worry about memory leaks due to the use of OPENCV image object data structures. However, some developers still persist in using Iplimage as an object, and Intel will allow the Iplimage object to continue to exist and provide a constructor that converts the Iplimage object into a Mat object, which is every opportunity as an open source SDK.
Mat Object Constructors
Since OpenCV2.0 introduced the Mat object, when you read an image through the Imread function, the developer does not need to allocate memory and then release it, because the OPENCV framework will help you do these things and automatically manage mat-related memory, so how to create a mat object in OpenCV, the following methods is one of your choices:
Method One:
By reading an image, you can convert directly to a Mat object:
Mat image = Imread ("test.jpg");
where the Imread () method needs to pass in a string-type value, typically an image file path. Shown below:
Method Two:
Create a Mat object using the parameterless constructor
Mat image = Mat (); Image.create (4, 4, CV_8UC3);
This moment represents creating a 4x4-sized block of pixels, each of which is a three-channel number of bits per channel that are 8 bits, one byte. 8 of the above CV_8UC3 means 8 bits, UC represents UCHAR type, 3 represents three channels. The print display is like this:
Method Three:
Create a Mat object using the row, column, and type constructors with this three parameter
Mat m = Mat (4, 4, CV_8UC3)
Means to create a block of pixels that are the same as the method two, and the print display is consistent with the method two content:
Method Four:
Create Mat objects using constructors of four parameters of row, column, type, scalar vector
Mat m = Mat (4, 4, CV_8UC3, Scalar (0, 255, 255);
It also means creating a 4x4 block of pixels, and the only difference is that the color is not the default but we specify a three-channel color value vector scalar (0, 255, 255). Where the number of scalar vectors is always equal to the number of channels, printed as shown below
Method Five:
Create a Mat object using a constructor of size, type two parameters
Mat m = Mat (Size (4, 4), CV_8UC3);
Similarly create a 4x4 block of 8-bit three-channel pixels per channel, printed as shown below:
Method Six:
Create Mat objects using constructors of size, type, scalar vector three parameters
Mat m = Mat (Size (4, 4), CV_8UC3, Scalar (255, 0, 0));
Similarly create a 4x4 block of 8-bit three-channel pixels per channel, printed as shown below:
Method Seven:
Using the Mat::zeros function, two parameters one is a size that represents the image width and height, and the other represents the type
Mat m = Mat::zeros (Size (+), CV_8UC3);
Similarly create a 4x4 block of 8-bit three-channel pixels per channel, printed as shown below:
Method Eight:
Using the Mat::ones function, two parameters one is a size that represents the image width and height, and the other represents the type
Mat m = Mat::ones (Size (+), CV_8UC1);
Similarly create a 4x4 pixel block of 8 bits per channel, printed as shown below:
Note this time the type is CV_8UC1, which represents the creation of a channel type data.
Copy Mat Object
The Mat object can be duplicated in OpenCV in the following ways
Mat m2; Mat m1 = Imread ("test.jpg"); m2 = M1;
Or
Mat m1 = Imread ("test.jpg"); Mat m2 (M1);
In both of these ways, the Mat object duplicates only the header and pointer to the pixel data, and does not actually copy the data portion. A full copy of the data object can be achieved by using the following method mat
Mat src = imread ("test.jpg"); Mat DST = Src.clone ();
Or
Mat src = imread ("test.jpg"); Mat Dst;src.copyto (DST);
Mat gets a pixel in an object
Method One: By reading the pixel value through the pointer, implement the pixel value operation. The function mat.ptr (row) where row represents the row index, starting from the zero base, represents the result of each row.
Mat src = imread ("test.jpg");
Const uchar* CurrentRow = src.ptr (row);
Represents a pointer to a pixel array that gets the specified row int row = 0.
Demo Code:
Mat resultimg = Mat::zeros (Src.size (), CV_8UC3), for (int row = 0; row < src.rows; row++) {for (int col = 0; Col < SR C.cols; col++) {Const uchar* CurrentRow = src.ptr (row), uchar* myrow = resultimg.ptr (Row), if (src.channels () = = 1) {Myrow[col] = 25 5-currentrow[col];} else if (src.channels () = = 3) {myrow[col*3] = 255-currentrow[col*3];myrow[col*3+1] = 255-currentrow[col*3+1];myrow[col* 3+2] = 255-currentrow[col*3+2];} else {printf ("Image type is unknown...\n");}}}
Method two: By randomly entering pixel point to read pixel value, realize pixel operation. The function mat.at<type> (row, col) supports the acquisition of single-channel or multi-channel images, in which case the type of the image needs to be predicted in advance. The code demonstrates the following:
for (int row = 0, row < src.rows; row++) {for (int col = 0; col < src.cols; col++) {if (src.channels () = = 1) {result Img.at<uchar> (row, col) = 255-src.at<uchar> (row, col);} else if (src.channels () = = 3) {vec3b pixels = src.at<vec3b> (row, col);resultimg.at<vec3b> (Row, col) [0] = 255- Pixels[0];resultimg.at<vec3b> (Row, col) [1] = 255-pixels[1];resultimg.at<vec3b> (row, col) [2] = 255-pixels [2];} else {printf ("Image type is unknown...\n");}}}
The results are shown below:
The new image memory object data structure was introduced by Mat as OpenCV 2.0, and it is the developer of every learning opencv that must be well known and mastered.
OPENCV Tutorial Two-Mat object with its various usages