Some operations of image container Mat and matrix in OpenCV4

Posted by TheStalker on Sat, 20 Nov 2021 23:11:07 +0100

catalogue

Images and matrices:

Image container Mat in OpenCV

First create an image container Mat and feel it:

Let's talk about the third parameter CV_8UC1 image file format:

Traverse Mat matrix elements (image pixel values):

Use Mat to perform various matrix element level operations:

C + + realizes the creation and operation of matrix:

Images and matrices:

In reality, the image we see is like this (we found a fuzzy single channel gray image):

What the computer reads is actually this:  

         Therefore, in the field of computer vision, the actual operation of image processing is digital, pixel by pixel. The whole image is a numerical matrix in the view of the computer. In order to carry the image, some matrix containers and image containers are needed.

Image container Mat in OpenCV

         There are many libraries of C + + operation matrices. OpenCV is the most popular in the direction of machine vision. Its image container mat provides very convenient matrix operation to process digital images. Mat is not only a very useful image container class, but also a general matrix class 2 -- there are many ways to create a mat object.

First create an image container Mat and feel it:

//Declare and initialize
int row = 3;
int col = 4;
cv::Mat a(row, col, CV_8UC1, cv::Scalar(0));

//Initialize after declaration
cv::Mat a2;
a2.create(5,4,CV_32FC3);  //Generate 5 rows and 4 columns, float type 3-channel matrix. This method cannot be assigned
a2.setTo(cv::Scalar(0.0,1.0,2.0)); //Can be used in conjunction with this function

Most of OpenCV's operations on matrices allow masking. for example

cv::Mat a;
a.create(5,4,CV_8UC1);
a.setTo(1, mask);

         The mask is a matrix with the same size as a. for the non-zero position in the mask, the element of the corresponding position of a will be set to 1, and other parts remain unchanged. The default value of mask is all non-zero, that is, all elements of a are operated by default.

Let's talk about the third parameter CV_8UC1 image file format:

Definition of writing format: CV_< bit_ depth>(S|U|F)C<number_ of_ channels>

Specific:

     1--bit_depth---Number of bits---Representative 8 bite,16bites,32bites,64bites---Take an example--for instance,as
        If you now create a storage--Grayscale image Mat object,The size of this image is 100 wide,High 100,that,Now this one
        There are 10000 pixels in the grayscale image, and the space occupied by each pixel in the memory space is 8 bite,8 position--So it's right
        It should be CV_8
     2--S|U|F--S--representative---signed int---Signed shaping
               U--representative--unsigned int--Unsigned shaping
               F--representative--float---------Single precision floating point
     3--C<number_of_channels>----representative---Number of channels in a picture,such as:
         1--Grayscale picture--grayImg---yes--Single channel image
         2--RGB color image ---------yes--3 Channel image
         3--belt Alph Channeled RGB image--yes--4 Channel image

         Some common correspondences: CV_8U --- uchar, CV_16U --- ushort, CV_32F --- float, CV_64F --- double  

Traverse Mat matrix elements (image pixel values):

Single channel:

cv::Mat a(5, 4, CV_8UC1, cv::Scalar(0));

for (int r = 0; r < a.rows; r++)
{
    for (int c = 0; c < a.cols; c++)
    {
        std::cout<<(int)a.ptr<uchar>(r)[c]<<std::endl;
    }
}

In the case of 3 channels, for example CV_32FC3, offset c*3+i on the basis of a.ptr < float > (R)

cv::Mat x(5, 4, CV_32FC3, cv::Scalar(0.0, 1.1, 2.2));

for (int r = 0; r < x.rows; r++)
{
    for (int c = 0; c < x.cols; c++)
    {  for (int i = 0; i < 3; i++)
		{      
			std::cout<<a.ptr<float>(r)[c*3+i]<<std::endl;    
		}
    }
}

Use Mat to perform various matrix element level operations:

cv::Mat a(3,2,CV_8UC1,cv::Scalar(127));
cv::Mat b(3,2,CV_8UC1,cv::Scalar(128));
cv::Mat mask(3,2,CV_8UC1,255);//Default all operations

double alpha;
double beta;
cv::Mat c;cv::add(a,b,c,mask); // a+b element level addition, the result is put in c, and the following is similar
cv::scaleAdd(a, alpha, b, c, mask); // a*alpha+b, element level addition, one matrix with scaling
cv::addWeighted(a, alpha, b, beta, c, mask); // a*alpha+b*beta, element level addition, two matrices with scaling coefficients (and offset gamma)
cv::subtract(a,b,c,mask); // Element level subtraction
cv::abs(a,c); // Take absolute value
cv::absdiff(a,b,c); // Element level subtraction takes the absolute value
cv::multiply(a,b,c,mask); // Element level multiplication
cv::divide(a,b,c,mask); // Element level division
//Similar operations include log, sqrt, exp, pow, min and max

cv::compare(a,b,c, cv::CMP_GT); // Element level size comparison. The results are stored in c. if the conditions are met, it is 255, otherwise it is 0, that is, c is an element type cv_ Matrix of 8uc1
//Conditional relationship CMP_GT greater than --- CMP_GE ≥ CMP_LT less than --- CMP_LE ≤ CMP_EQ equals --- CMP_NE is not equal to / / element level logical operation

cv::bitwise_or(a,b,c,mask);//Similar to bitwise_and, etc. note that this is not only an element level, but also a bit operation. For example, if an element a is 128 and the element at the corresponding position b is 0, they will bitwise_or, the corresponding position is 128
//If the element of the corresponding position of b is 1, the corresponding position of the result is 129 (because the last bit of 128 is 0, and the number of digits in front of 1128 after the last bit of 1 (i.e. 1) is retained, 129 is obtained)
//Similarly, if the element of a is 129 and the corresponding element of b is 1, the result is 129

C + + realizes the creation and operation of matrix:

#include <iostream>
#include <malloc.h>
#include <stdio.h>
using namespace std;

typedef struct
{
    //structural morphology
    int row,col;
    //A two-dimensional pointer to dynamically allocate memory
    float **matrix;
} Matrix;

typedef struct
{
    char *name;
    char *number;
} Student;

Matrix CreateMatrix()
{
    Matrix m;
    int row,col;
    cout << "Enter the number of rows and columns:" << endl;
    cin >> row >> col;
    float **enterMatrix ;
    enterMatrix=(float**) malloc(row*sizeof(float*)) ;
    for(int i=0; i<row; i++)
        enterMatrix[i] = (float *)malloc(col * sizeof(float));
    cout<<"Enter your matrix:"<<endl;
    for(int i=0; i<row; i++)
    {
        for(int j=0; j<col; j++)
        {
            cin >> enterMatrix[i][j];
        }
    }
    m.col = col;
    m.row = row;
    m.matrix = enterMatrix;
    return m;
}

//Initialize a row column as a col matrix
Matrix InitMatrix(int row,int col)
{
    Matrix m;
    float **matrix ;
    matrix=(float**) malloc(row*sizeof(float*)) ;
    for(int i=0; i<row; i++)
        matrix[i] = (float *)malloc(col * sizeof(float));
    for(int i=0; i<row; i++)
    {
        for(int j=0; j<col; j++)
        {
            matrix[i][j] = 0;
        }
    }
    m.col = col;
    m.row = row;
    m.matrix = matrix;
    return m;
}

Matrix add(Matrix m1, Matrix m2)
{
    for(int i=0; i<m1.row; i++)
    {
        for(int j=0; j<m1.col; j++)
        {
            m1.matrix[i][j] = m1.matrix[i][j] +m2.matrix[i][j];
        }
    }
    return m1;
}

Matrix sub(Matrix m1, Matrix m2)
{
    for(int i=0; i<m1.row; i++)
    {
        for(int j=0; j<m1.col; j++)
        {
            m1.matrix[i][j] = m1.matrix[i][j] -m2.matrix[i][j];
        }
    }
    return m1;
}

int calRowCol(Matrix M1,Matrix M2,int row,int col)//Row with row M1 and column with col m2
{
    int result = 0;
    int same = M1.col;
    for(int j=0; j<same; j++)
    {
        result+=M1.matrix[row][j]*M2.matrix[j][col];
    }

    return result;
}


Matrix Mul(Matrix m1, Matrix m2)
{
    Matrix result = InitMatrix(m1.row,m2.col);
    for(int i=0; i<m1.row; i++)
    {
        for(int j=0; j<m2.col; j++)
        {
            result.matrix[i][j] = calRowCol(m1,m2,i,j);
        }
    }
    return result;
}

Matrix numMul(Matrix m, int num)
{
    cout<<"numerical value:"<<num<<endl;
    for(int i=0; i<m.row; i++)
    {
        for(int j=0; j<m.col; j++)
        {
            m.matrix[i][j] = m.matrix[i][j]*num;
        }
    }
    return m;
}

Matrix printMatrix(Matrix m)
{
    for(int i=0; i<m.row; i++)
    {
        for(int j=0; j<m.col; j++)
        {
            cout << m.matrix[i][j] << "  ";
        }
        cout<<endl;
    }
}

int main()
{
    int num = 0;
    do
    {
        cout<<"*************************************\n";
        cout<<"*              menu                 *\n";
        cout<<"*          1.matrix addition                *\n";
        cout<<"*          2.Matrix subtraction               *\n";
        cout<<"*          3.matrix multiplication                *\n";
        cout<<"*          4.Matrix number multiplication               *\n";
        cout<<"*          5.sign out                   *\n";
        cout<<"*************************************\n";
        cin>>num;
        if(1 == num|| 2 == num || 3 == num)
        {
            cout<<"Please enter matrix 1"<<endl;
            Matrix m1 = CreateMatrix();
            cout<<"Please enter matrix 2"<<endl;
            Matrix m2 = CreateMatrix();
            cout<<"Two matrices are"<<endl;
            printMatrix(m1);
            cout<<endl;
            printMatrix(m2);
            switch(num)
            {
            case 1:
            {
                if(m1.col!=m2.col || m1.row!=m2.row)
                {
                    cout<<"Different ranks"<<endl;
                }
                else{
                    cout<<"The result is:"<<endl;
                    printMatrix(add(m1,m2));
                }
                break;
            }
            case 2:
            {

                if(m1.col!=m2.col || m1.row!=m2.row)
                {
                    cout<<"Parameter error"<<endl;
                }
                else{
                    cout<<"The result is:"<<endl;
                    printMatrix(sub(m1,m2));
                }
                break;

            }
            case 3:
            {
                if(m1.col!=m2.row)
                {
                    cout<<"Parameter error"<<endl;
                }
                else{
                    cout<<"The result is:"<<endl;
                    printMatrix(Mul(m1,m2));
                }
                break;
            }
            default:
                break;
            }
        }
        else if(4 == num)
        {
            int number = 1;
            cout<<"Please enter a matrix"<<endl;
            Matrix m = CreateMatrix();
            cout<<"Please enter a value"<<endl;
            cin>>number;
            cout<<"The matrix is:"<<endl;
            printMatrix(m);
            cout<<"The value is:"<<endl;
            cout<<number<<endl;
            printMatrix(numMul(m,number));
        }
        cout<<"Press enter to continue....";

        getchar();
        getchar();
        system("cls");
    }
    while(1 == num|| 2 == num || 3 == num ||4 == num);
    return 0;
}

Topics: C++ OpenCV image processing