OpenCV  3.4.0
Open Source Computer Vision
Back Projection


In this tutorial you will learn:


What is Back Projection?

How does it work?



  1. Declare the matrices to store our images and initialize the number of bins to be used by our histogram:
    Mat src; Mat hsv; Mat hue;
    int bins = 25;
  2. Read the input image and transform it to HSV format:
    src = imread( argv[1], 1 );
    cvtColor( src, hsv, COLOR_BGR2HSV );
  3. For this tutorial, we will use only the Hue value for our 1-D histogram (check out the fancier code in the links above if you want to use the more standard H-S histogram, which yields better results):
    hue.create( hsv.size(), hsv.depth() );
    int ch[] = { 0, 0 };
    mixChannels( &hsv, 1, &hue, 1, ch, 1 );
    as you see, we use the function cv::mixChannels to get only the channel 0 (Hue) from the hsv image. It gets the following parameters:
    • **&hsv:** The source array from which the channels will be copied
    • 1: The number of source arrays
    • **&hue:** The destination array of the copied channels
    • 1: The number of destination arrays
    • ch[] = {0,0}: The array of index pairs indicating how the channels are copied. In this case, the Hue(0) channel of &hsv is being copied to the 0 channel of &hue (1-channel)
    • 1: Number of index pairs
  4. Create a Trackbar for the user to enter the bin values. Any change on the Trackbar means a call to the Hist_and_Backproj callback function.
    char* window_image = "Source image";
    namedWindow( window_image, WINDOW_AUTOSIZE );
    createTrackbar("* Hue bins: ", window_image, &bins, 180, Hist_and_Backproj );
    Hist_and_Backproj(0, 0);
  5. Show the image and wait for the user to exit the program:
    imshow( window_image, src );
    return 0;
  6. Hist_and_Backproj function: Initialize the arguments needed for cv::calcHist . The number of bins comes from the Trackbar:
    void Hist_and_Backproj(int, void* )
    MatND hist;
    int histSize = MAX( bins, 2 );
    float hue_range[] = { 0, 180 };
    const float* ranges = { hue_range };
  7. Calculate the Histogram and normalize it to the range \([0,255]\)
    calcHist( &hue, 1, 0, Mat(), hist, 1, &histSize, &ranges, true, false );
    normalize( hist, hist, 0, 255, NORM_MINMAX, -1, Mat() );
  8. Get the Backprojection of the same image by calling the function cv::calcBackProject
    MatND backproj;
    calcBackProject( &hue, 1, 0, hist, backproj, &ranges, 1, true );
    all the arguments are known (the same as used to calculate the histogram), only we add the backproj matrix, which will store the backprojection of the source image (&hue)
  9. Display backproj:
    imshow( "BackProj", backproj );
  10. Draw the 1-D Hue histogram of the image:
    int w = 400; int h = 400;
    int bin_w = cvRound( (double) w / histSize );
    Mat histImg = Mat::zeros( w, h, CV_8UC3 );
    for( int i = 0; i < bins; i ++ )
    { rectangle( histImg, Point( i*bin_w, h ), Point( (i+1)*bin_w, h - cvRound(<float>(i)*h/255.0 ) ), Scalar( 0, 0, 255 ), -1 ); }
    imshow( "Histogram", histImg );


Here are the output by using a sample image ( guess what? Another hand ). You can play with the bin values and you will observe how it affects the results: