Home | History | Annotate | Download | only in histogram_comparison
      1 Histogram Comparison {#tutorial_histogram_comparison}
      2 ====================
      3 
      4 Goal
      5 ----
      6 
      7 In this tutorial you will learn how to:
      8 
      9 -   Use the function @ref cv::compareHist to get a numerical parameter that express how well two
     10     histograms match with each other.
     11 -   Use different metrics to compare histograms
     12 
     13 Theory
     14 ------
     15 
     16 -   To compare two histograms ( \f$H_{1}\f$ and \f$H_{2}\f$ ), first we have to choose a *metric*
     17     (\f$d(H_{1}, H_{2})\f$) to express how well both histograms match.
     18 -   OpenCV implements the function @ref cv::compareHist to perform a comparison. It also offers 4
     19     different metrics to compute the matching:
     20     -#  **Correlation ( CV_COMP_CORREL )**
     21         \f[d(H_1,H_2) =  \frac{\sum_I (H_1(I) - \bar{H_1}) (H_2(I) - \bar{H_2})}{\sqrt{\sum_I(H_1(I) - \bar{H_1})^2 \sum_I(H_2(I) - \bar{H_2})^2}}\f]
     22         where
     23         \f[\bar{H_k} =  \frac{1}{N} \sum _J H_k(J)\f]
     24         and \f$N\f$ is the total number of histogram bins.
     25 
     26     -#  **Chi-Square ( CV_COMP_CHISQR )**
     27         \f[d(H_1,H_2) =  \sum _I  \frac{\left(H_1(I)-H_2(I)\right)^2}{H_1(I)}\f]
     28 
     29     -#  **Intersection ( method=CV_COMP_INTERSECT )**
     30         \f[d(H_1,H_2) =  \sum _I  \min (H_1(I), H_2(I))\f]
     31 
     32     -#  **Bhattacharyya distance ( CV_COMP_BHATTACHARYYA )**
     33         \f[d(H_1,H_2) =  \sqrt{1 - \frac{1}{\sqrt{\bar{H_1} \bar{H_2} N^2}} \sum_I \sqrt{H_1(I) \cdot H_2(I)}}\f]
     34 
     35 Code
     36 ----
     37 
     38 -   **What does this program do?**
     39     -   Loads a *base image* and 2 *test images* to be compared with it.
     40     -   Generate 1 image that is the lower half of the *base image*
     41     -   Convert the images to HSV format
     42     -   Calculate the H-S histogram for all the images and normalize them in order to compare them.
     43     -   Compare the histogram of the *base image* with respect to the 2 test histograms, the
     44         histogram of the lower half base image and with the same base image histogram.
     45     -   Display the numerical matching parameters obtained.
     46 -   **Downloadable code**: Click
     47     [here](https://github.com/Itseez/opencv/tree/master/samples/cpp/tutorial_code/Histograms_Matching/compareHist_Demo.cpp)
     48 -   **Code at glance:**
     49 
     50 @include cpp/tutorial_code/Histograms_Matching/compareHist_Demo.cpp
     51 
     52 Explanation
     53 -----------
     54 
     55 -#  Declare variables such as the matrices to store the base image and the two other images to
     56     compare ( BGR and HSV )
     57     @code{.cpp}
     58     Mat src_base, hsv_base;
     59     Mat src_test1, hsv_test1;
     60     Mat src_test2, hsv_test2;
     61     Mat hsv_half_down;
     62     @endcode
     63 -#  Load the base image (src_base) and the other two test images:
     64     @code{.cpp}
     65     if( argc < 4 )
     66       { printf("** Error. Usage: ./compareHist_Demo <image_settings0> <image_setting1> <image_settings2>\n");
     67         return -1;
     68       }
     69 
     70     src_base = imread( argv[1], 1 );
     71     src_test1 = imread( argv[2], 1 );
     72     src_test2 = imread( argv[3], 1 );
     73     @endcode
     74 -#  Convert them to HSV format:
     75     @code{.cpp}
     76     cvtColor( src_base, hsv_base, COLOR_BGR2HSV );
     77     cvtColor( src_test1, hsv_test1, COLOR_BGR2HSV );
     78     cvtColor( src_test2, hsv_test2, COLOR_BGR2HSV );
     79     @endcode
     80 -#  Also, create an image of half the base image (in HSV format):
     81     @code{.cpp}
     82     hsv_half_down = hsv_base( Range( hsv_base.rows/2, hsv_base.rows - 1 ), Range( 0, hsv_base.cols - 1 ) );
     83     @endcode
     84 -#  Initialize the arguments to calculate the histograms (bins, ranges and channels H and S ).
     85     @code{.cpp}
     86     int h_bins = 50; int s_bins = 60;
     87     int histSize[] = { h_bins, s_bins };
     88 
     89     float h_ranges[] = { 0, 180 };
     90     float s_ranges[] = { 0, 256 };
     91 
     92     const float* ranges[] = { h_ranges, s_ranges };
     93 
     94     int channels[] = { 0, 1 };
     95     @endcode
     96 -#  Create the MatND objects to store the histograms:
     97     @code{.cpp}
     98     MatND hist_base;
     99     MatND hist_half_down;
    100     MatND hist_test1;
    101     MatND hist_test2;
    102     @endcode
    103 -#  Calculate the Histograms for the base image, the 2 test images and the half-down base image:
    104     @code{.cpp}
    105     calcHist( &hsv_base, 1, channels, Mat(), hist_base, 2, histSize, ranges, true, false );
    106     normalize( hist_base, hist_base, 0, 1, NORM_MINMAX, -1, Mat() );
    107 
    108     calcHist( &hsv_half_down, 1, channels, Mat(), hist_half_down, 2, histSize, ranges, true, false );
    109     normalize( hist_half_down, hist_half_down, 0, 1, NORM_MINMAX, -1, Mat() );
    110 
    111     calcHist( &hsv_test1, 1, channels, Mat(), hist_test1, 2, histSize, ranges, true, false );
    112     normalize( hist_test1, hist_test1, 0, 1, NORM_MINMAX, -1, Mat() );
    113 
    114     calcHist( &hsv_test2, 1, channels, Mat(), hist_test2, 2, histSize, ranges, true, false );
    115     normalize( hist_test2, hist_test2, 0, 1, NORM_MINMAX, -1, Mat() );
    116     @endcode
    117 -#  Apply sequentially the 4 comparison methods between the histogram of the base image (hist_base)
    118     and the other histograms:
    119     @code{.cpp}
    120     for( int i = 0; i < 4; i++ )
    121        { int compare_method = i;
    122          double base_base = compareHist( hist_base, hist_base, compare_method );
    123          double base_half = compareHist( hist_base, hist_half_down, compare_method );
    124          double base_test1 = compareHist( hist_base, hist_test1, compare_method );
    125          double base_test2 = compareHist( hist_base, hist_test2, compare_method );
    126 
    127         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 );
    128       }
    129     @endcode
    130 
    131 Results
    132 -------
    133 
    134 -#  We use as input the following images:
    135     ![Base_0](images/Histogram_Comparison_Source_0.jpg)
    136     ![Test_1](images/Histogram_Comparison_Source_1.jpg)
    137     ![Test_2](images/Histogram_Comparison_Source_2.jpg)
    138     where the first one is the base (to be compared to the others), the other 2 are the test images.
    139     We will also compare the first image with respect to itself and with respect of half the base
    140     image.
    141 
    142 -#  We should expect a perfect match when we compare the base image histogram with itself. Also,
    143     compared with the histogram of half the base image, it should present a high match since both
    144     are from the same source. For the other two test images, we can observe that they have very
    145     different lighting conditions, so the matching should not be very good:
    146 
    147 -#  Here the numeric results:
    148       *Method*        |  Base - Base |  Base - Half |  Base - Test 1 |  Base - Test 2
    149     ----------------- | ------------ | ------------ | -------------- | ---------------
    150       *Correlation*   |  1.000000    |  0.930766    |  0.182073      |  0.120447
    151       *Chi-square*    |  0.000000    |  4.940466    |  21.184536     |  49.273437
    152       *Intersection*  |  24.391548   |  14.959809   |  3.889029      |  5.775088
    153       *Bhattacharyya* |  0.000000    |  0.222609    |  0.646576      |  0.801869
    154     For the *Correlation* and *Intersection* methods, the higher the metric, the more accurate the
    155     match. As we can see, the match *base-base* is the highest of all as expected. Also we can observe
    156     that the match *base-half* is the second best match (as we predicted). For the other two metrics,
    157     the less the result, the better the match. We can observe that the matches between the test 1 and
    158     test 2 with respect to the base are worse, which again, was expected.
    159