# Using Hue and Saturation to calculate Backprojection of an object

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);

\\code

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;

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);
threshold( backproj, backproj, 250, 255,0 );

return backproj;


}

edit retag 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.

( 2012-07-17 03:52:02 -0500 )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++.

( 2012-07-17 03:54:55 -0500 )edit

Sort by ยป oldest newest most voted

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

training = cv2.imread('sample.jpg')


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


Compute the histogram:

hsv = cv2.cvtColor(training, cv2.COLOR_BGR2HSV)


Finally:

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)


more

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.

more

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

( 2012-07-15 20:51:39 -0500 )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.

( 2012-07-16 01:45:49 -0500 )edit

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.

more

Official site

GitHub

Wiki

Documentation