NO.8 C + + histogram & convolution

Zero erosion

histogram

  • Histogram drawing

    • The histogram drawing we use in python has been drawn internally, but the histogram on C + + needs to draw a straight line by ourselves. We can only get the corresponding data on the api.
    #include  <iostream>
    #include <opencv2/opencv.hpp>
    
    using namespace std;
    using namespace cv;
    
    int main(){
        Mat src = imread("../resource/ashin.jpg");
        Mat gray;
        cvtColor(src,gray,COLOR_RGB2GRAY);
        imshow("src",src);
    
    
    
        Mat hist; // dst
        int channels=0; //
        int histSize=256;
        float range[]={0,255};
        const float* h_rang = range;
    
        // Collect histogram data, source data, quantity, mask, channel index, data, latitude, range,
        calcHist(&gray,1, &channels,Mat(),hist,1,&histSize,&h_rang);
    
        /** Draw histogram**/
        Mat dst = Mat::zeros(Size(1200,500),CV_8UC3);
        // Data normalization processing (distributing data to 0-400)
        Mat norm;
        normalize(hist,norm,0,400,NORM_MINMAX);
        // Draw data
        for (int a=0;a<256;++a){
            int xOffset = a*4 + 100;
            float y = norm.at<float>(a);
            line(dst,Point(xOffset,500),Point(xOffset, static_cast<int>(500 - y)),Scalar(255,255,255,2),2);
        }
        imshow("dst",dst);
    
        waitKey(0);
        return 0;
    }
    

  • Histogram equalization

    • Calculation method of Equalization: calculate the value of gray image, then convert it to the frequency of occurrence, calculate the cumulative probability, and equalize according to the cumulative probability. Equalization is to make the image softer and approximate some prominent color values to the overall color.
    // main
    #include  <iostream>
    #include <opencv2/opencv.hpp>
    #include "equalization.h"
    
    
    
    int main(){
        // Histogram equalization
        histEqualization("../resource/ashin.jpg","after");
        return 0;
    }
    
    // Function cpp
    //
    // Created by zero erosion on November 15, 2020
    //
    
    #include "equalization.h"
    
    
    void histEqualization(string path, string title) {
        Mat src = imread(path);
        Mat gray;
        cvtColor(src, gray, COLOR_RGB2GRAY);
    
        // Histogram value of gray scale
        int channels = 0;
        const int size = 256;
        float range[] = {0, 255};
        const float *ranges = range;
        Mat hist;
        calcHist(&gray, 1, &channels, Mat(), hist, 1, &size, &ranges);
    
        // Calculate the probability
        Mat radio = hist / (gray.rows * gray.cols);
    
        // Calculate cumulative probability
        Mat calculator(256,1,CV_32FC1);
        float s = 0;
        for (int i = 0; i < 256; i++) {
            float r= radio.at<float>(i);
            s+=r;
            calculator.at<float>(i)=s;
        }
        imshow("before", gray);
    
        // Equalization according to cumulative probability
        for(int m = 0;m<gray.rows;m++){
            for (int n = 0; n < gray.cols; ++n) {
                int color  =  gray.at<uint8_t>(m,n);
                // Find the scale corresponding to the color
                float per = calculator.at<float>(color);
                // Equalization (255 * cumulative color proportion)
                gray.at<uint8_t>(m,n) = static_cast<uint8_t>(255 * per);
            }
        }
    
    
    
        imshow(title, gray);
        waitKey();
    }
    

  • Histogram matching

    • The main process of histogram is to get the minimum difference between the two images by calculating the cumulative probability of the original image and the target image, and then map. This is histogram matching. It's more like two images with the smallest difference in hue fusion.
    #include "match.h
    int main(){
        // Original image, mapped image data
        histMatch("../resource/collapse.jpg","../resource/ashin.jpg");
        return 0;
    }
    // match.cpp
    //
    // Created by zero erosion on November 15, 2020
    //
    
    #include "match.h"
    
    void getEqualHist(Mat *mat, Mat *calculator);
    void getMatchColor(Mat *srcSum, Mat *referSum,Mat *color);
    void oneChannelMatch(Mat* srcChannel,Mat* referChannel);
    
    void histMatch(string src_path, string refer_path) {
        // Get the original map and the map to be mapped
        Mat src = imread(src_path);
        Mat refer = imread(refer_path);
    
    
        imshow("srcGray", src);
        imshow("referGray", refer);
        // Channel cutting
        vector<Mat> chsSrc;
        vector<Mat> chsRefer;
        split(src, chsSrc);
        split(refer, chsRefer);
    
        // Gray matching
        //Mat graySrc;
        //cvtColor(src,graySrc,COLOR_RGB2GRAY);
        //Mat grayRefer;
        //cvtColor(refer,grayRefer,COLOR_RGB2GRAY);
        //oneChannelMatch(&graySrc,&grayRefer);
    
        // Single channel matching
        oneChannelMatch(&chsSrc[0],&chsRefer[0]);
        oneChannelMatch(&chsSrc[1],&chsRefer[1]);
        oneChannelMatch(&chsSrc[2],&chsRefer[2]);
    
        // Multi-channel fusion
        merge(chsSrc,src);
        imshow("result", src);
        waitKey();
    
    }
    
    
    
    /**
     * Color value matching of single channel
     * @param srcChannel
     * @param referChannel
     */
    void oneChannelMatch(Mat* srcChannel,Mat* referChannel){
    
        Mat srcCalculator(256,1,CV_32FC1);
        getEqualHist(srcChannel,&srcCalculator);
        Mat referCalculator(256,1,CV_32FC1);
        getEqualHist(referChannel,&referCalculator);
        Mat color(256,1,CV_8UC1);
        getMatchColor(&srcCalculator,&referCalculator,&color);
    
    
        // Get the minimum difference color
        for(int row =0 ; row< srcChannel->rows;++row){
            for (int col = 0; col < srcChannel->cols; ++col) {
                // The color value obtained from the original image
                int colorValue = srcChannel->at<uint8_t>(row,col);
                //cout<< "colorValue="<<colorValue<<endl;
                // Get the color value of the corresponding target
                uchar value = color.at<uchar>(colorValue);
    
                // Update image information
                srcChannel->at<uint8_t>(row,col)=value;
    
            }
        }
    
    
    
    }
    
    /**
     * Get cumulative probability
     * @param mat
     * @param calculator
     * @return
     */
    
    void getEqualHist(Mat *mat, Mat *calculator) {
        // Histogram value of gray scale
        int channels = 0;
        const int size = 256;
        float range[] = {0, 255};
        const float *ranges = range;
        Mat hist;
        calcHist(mat, 1, &channels, Mat(), hist, 1, &size, &ranges);
    
        // Calculate the probability
        Mat radio = hist / (mat->rows * mat->cols);
    
        // Calculate cumulative probability
        //*calculator = Mat::zeros(256, 1, CV_32FC1);
    
        float s = 0;
        for (int i = 0; i < 256; i++) {
            float r = radio.at<float>(i);
            s += r;
            calculator->at<float>(i) = s;
        }
    
    
    
    }
    
    /**
     * Obtain the cumulative probability difference between the original image and the target image
     * @param srcSum
     * @param referSum
     * @param color
     */
    
    void getMatchColor(Mat *srcSum, Mat *referSum,Mat *color) {
    
    
    
        for (int i = 0; i < 256; i++) {
            float src_radio = srcSum->at<float>(i);
            float aimValue = 10;
            int index = 0;
            cout<<"=========="<<endl;
            for (int j = 0; j < 256; ++j) {
                float refer_radio = referSum->at<float>(j);
                // Calculate the minimum difference of cumulative probability
                float diffValue = abs(src_radio - refer_radio);
                if(diffValue < aimValue){
                    aimValue = diffValue;
                    index = j;
                    color->at<uint8_t>(i)= static_cast<uint8_t>(index);
                }
    
            }
    
    
        }
    }
    
    • As shown in the figure below, the original image in the upper left corner blends the hue in the upper right corner into the image, and finally generates the hue in the lower left corner. Gray matching

    • Color matching

    [external chain picture transfer failed, the source station may

convolution

  • convolution

    • Convolution is mainly an operation between the pixels of the image and the surrounding pixels, which can make the image smaller color difference (blur) or improve the color value (sharpen). See the corresponding part of android for the specific principle.
    void showFilter(string path) {
        Mat src = imread(path);
        Mat dst;
        // Build kernel
        Mat kernel = (Mat_<char>(3, 3) <<  -1, -1, -1,
                                            -1, -1, 9, -1,
                                            -1, -1, -1);
        filter2D(src, dst, -1,kernel);
    
        //You can enlarge the picture
        namedWindow("src",WINDOW_NORMAL);
        imshow("src",src);
        imshow("dst",dst);
        waitKey();
    
    }
    

    • laplacian (laplacian operator). The information presented by laplacian algorithm is more delicate than canny. It directly retains only the edge information of the image, and it is obvious that laplacian will retain some details inside the image.
    void showLaplacian(string path){
        Mat src = imread(path);
        Mat dst ;
        Laplacian(src,dst,CV_16S);
        // Since the calculation may lead to overflow, some algorithms need to be used for acceleration (because the default is 8-bit uint8, while CV_16S is 16 bits, so it needs to be accelerated, which can also make the image clearer.)
        convertScaleAbs(dst,dst);
    
        imshow("src",src);
        imshow("dst",dst);
        waitKey();
    
    
    }
    

    • Sobel & ScHARR operator
    void showSobel(string path){
        Mat src = imread(path);
        Mat dst ;
        // Sobel(src,dst,-1,1,0);
        // Since the calculation may lead to overflow, some algorithms need to be used to speed up
        // x direction
        Sobel(src,dst,CV_16S,1,0);
        convertScaleAbs(dst,dst);
         // y direction
        Mat dstY;
        Sobel(src,dstY,CV_16S,0,1);
        convertScaleAbs(dstY,dstY);
    
        Mat dst;
        add(dstX,dstY,dst);
    
        imshow("src",src);
        imshow("dst",dst);
        waitKey();
    }
    

    void showSobel(string path){
        Mat src = imread(path);
        Mat dst ;
        Scharr(src,dst,CV_16S,1,0);
        // Since the calculation may lead to overflow, some algorithms need to be used to speed up
        convertScaleAbs(dst,dst);
    
        imshow("src",src);
        imshow("dst",dst);
        waitKey();
    }
    

🔗 preface
🔗 Robot vision
🔗 NO.1 preface to machine vision
🔗 NO.2 geometric change of machine vision & special effect processing
🔗 NO.3 machine vision histogram & frame extraction
🔗 NO.4 machine vision face recognition & color filtering
🔗 NO.5 robot vision binarization & convolution
🔗 NO.6 robot vision Hough detection & edge search
🔗 Using Opencv in NO.7 C + +
🔗 NO.9 C + + match & change

Posted by sn202 on Fri, 06 May 2022 00:16:21 +0300