Ask Your Question

Using Hue and Saturation to calculate Backprojection of an object

asked 2012-07-12 18:13:42 -0600

imran gravatar image

updated 2012-07-16 02:42:26 -0600

Kirill Kornyakov gravatar image

In OpenCV it is possible to calculate the backprojection of a selected area using only the Hue component in the HSV image (CamSHIFT example). I am trying to do the same thing but using both the Hue and Saturation components to compute the backprojection. I am not sure whether I am doing it correctly. Below is my code,

The functions that I am not to sure about are

  • int ch[] = { 0,0, 1,0}; // here from what I understand, for the variable fromTo needed in the mixChannels function, does this hsv[0]->hue[0], hsv[0]->saturation[1]
  • mixChannels(&hsv, 1, out, 2, ch, 2); // from what I understand should split, hue and saturation from hsv
  • calcHist(planes[1], 1, 0, maskroi, hist, 1, hdims, ranges);

If someone has done something similar, could you please advise.


Mat backProjectObject(Mat frame, Point pnt){

   int hsize = 16, ssize = 16;
   int hdims[] = { hsize, ssize };
   float h_ranges[] = { 0,180 };
   float s_ranges[] = { 0,255 };
   const float* ranges[] = { h_ranges, s_ranges };

   Mat hsv, hue, saturation, mask, histimg = Mat::zeros(200, 320, CV_8UC3);
   MatND hist, backproj;

   Rect selection;
   int vmin = 10, vmax = 256, smin = 30;

   cvtColor(frame, hsv, CV_BGR2HSV);

   selection.x = pnt.x; //selected center for the area
   selection.y = pnt.y; //selected center for the area
   selection.width = 20; //selected center for the area
   selection.height = 20; //selected center for the area

   selection &= Rect(0, 0, frame.cols, frame.rows);

   int _vmin = vmin, _vmax = vmax;

   inRange(hsv, Scalar(0, smin, MIN(_vmin,_vmax)), Scalar(180, 256, MAX(_vmin, _vmax)), mask);
   hue.create(hsv.size(), hsv.depth());
   saturation.create(hsv.size(), hsv.depth());
   Mat out[] = { hue, saturation };
   int ch[] = { 0,0, 1,0};
   Mat planes[2][2];

   mixChannels(&hsv, 1, out, 2, ch, 2);

   planes[0][0] = hue; 
   planes[0][1] = saturation;

   Mat roi1(hue, selection), roi2(saturation, selection), maskroi(mask, selection);

   planes[1][0] = roi1; //selected template
   planes[1][1] = roi2; //selected template        

   calcHist(planes[1], 1, 0, maskroi, hist, 1, hdims, ranges);
   normalize(hist, hist, 0, 255, CV_MINMAX);

   calcBackProject(planes[0], 1, 0, hist, backproj, ranges);
   backproj &= mask;
   threshold( backproj, backproj, 250, 255,0 );

   return backproj;


edit retag flag offensive close merge delete


@Thiago Thanks for the solution, but it is much different in C++. If anyone has a C++ version could you please advise me.

imran gravatar imageimran ( 2012-07-17 03:52:02 -0600 )edit

@rics I implemented it in the old OpenCV version but can't seem to do it in the new OpenCV. @kevin I had a look at the CookBook particularly pages 108-112 but it isn't the same thing. I need to do what Thiago does but in C++.

imran gravatar imageimran ( 2012-07-17 03:54:55 -0600 )edit

3 answers

Sort by ยป oldest newest most voted

answered 2012-07-16 17:55:45 -0600

Thiago Santos gravatar image

This is a Python solution, but you can port it to C++ easily.

training = cv2.imread('sample.jpg')
gray = cv2.imread('sample.jpg', cv2.CV_LOAD_IMAGE_GRAYSCALE)


val, mask = cv2.threshold(gray, 128, 255, cv2.THRESH_BINARY)


Compute the histogram:

hsv = cv2.cvtColor(training, cv2.COLOR_BGR2HSV)
h = cv2.calcHist([hsv], channels=[0,1], mask=mask, histSize=[36,50], ranges=[0,180,0,255])


test = cv2.imread('test.jpg')
test_hsv = cv2.cvtColor(test, cv2.COLOR_BGR2HSV)
skin = cv2.calcBackProject([test_hsv], [0,1], h, ranges=[0,180,0,255], scale=1.0)


edit flag offensive delete link more

answered 2012-07-14 15:56:51 -0600

rics gravatar image

Without checking your code I can suggest you to have a look at example codes of Learning OpenCV book here because it contains a hue-saturation backprojection example.

edit flag offensive delete link more


Unfortunately that book documents the old C way and not the newer 2.0.

kevin gravatar imagekevin ( 2012-07-15 20:51:39 -0600 )edit

Yes, it does but it is still a working version of hue-saturation histograms. The new book, including C++ examples, is expected to come in 2012 September.

rics gravatar imagerics ( 2012-07-16 01:45:49 -0600 )edit

answered 2012-07-15 20:55:25 -0600

kevin gravatar image

Try the OpenCV 2 Cookbook ... there are some good examples in there.

Also, when you download the OpenCV source code, take a look at the camshiftdemo.cpp samples/cpp subfolder. That is a histogram example.

edit flag offensive delete link more

Question Tools



Asked: 2012-07-12 18:13:42 -0600

Seen: 7,412 times

Last updated: Jul 16 '12