In this tutorial, you are learn how to segment a colored object using a web-cam. We will use inRange() algorithm to segment the moving colored object and draw contour or boundary boxes around the tracked object.
Mat roi_RGB(image, selection); // Set ROI by the selection box
Mat roi_HSV;
cvtColor(roi_RGB, roi_HSV, CV_BGR2HSV);
Scalar means, stddev; meanStdDev(roi_HSV, means, stddev);
cout << "\n Selected ROI Means= " << means << " \n stddev= " << stddev;
/// set dst as the output of InRange
inRange(hsv, Scalar(MIN(hmin, hmax), MIN(smin, smax), MIN(vmin, vmax)),
Scalar(MAX(hmin, hmax), MAX(smin, smax), MAX(vmin, vmax)), dst);
Mat image_disp, hsv, hue, mask, dst;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
…
findContours(dst, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
/// Find the Contour with the largest area ///
int idx = 0, largestComp = 0;
double maxArea = 0;
for (; idx >= 0; idx = hierarchy[idx][0])
{
const vector<Point>& c = contours[idx];
double area = fabs(contourArea(Mat(c)));
if (area > maxArea)
{
maxArea = area;
largestComp = idx;
}
}
/// Draw the Contour Box on Original Image ///
drawContours(image_disp, contours, largestComp, Scalar(255, 255, 255), 4, 8, hierarchy);
Rect boxPoint = boundingRect(contours[largestComp]);
rectangle(image_disp, boxPoint, Scalar(255, 0, 255), 3);
/// On mouse event
static void onMouse(int event, int x, int y, int, void*)
{
if (selectObject) // for any mouse motion
{
selection.x = MIN(x, origin.x);
selection.y = MIN(y, origin.y);
selection.width = abs(x - origin.x) + 1;
selection.height = abs(y - origin.y) + 1;
selection &= Rect(0, 0, image.cols, image.rows);
// Bitwise AND check selection is within the image coordinate
}
switch (event)
{
case CV_EVENT_LBUTTONDOWN:
selectObject = true;
origin = Point(x, y);
break;
case CV_EVENT_LBUTTONUP:
selectObject = false;
if (selection.area())
trackObject = true;
break;
}
}