Opencv-C++ Notes (10): opencv-image pixel calculation

1. Probability

We can understand a digital image as a matrix of a certain size. The size of each element in the matrix represents the brightness and darkness of each pixel in the image. Therefore, the maximum value in the statistical matrix is ​​to find the pixel with the largest gray value in the image. Calculating the average value is to calculate the average gray level of the image pixels, which can be used to represent the overall brightness and darkness of the image. Therefore, the statistical work for matrix data also has a certain significance and role in image pixels. In OpenCV 4, functions for calculating the maximum value, minimum value, average value, mean square error and many other statistics of image pixels are integrated. Next, the related functions of these functions will be introduced in detail.

2. Find the maximum and minimum values ​​of image pixels

void cv::minMaxLoc(InputArray src,
                   double * minVal,
                   double * maxVal = 0,
                   Point * minLoc = 0,
                   Point * maxLoc = 0,
                   InputArray mask = noArray())

src: The image or matrix that needs to find the maximum and minimum values. It must be a single-channel matrix.
minVal: The minimum value in the image or matrix.
maxVal: The maximum value in the image or matrix.
minLoc: The coordinates of the minimum value in the image or matrix in the matrix.
maxLoc: The coordinates of the maximum value in the image or matrix in the matrix.
mask: mask, used to set the specified area in the image or matrix to find the maximum value.

Here we see a new data type Point, which is used to represent the pixel coordinates of the image. Since the pixel coordinate axis of the image takes the upper left corner as the coordinate origin, the horizontal direction is the x axis, and the vertical direction is the y axis, so Point (x,y) corresponds to the rows and columns of the image expressed as Point(columns, rows). In OpenCV, a variety of data types are set for both 2D coordinates and 3D coordinates. For 2D coordinate data types, integer coordinates cv::Point2i (or cv::Point), double coordinates cv::Point2d, and floating point types are defined. The coordinate cv::Point2f also defines the above-mentioned coordinate data type for 3D coordinates, and only needs to change the number "2" to "3". For the specific data of the x, y, and z axes in the coordinates, they can be accessed through the x, y, and z attributes of the variables. For example, Point.x can read the x-axis data of the coordinates.

The function realized by this function is to find the maximum value in a specific area in the image. The first parameter of the function is to input a single-channel matrix. It should be noted that this variable must be a single-channel matrix data. If it is a multi-channel matrix data , you need to use cv::Mat::reshape() to change multiple channels into a single channel, or find the maximum value of each channel separately, and then compare to find the global maximum value. For the usage of cv::Mat::reshape(), it is given in the code listing 3-8. The second to fifth parameters are pointers to the minimum value, maximum value, minimum value position and maximum value position respectively. If you do not need to find a certain parameter, you can set this parameter to NULL. The last parameter of the function is to find the most worthwhile The mask matrix is ​​used to mark the range to search for the above four values. The default value of the parameter is noArray(), which means that the search range is all the data in the matrix.

Mat cv::Mat::reshape(int  cn,int  rows = 0)

cn: the number of channels of the transformed matrix.
rows: The number of rows of the matrix after transformation, if the parameter is zero, the number of rows after transformation is the same as before transformation.

Note that
if there are multiple maximum or minimum values ​​in the matrix, the position where the minMaxLoc() function outputs the maximum value is the position where the maximum value is detected for the first time by row scanning from left to right. At the same time, when inputting parameters, be sure to add the value address character.
In order for readers to better understand the principle and usage of the minMaxLoc() function, a sample program for finding the maximum value of the matrix is ​​given in Code Listing 3-9, and the final result of the program operation is shown in Figure 3-6, and in Figure 3 -7 shows the content of the created two matrices and channel-transformed matrices viewed in Image
Watch.

#include<iostream>
#include<vector>
#include<string>
#include <opencv2/opencv.hpp>
#include "opencv/highgui.h"

using namespace std;
using namespace cv;

int main(int argc,char** argv) {
    
    
    cout<<"OpenCv Version: "<<CV_VERSION<<endl;
    float a[12]={
    
    1,2,3,4,5,10,6,7,8,9,10,0};
    Mat img=Mat(3,4,CV_32FC1,a);//单通道矩阵
    Mat imgs=Mat(2,3,CV_32FC2,a);//多通道矩阵
    double minVal,maxVal;//用于存放矩阵中的最大值和最小值
    Point minIdx,maxIdx;//用于存放矩阵中的最大值和最小值的位置

    /*寻找单通道矩阵中的最值*/
    minMaxLoc(img,&maxVal,&minVal,&minIdx,&maxIdx);
    cout << "img中最大值是:" << maxVal << " " << "在矩阵中的位置:" << maxIdx << endl;
    cout << "img中最小值是:" << minVal << " " << "在矩阵中的位置:" << minIdx << endl;

    /*寻找多通道矩阵中的最值*/
    Mat imgs_re=imgs.reshape(1,4);//将多通道矩阵变成单通道矩阵
    minMaxLoc(imgs_re,&minVal,&maxVal,&minIdx,&maxIdx);
    cout << "img中最大值是:" << maxVal << " " << "在矩阵中的位置:" << maxIdx << endl;
    cout << "img中最小值是:" << minVal << " " << "在矩阵中的位置:" << minIdx << endl;
    return 0;
}

insert image description here
insert image description here

3. Calculate the mean and standard deviation of the image

The average value of the image indicates the overall brightness and darkness of the image, and the larger the average value of the image, the brighter the image as a whole. The standard deviation represents the contrast degree of light and dark changes in the image, and the larger the standard deviation is, the more obvious the light and dark changes in the image are. OpenCV
4 provides the mean() function to calculate the mean value of the image, and the meanStdDev() function to calculate the mean and standard deviation of the image at the same time. Next, we will introduce how to use these two functions in detail.

cv::Scalar cv::mean(InputArray src,InputArray mask = noArray())

src: The image matrix to be averaged.
mask: mask, which is used to mark which areas are averaged.

This function is used to calculate the average value of each channel of the image matrix. The first parameter of the function is used to input the image matrix to be averaged. The number of channels can be between 1 and 4. It should be noted that the return value of this function is a variable of type cv::Scalar. The return value of the function has 4 bits, which respectively represent the average value of the 4 channels of the input image. If the input image has only 1 channel, then the return value The last three bits are all 0. For example, if you input an image with a single-channel average value of 1 into this function, the output result is [1,0,0,0], and you can view the nth channel through cv::Scalar[n] average of. The second parameter of this function is used to control the range of calculating the mean value of the image. In the first parameter, the pixel with a pixel value of 0 in the second parameter is removed. The calculation principle is shown in formula (3.5). When not input When the second parameter is used, it means to calculate the average value of all pixels of the first parameter.
insert image description here
Among them, it represents the average value of the cth channel, and represents the gray value of the pixel of the cth channel.
The meanStdDev() function can calculate the mean value and standard deviation of each channel of the image at the same time, and its function prototype is given in Code Listing 3-11.

void cv::meanStdDev(InputArray src,OutputArray mean,OutputArray stddev,InputArray mask = noArray())
src:待求平均值的图像矩阵。
mean:图像每个通道的平均值,参数为Mat类型变量。
stddev:图像每个通道的标准方差,参数为Mat类型变量。
mask:掩模,用于标记求取哪些区域的平均值和标准方差。

The first parameter of this function is the same as the first parameter of the previous mean() function, which can be an image of 1-4 channels. The difference is that this function has no return value, and the mean and standard deviation of the image are output in the first function. In the second and third parameters, different from the mean() function, the Mat type variable is used to store the mean value and standard deviation. The number of data in the variable is the same as the number of channels in the first parameter. If the input image has only one channel, there is only one data in the mean and standard deviation variables calculated by this function. The calculation principle of this function is shown in formula (3.6).

insert image description here

#include<iostream>
#include<vector>
#include<string>
#include <opencv2/opencv.hpp>
#include "opencv/highgui.h"

using namespace std;
using namespace cv;

int main(int argc,char** argv) {
    
    
    cout<<"OpenCv Version: "<<CV_VERSION<<endl;
    float a[12]={
    
    1,2,3,4,5,10,6,7,8,9,10,0};
    Mat img=Mat(3,4,CV_32FC1,a);//单通道矩阵
    Mat imgs=Mat(2,3,CV_32FC2,a);//多通道矩阵

    cout << "/* 用meanStdDev同时求取图像的均值和标准方差 */" << endl;
    Scalar myMean;
    myMean=mean(imgs);
    cout<<"imgs均值 = "<<myMean<<endl;
    cout<<"imgs第一个通道的均值 = "<<myMean[0]<<" "
        <<"imgs第二个通道的均值 = "<<myMean[1]<<endl;

    cout << "/* 用meanStdDev同时求取图像的均值和标准方差 */" << endl;
    Mat myMeanMat,myStddevMat;

    meanStdDev(img,myMeanMat,myStddevMat);
    cout << "img均值=" << myMeanMat << " " << endl;
    cout << "img标准方差=" << myStddevMat << endl << endl;
    meanStdDev(imgs,myMeanMat,myStddevMat);
    cout << "img均值=" << myMeanMat << " " << endl;
    cout << "img标准方差=" << myStddevMat << endl << endl;
    return 0;
}

insert image description here

4. Comparison operation of two pictures

OpenCV 4 provides the max() and min() functions to calculate the larger or smaller gray value of each pixel in two images. These two functions compare the gray value of each element in the two images respectively. size, retaining larger (smaller) grayscale values

 void cv::max(InputArray src1,InputArray src2,OutputArray dst) void
 cv::min(InputArray src1,InputArray src2,OutputArray dst)
  • src1: the first image matrix, which can be a matrix with any number of channels.
  • src2: The second image matrix, the size, number of channels and data type need to be consistent with src1.
  • dst: The image matrix after retaining the larger (smaller) gray value of the corresponding position, the size, number of channels and data type are consistent with src1.

The function of this function is relatively simple, which is to compare the size of each pixel of the image, retain the larger or smaller value as required, and finally generate a new image. For example, if the pixel value of the first image is 100, and the pixel value of the second image is 10, then the pixel value of the output image is 100. The code implementation process and operation results of these two functions are given in Code Listing 3-14, and the operation results are shown in Figure 3-9, Figure 3-10 and Figure 3-11. This comparison operation is mainly used in the processing of matrix type data, and the comparison operation with the mask image can achieve the effect of matting or selecting channels.

#include<iostream>
#include<vector>
#include<string>
#include <opencv2/opencv.hpp>
#include "opencv/highgui.h"

using namespace std;
using namespace cv;

int main(int argc,char** argv) {
    
    
    cout<<"OpenCv Version: "<<CV_VERSION<<endl;
    float a[12]={
    
    1,2,3.3,4,5,9,5,7,8.2,9,10,2};
    float b[12]={
    
    1,2.2,3,1,3,10,6,7,8,9.3,10,1};
    Mat imga=Mat(3,4,CV_32FC1,a);
    Mat imgb=Mat(3,4,CV_32FC1,b);
    Mat imgas=Mat(2,3,CV_32FC2,a);
    Mat imgbs=Mat(2,3,CV_32FC2,b);

    //对两个单通道矩阵进行比较远算
    Mat myMax,myMin;
    max(imga,imgb,myMax);
    min(imga,imgb,myMin);

    //对两个多通道矩阵进行比较运算
    Mat myMaxs,myMins;
    max(imgas,imgbs,myMaxs);
    min(imgas,imgbs,myMins);

    //对两张彩色图像进行比较运算
    Mat img0=imread("lena.png");
    Mat img1=imread("noobcv.jpg");
    if(img0.empty()||img1.empty()){
    
    
        cout<<"请确认图像文件名称是否正确"<<endl;
        return -1;
    }
    Mat comMin,comMax;
    max(img0,img1,comMax);
    min(img0,img1,comMin);
    imshow("comMin",comMin);
    imshow("comMax",comMax);

    //与掩模进行比较运算
    Mat src1=Mat::zeros(Size(512,512),CV_8UC3);
    Rect rect(100,100,300,300);
    src1(rect)=Scalar(255,255,255);//生成一个300*300的掩模
    Mat comsrc1,comsrc2;
    min(img0,src1,comsrc1);
    imshow("comsrc1",comsrc1);

    Mat src2=Mat(512,512,CV_8UC3,Scalar(0,0,255));//生成一个显示红色的低通掩模
    min(img0,src2,comsrc2);
    imshow("comsrc2",comsrc2);

    //对两张图片灰度图像进行比较运算
    Mat img0G,img1G,comMinG,comMaxG;
    cvtColor(img0,img0G,COLOR_BGR2GRAY);
    cvtColor(img1,img1G,COLOR_BGR2GRAY);
    max(img0G,img1G,comMaxG);
    max(img0G,img1G,comMaxG);
    imshow("comMinG",comMinG);
    imshow("comMaxG",comMaxG);
    return 0;
}

insert image description here
insert image description here
insert image description here

5. Logical operation of two pictures

OpenCV 4 provides four functions **bitwise_and(), bitwise_or(), bitwise_xor() and bitwise_not()** for AND, OR, XOR and NOT operations between two image pixels, in code listing 3-15 The function prototypes of these four functions are given in . Before understanding the usage of functions, let's understand the rules of logical operation of image pixels. The logical operation between image pixels is the same as the logical operation between numbers, and the specific rules are given in Figure 3-12. The negation operation of a pixel can only be performed on one value, so the negation operation is performed on the pixel value of image 1 when negating the pixel in Figure 3-12. If the pixel value is only 0 and 1, then the first 4 rows of data in the figure correspond to all the operation rules, but the image pixel value of CV_8U type is from 0 to 255, and the logic operation at this time needs to convert the pixel value to Convert it into a binary number, because the CV_8U type is 8-bit data, so negating 0 is 11111111, which is 255. In the last row of data in Figure 3-12, the binary value corresponding to pixel value 5 is 101, and the binary value corresponding to pixel value 6 is 110, so the AND operation is 100 (4), or the operation is 111 (7), and the XOR operation is 011 (3), negate the pixel value 5 to get 11111010 (250). After understanding the principle of the array operation of pixels, let's look at
how to use the array operation function provided in OpenCV 4.
insert image description here

//像素求与运算
  void cv::bitwise_and(InputArray src1,
                           InputArray src2,
                           OutputArray dst,
                          InputArray mask = noArray()
                            )
  //像素求或运算
   void cv::bitwise_or(InputArray src1,
                     InputArray src2,
                      OutputArray dst,
                      InputArray mask = noArray()
                        )
   //像素求异或运算
   void cv::bitwise_xor(InputArray src1,
                       InputArray src2,
                       OutputArray dst,
                       InputArray mask = noArray()
                        )
   //像素求非运算
   void cv::bitwise_not(InputArray src,
                       OutputArray dst,
                       InputArray mask = noArray()
                         )
  • src1: the first image matrix, which can be multi-channel image data.
  • src2: The second image matrix, the size, number of channels and data type need to be consistent with src1.
  • dst: The output result of logical operation, the size, number of channels and data type are consistent with src1.
  • mask: mask, used to set the range of logical operations in images or matrices.

These functions all perform corresponding logical operations. When performing logical calculations, it is necessary to ensure that the size, data type, and number of channels between the two image matrices are the same. When multiple channels perform logical operations, different channels are independently performed. of. In order to understand the logical operation between two image pixels more intuitively, an example program for logical operation of two black and white image pixels is given in Code Listing 3-16

#include <opencv2\opencv.hpp>
   2.  #include <iostream>
   3.  #include <vector>
   4.  
   5.  using namespace std;
   6.  using namespace cv;
   7.  
   8.  int main()
   9. {
    
    
   10.    Mat img = imread("lena.png");
   11.    if (img.empty())
   12.    {
    
    
   13.      cout << "请确认图像文件名称是否正确" << endl;
   14.      return -1;
   15.    }
   16.    //创建两个黑白图像
   17.    Mat img0 = Mat::zeros(200, 200, CV_8UC1);
   18.    Mat img1 = Mat::zeros(200, 200, CV_8UC1);
   19.    Rect rect0(50, 50, 100, 100);
   20.    img0(rect0) = Scalar(255);
   21.    Rect rect1(100, 100, 100, 100);
   22.    img1(rect1) = Scalar(255);
   23.    imshow("img0", img0);
   24.    imshow("img1", img1);
   25.  
   26.    //进行逻辑运算
   27.    Mat myAnd, myOr, myXor, myNot, imgNot;
   28.    bitwise_not(img0, myNot);
   29.    bitwise_and(img0, img1, myAnd);
   30.    bitwise_or(img0, img1, myOr);
   31.    bitwise_xor(img0, img1, myXor);
   32.    bitwise_not(img, imgNot);
   33.    imshow("myAnd", myAnd);
   34.    imshow("myOr", myOr);
   35.    imshow("myXor", myXor);
   36.    imshow("myNot", myNot);
   37.    imshow("img", img);
   38.    imshow("imgNot", imgNot);
   39.    waitKey(0);
   40.    return 0;
   41.  }

insert image description here

Guess you like

Origin blog.csdn.net/jiyanghao19/article/details/131251381