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