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);
If someone has done something similar, could you please advise.
\\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;
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;
}
@Thiago Thanks for the solution, but it is much different in C++. If anyone has a C++ version could you please advise me.
@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++.