OpenCV2:Mat

1. Mat foundation

In computer memory, digital images are stored in matrix form. In OpenCV2, the data structure Mat is a matrix that stores image pixel information. It mainly includes two parts: a matrix header and a matrix pointer pointing to pixel data.

The matrix header mainly includes matrix size, storage method, storage address and number of references, etc.

The size of the matrix header is a constant and will not change with the size of the image, but the matrix storing the pixel data of the image will change with the size of the image. Usually, the amount of data will be large, several orders of magnitude larger than the matrix header. Thus, during image copying and transfer, the main overhead is caused by storing the matrix of image pixels. Therefore, OpenCV uses the number of references, and when doing image copying and passing, the entire Mat data is no longer copied, but just the matrix header and the pointer to the pixel matrix. For example:

cv::Mat a ;//创建矩阵头

a = cv::imread("f:\\psb.jpg");//读入图像

cv::Mat b = a ;//复制 

The a and b above have their own matrix headers, but their matrix pointers point to the same matrix, that is, any one of them changing the matrix data will affect the other.

So, multiple Mats share one matrix data, who will release the matrix data in the end?

This is the role of reference counting. When a Mat object is copied, the reference count will be increased by 1, and each time a Mat object is destroyed (sharing the same matrix data), the reference count will be decremented by 1. When the reference count is 0 , the matrix data will be cleaned.

The figure above shows that Mat objects a and b share a matrix, so its reference count refcount is 2.

But sometimes you still need to copy the matrix data itself (not just the matrix header and matrix pointer), at this time you can use the clone and copyTo methods.

cv::Mat c = a.clone();
cv::Mat d ;
a.copyTo(d);

C and d in the above code each have their own matrix, and changing their own matrix data will not affect each other.

In using Mat, you need to remember:

  1. Memory allocation in OpenCV is done automatically (if not specified)
  2. There is no need to consider memory release issues when using OpenCV's C++ interface
  3. Mat's assignment operation and copy constructor will only copy the matrix head, still share the same matrix
  4. If you want to copy the matrix data, you can use the clone and copyTo functions

2. Mat storage method

Each element of the matrix in Mat can use different data types. The smallest data type is char, which occupies one byte or 8 bits, and can be signed (0 to 255) or unsigned (-127 to 127) . In the RGB color space, using three char types can represent 16 million colors, but in the process of image processing, float or double may be used to represent the pixels of the image.

Mat Creation

Constructor

cv::Mat img(2,2,CV_8UC3,cv::Scalar(0,0,255));

The above code creates a matrix with 2 rows and 2 columns. The matrix elements are stored in 8-bit unsigned char type with 3 channels. The initial value of each pixel is (0, 0, 255). The first two parameters of the constructor
specify The rows and columns of the matrix
The third parameter specifies the data type of the matrix elements and the number of channels, and the specification rules are as follows:

CV_[The number of bits per item][Signed or Unsigned][TypePrefix]C[The channel number]

The four parts specify: the size of the element, whether it is signed or unsigned, the data type, and the number of channels

The last parameter, Scalar is a vector of short type, providing matrix initialization.

Create method

This method cannot set the initial value for the matrix, it just reallocates the memory for the matrix data when changing the size. Instructions:

img.create(4,4,CV_8UC(2));

Created a matrix with 4 rows and 4 columns with 2 channels

Initialization in MATLAB form

cv::Mat e = cv::Mat::eye(4,4,CV_64F);
cv::Mat z = cv::Mat::ones(2,2,CV_32F);
cv::Mat o = cv::Mat::zeros(3,3,CV_8UC1); 

Mat e is a diagonal matrix with 4 rows and 4 columns

Mat z is an identity matrix with 2 rows and 2 columns

Mat o is a matrix of zeros with 3 rows and 3 columns

Initialization of small matrices

For small matrices you can use a comma-separated initialization function

Mat c =(Mat_<double>(3,3)<<1,2,3,0,-1,0,4,5,6);

When template operations are performed on images, it is convenient to define templates using this method.

 

3.Mat input and output

Use the imread function to write an image to the Mat object.

a = cv::imread("f:\\psb.jpg");//读入图像

The prototype of imread is as follows

cv::Mat imread(const string& filename,int flags=1)

filename specifies where to read the image

flags specifies the color space of the image  

    flags > 0 3-channel color image

    flags = 0 grayscale image

    flags < 0 no change

Can also have the following enumeration values

CV_LOAD_IMAGE_ANYDEPTH、CV_LOAD_IMAGE_COLOR,CV_LOAD_IMAGE_GRAYSCALE

Use the imwrite function to save the Mat object to the specified file.

The function prototype of imwrite is as follows:

bool imwrite(const string& filename,InputArray img,constvector<int>& params=vector<int>())

filename, the specified file

img Mat object to save

params is used to specify the save encoding method of the image.

Use the filename extension to specify the image save format (.jpg .png .bmp), for different image save types, params are different values

  • JPEG, params is used to specify the quality of the image (0 to 100), the default is 95. CV_IMWRITE_JPEG_QUALITY
  • PNG, params is used to specify the compression level of the image (0 to 9). The higher the compression level, the smaller the space occupied by the image, and the longer it takes to save the image. The default value is 3. CV_IMWRITE_PNG_COMPRESSION
  • PPM, PGM, PBM, params is a flag (0 or 1), the default is 1.CV_IMWRITE_PXM_BINARY

imwrite can only save 8-bit (or 16-bit unsigned (CV_16UC) PNG, JPEG200 or TIFF images) single-channel or three-channel images. If you want to save such an image, you can use convertTo or cvtColor to convert it.

The following code shows how to write a 4-channel png image to a file using imwrite

void createAlphaMat(Mat &mat) 
{
    for(int i = 0 ; i < mat.rows ; i ++) {
        for(int j = 0 ; j < mat.cols ; j ++) {
            Vec4b &rgba = mat.at<Vec4b>(i,j);
            rgba[0] = UCHAR_MAX ;
            rgba[1] = saturate_cast<uchar>((float (mat.cols - j)) / ((float)mat.cols) * UCHAR_MAX);
            rgba[2] = saturate_cast<uchar>((float (mat.rows - i)) / ((float)mat.rows) * UCHAR_MAX);
            rgba[3] = saturate_cast<uchar>(0.5 * (rgba[1] + rgba[2]));
        }
    }
}
int main()
{
    Mat mat(480,640,CV_8UC4);
    createAlphaMat(mat);

    vector<int> compression_params ;
    compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
    compression_params.push_back(9);

    imwrite("alpha.png",mat,compression_params);

    return 0;
}

 

4.Mat display

OpenCV provides a method to display pictures in the form of a window, the code is as follows:

Mat img = imread("f:\psb.jpg");
const string name ="Hu";
namedWindow(name);
imshow(name,img);
waitKey();

Reprint link: https://www.cnblogs.com/wangguchangqing/p/3841271.html 

Supongo que te gusta

Origin blog.csdn.net/weixin_58045467/article/details/130874098
Recomendado
Clasificación