From: http://blog.163.com/woshitony111@126/blog/static/71379539201262202820650/
Principle
To compare two histograms (and
), You must first selectComparison criteria().
Opencv Functions
Comparehist performs a histogram comparison task. This function provides four comparison criteria for similarity calculation:
Correlation (cv_comp_correl)
Where
Is the number of bin in the histogram.
Chi-square (cv_comp_chisqr)
Intersection (cv_comp_intersect)
Bhattacharyya distance (cv_comp_bhattacharyya)
Source code
# Include "opencv2/highgui. HPP "# include" opencv2/imgproc. HPP "# include <iostream> # include <stdio. h> using namespace STD; using namespace CV;/** @ function main */INT main (INT argc, char ** argv) {mat src_base, HSV _base; MAT src_test1, HSV _test1; mat src_test2, HSV _test2; mat hsv _half_down; // load three images with different backgrounds if (argc <4) {printf ("** error. usage :. /comparehist_demo <image_settings0> <image_setting1> <image_settings2> \ n "); Return-1;} src_base = imread (argv [1], 1 ); src_test1 = imread (argv [2], 1); src_test2 = imread (argv [3], 1); // convert to HSV cvtcolor (src_base, HSV _base, cv_bgr2hsv ); cvtcolor (src_test1, HSV _test1, latency); cvtcolor (src_test2, HSV _test2, latency); HSV _half_down = HSV _base (range (HSV _base.rows/2, HSV _base.rows-1), range (0, HSV _base.cols-1); // use 30 bin pairs for the hue channel and 32 bin int h_bins = 50 for the saturatoin channel; int s_bins = 60; int histsize [] = {h_bins, s_bins}; // The value range of hue is from 0 to 256, and the value range of saturation is from 0 to 180 float h_ranges [] = {0,256 }; float s_ranges [] = {0,180}; const float * ranges [] = {h_ranges, s_ranges}; // use The 0th and 1st channels int channels [] = {0, 1 }; /// histogram matnd hist_base; matnd hist_half_down; matnd hist_test1; matnd hist_test2; // calculate the histogram calchist (& HSV _base, 1, channels, MAT (), hist_base, 2, histsize, ranges, true, false); normalize (hist_base, hist_base, 0, 1, norm_minmax,-1, MAT (); calchist (& HSV _half_down, 1, channels, MAT (), hist_half_down, 2, histsize, ranges, true, false); normalize (hist_half_down, hist_half_down, 0, 1, norm_minmax,-1, MAT ()); calchist (& HSV _test1, 1, channels, MAT (), hist_test1, 2, histsize, ranges, true, false); normalize (hist_test1, hist_test1, 0, 1, norm_minmax, -1, MAT (); calchist (& HSV _test2, 1, channels, MAT (), hist_test2, 2, histsize, ranges, true, false); normalize (hist_test2, hist_test2, 0, 1, norm_minmax,-1, MAT (); // apply different histogram comparison methods for (INT I = 0; I <4; I ++) {int compare_method = I; double base_base = comparehist (hist_base, hist_base, compare_method); double region = comparehist (hist_base, region, compare_method); double base_test1 = comparehist (hist_base, Region, compare_method); double base_test2 = comparehist (hist_base, hist_test2, compare_method); printf ("method [% d] Perfect, base-half, base-test (1 ), base-test (2): % F, % F \ n ", I, base_base, base_half, base_test1, base_test2 );} printf ("done \ n"); Return 0 ;}
Explanation
Declare the matrix for storing the benchmark image and the other two contrast images (RGB and HSV)
Mat src_base, hsv_base; Mat src_test1, hsv_test1; Mat src_test2, hsv_test2; Mat hsv_half_down;
Load the benchmark image (src_base) and two test images:
if( argc < 4 ) { printf("** Error. Usage: ./compareHist_Demo <image_settings0> <image_setting1> <image_settings2>\n"); return -1; } src_base = imread( argv[1], 1 ); src_test1 = imread( argv[2], 1 ); src_test2 = imread( argv[3], 1 );
Convert the image to the HSV format:
cvtColor( src_base, hsv_base, CV_BGR2HSV ); cvtColor( src_test1, hsv_test1, CV_BGR2HSV ); cvtColor( src_test2, hsv_test2, CV_BGR2HSV );
Create a half-length image (in hsv format) that contains the lower half of the baseline image ):
hsv_half_down = hsv_base( Range( hsv_base.rows/2, hsv_base.rows - 1 ), Range( 0, hsv_base.cols - 1 ) );
Initialize the real parameters (bins, range, channels h and S) required for calculating the histogram ).
int h_bins = 50; int s_bins = 32; int histSize[] = { h_bins, s_bins }; float h_ranges[] = { 0, 256 }; float s_ranges[] = { 0, 180 }; const float* ranges[] = { h_ranges, s_ranges }; int channels[] = { 0, 1 };
Create a matnd instance for storing the histogram:
MatND hist_base; MatND hist_half_down; MatND hist_test1; MatND hist_test2;
Calculate the baseline image, two test images, and the histogram of the half-body baseline image:
calcHist( &hsv_base, 1, channels, Mat(), hist_base, 2, histSize, ranges, true, false ); normalize( hist_base, hist_base, 0, 1, NORM_MINMAX, -1, Mat() ); calcHist( &hsv_half_down, 1, channels, Mat(), hist_half_down, 2, histSize, ranges, true, false ); normalize( hist_half_down, hist_half_down, 0, 1, NORM_MINMAX, -1, Mat() ); calcHist( &hsv_test1, 1, channels, Mat(), hist_test1, 2, histSize, ranges, true, false ); normalize( hist_test1, hist_test1, 0, 1, NORM_MINMAX, -1, Mat() ); calcHist( &hsv_test2, 1, channels, Mat(), hist_test2, 2, histSize, ranges, true, false ); normalize( hist_test2, hist_test2, 0, 1, NORM_MINMAX, -1, Mat() );
Compare the histogram of the baseline image (hist_base) with other histograms by using four comparison criteria in sequence:
for( int i = 0; i < 4; i++ ) { int compare_method = i; double base_base = compareHist( hist_base, hist_base, compare_method ); double base_half = compareHist( hist_base, hist_half_down, compare_method ); double base_test1 = compareHist( hist_base, hist_test1, compare_method ); double base_test2 = compareHist( hist_base, hist_test2, compare_method ); printf( " Method [%d] Perfect, Base-Half, Base-Test(1), Base-Test(2) : %f, %f, %f, %f \n", i, base_base, base_half , base_test1, base_test2 ); }
Result
Use the following input image:
The first one is the benchmark image, and the other two are the test images. At the same time, we will compare the benchmark image with its own and its half body images.
We should expect that the baseline Image Histogram and its own comparison will produce a perfect match. When compared with a half-body image from the same background environment, there should be a relatively high similarity, when compared with the other two test images with Different Brightness and illumination conditions, the matching degree should not be good:
The result value is shown below:
Comparison criteria |
Benchmark-Benchmark |
Benchmark-half body |
Benchmark-Test 1 |
Benchmark-Test 2 |
Correlation |
1.000000 |
0.930766 |
0.182073 |
0.120447 |
Chi-square |
0.000000 |
4.940466 |
21.184536 |
49.273437 |
Intersection |
24.391548 |
14.959809 |
3.889029 |
5.775088 |
Bhattacharyya |
0.000000 |
0.222609 |
0.646576 |
0.801869 |
ForCorrelationAndIntersectionThe greater the value, the greater the similarity. Therefore, we can see that for the comparison using these two methods, the comparison result value of * benchmark-benchmark * is the largest, whileBenchmark-half bodyThe matching is the second best (consistent with our predictions ). The smaller the result, the larger the similarity. We can see that the matching between the baseline Image Histogram and the two test image histograms is the worst, which once again confirms our prediction.