[learning notes] OpenCV+C + + (2)

Mat object
Mat object and IplImage object
The image data structure, automatic memory allocation and no memory leakage introduced after Mat object OpenCV2.0 are object-oriented data structures, which are divided into two parts: the head part and the data part.
IplImage has existed since OpenCV was released in 2001. It is a C language style data structure, which requires developers to allocate and manage memory by themselves. Using it for large programs is easy to cause memory leakage.

//Mat object constructor and common methods
//           Mat()
//          Mat(int rows,int cols,int type)
//          Mat(Size size,int type)
//          Mat(int rows,int cols,int type,const Scalar &s)
//          Mat(Size size,int type,const Scalar &s)
//          Mat(int ndims,const int *sizes,int type)
//          Mat(int ndims,const int *sizes,int type,const Scalar &s)
//
//           Common methods:
//              void copyTo(Mat mat)
//              void convertTo(Mat dst,int type)
//              Mat clone()
//              int channels()
//              int depth()
//              bool empty()
//              uchar* ptr(i=0)

#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace std;
using namespace cv;
int main(int argc,char** argv){
    Mat src;
    src = imread("");
    if(src.empty()){
        cout<<"could not load image..."<<endl;
        return -1;
    }
    namedWindow("input",CV_WINDOW_AUTOSIZE);
    imshow("input",src);
    /*
    Mat dst;
    dst = Mat(src.size(),src.type());
    dst = Scalar(127,0,255);//Assign value to image
    namedWindow("output",CV_WINDOW_AUTOSIZE);
    imshow("output",dst);
    */
    Mat dst = src.clone();//Clone
    src.copyTo(dst);//copy
    cvtColor(src,dst,CV_GRAY2GRAY);
    src.channels();//How many channels does the function return a value
    const uchar* firstRow = dst.ptr<uchar>(0);
    cout<<"first pixel value:"<<*firstRow<<endl;

    int cols = dst.cols;
    int rows = dst.rows;
    namedWindow("output",CV_WINDOW_AUTOSIZE);
    imshow("output",dst);

    //Usage of mat (int rows, int cols, int type, const scalar & S)
    Mat M(3,3,CV_8UC3,Scalar(0,0,255));
    //Cout < < m = "< endl < < m < < endl; / / comment it out, otherwise it will cost performance
    imshow("output",M);
    waitKey(0);
    return 0;
}

Use of Mat objects
Partial copy: generally, only the header and pointer parts of the Mat object will be copied, not the data part
                Mat A = imread(imgFilePath);
Mat B(A); / / copy only
Full copy: if you want to copy the header and data part of the Mat object together, you can use the following two API s
Mat F = A.clone(); or Mat G; A.copyTo(G);
Four key points:
The memory of the output image is automatically allocated
Using OpenCV's C + + interface does not need to consider memory allocation
Copy operations and copy constructors copy only the header part
Using two functions of clone and copyTo to realize complete data replication
Mat object creation:
cv::Mat::Mat constructor
        Mat M(2,2,CV_8UC3,Scalar(0,0,255));
The first two parameters represent row and column respectively, and the third parameter CV UC3 8 represents 8 bits of each channel, UC represents the unsigned char type, and 3 represents 3 channels. The fourth parameter is the vector indicating the initialization value of each pixel. The length of the vector corresponds to the number of channels
Create multidimensional array cv::Mat::create
        int sz[3] = {2,2,2};
        Mat L(3,sz,CV_8UC1,Scalar::all(0));
Code:
            Mat m1;
            m1.create(src.size(),src.type());
            m1=Scalar(0,0,255);
            Mat M;
            M.create(4,3,CV_8UC2);
            M = Scalar(127,127);
            cout<<"M="<<endl<<" "<<M<<endl<<endl;
            uchar* firstRow = M.ptr<uchar>(0);
            printf("%d",*firstRow);
Mat definition array
        Mat C = (Mat_<float>(3,3)<<0,-1,0,-1,5,-1,0,-1,0);
        filter2D(src,dst,src.depth(),kernel);

Tip: output a picture in pure black
    Mat m2 = Mat::zeros(src.size(),src.type());
Resize
    Mat m = Mat::zeros(2,2,CV_8UC1);
Symmetric matrix with output diagonal 1
    Mat m1 = Mat::eye(2,2,CV_8UC1)

Image operation
Read write image
imread can specify to load as grayscale or RGB image
imwrite saves the image file. The type is determined by the extension
Read write pixel
Read the pixel value of a GRAY pixel (CV uc1)
Scalar intensity = img.at<uchar> (y, x) or Scalar intensity = img.at<uchar> (Point (x, y))

Read the pixel value of an RGB pixel
            Vec3f intensity = img.at<Vec3f>(y,x);
            float blue = intensity.val[0];
            float green = intensity.val[1];
            float red = intensity.val[2];

namedWindow("input",CV_WINDOW_AUTOSIZE);
        imshow("input",src);
        //single channel
        cvtColor(src,gray_src,CV_BGR2GRAY);
        namedWindow("output",CV_WINDOW_AUTOSIZE);
        imshow("output",gray_src);
        int height = gray_src.rows;
        int width = gray_src.cols;
        for(int row = 0; row < height; row++){
            for(int col = 0; col < width; col++){
                int gray = gray_src.at<uchar>(row,col);
                gray_src.at<uchar>(row,col) = 255 - gray;//Backward interpolation
            }
        }
        //Three channel
        Mat dst;
        dst.create(src.size(),src.type());
        height = src.rows;
        width = src.cols;
        int nc = src.channels();//Get the number of channels
        for(int row = 0; row < height; row++){
            for(int col = 0; col < width; col++){
                if(nc == 1){
                    int gray = gray_src.at<uchar>(row,col);
                    gray_src.at<uchar>(row,col) = 255 - gray;//Backward interpolation
                }else if(nc == 3){
                    int b = dst.at<Vec3b>(row,col)[0];
                    int g = dst.at<Vec3b>(row,col)[1];
                    int r = dst.at<Vec3b>(row,col)[2];
                    dst.at<Vec3b>(row,col)[0] = 255 - b;
                    dst.at<Vec3b>(row,col)[1] = 255 - g;
                    dst.at<Vec3b>(row,col)[2] = 255 - r;

                    gray_src.at<uchar>(row,col) = max(r,max(b,g));//The gray value of gray μ SRC is the largest
                    gray_src.at<uchar>(row,col) = min(r,min(b,g));//Minimize gray value of gray ﹣ SRC
                }
            }
        }

Note:
Vec3b byte type
Vec3f float type
Vec3b and Vec3f
Vec3b corresponds to the uchar type data of blue, green and red
Vec3f corresponds to the float type data of three channels
The conversion of CV uc1 to CV32F1 is as follows:
                  src.convertTo(dst,CV_32F);
/ / get the pixel and invert the function
        bitwise_not(src.dst);
Modify pixel value

 

Image blending
Theoretical linear hybrid operation
g(x)=(1-a)f0(x)+af1(x), where a is between 0 and 1
Related API(addWeighted)
void cv::addWeighted(InputArray src1, parameter 1: input image mat SRC1
double alpha, parameter 2: enter the alpha value of image src1
InputArray src2, parameter 3: input image Mat-src2
double beta, parameter 4: input the alpha value of image src2
double gamma, parameter 5:gamma value
OutputArray dst, parameter 6: output mixed image
                           int dtype=-1)

        dst(I) = saturate(src1(I)*alpha + src2(I)*beta + gamma)
Note: the size and type of the two images must be the same

 

    #include<opencv2/opencv.hpp>
    #include<iostream>
    using namespace std;
    using namespace cv;
    int main(int argc,char** argv){
        Mat src1,src2,dst;
        double alpha = 0.5;
        src1 = imread("");
        src2 = imread("");
        if(!src1.data){
            cout<<"could not load image..."<<endl;
            return -1;
        }
        if(!src2.data){
            cout<<"could not load image..."<<endl;
            return -1;
        }
        if(src1.rows==src2.rows && src1.cols==src2.cols && src1.type() == src2.type()){
            addWeighted(src1,alpha,src2,(1.0-alpha),0,0,dst);
            //Direct addition
            //add(src1,src2,dst,Mat());
            //Multiplication
            //multiply(src1,src2,dst,1.0)
            namedWindow("src1",CV_WINDOW_AUTOSIZE);
            imshow("src1",src1);
            namedWindow("src2",CV_WINDOW_AUTOSIZE);
            imshow("src2",src2)
            namedWindow("blend demo",CV_WINDOW_AUTOSIZE);
            imshow("blend demo",dst);
        }else{
            printf("could not blend images, the size is not same...\n");
            return -1;
        }
        waitKey(0);
        return 0;
    }  

 

Published 5 original articles, won praise 1, visited 79
Private letter follow

Tags: OpenCV C

Posted on Fri, 07 Feb 2020 07:51:09 -0800 by PHP_apprentice