c++ - Multiple tracking in a Video -
i m working on small image processing assignment need track 4 red color object. got how track single one. want know best approach track more 1 point.
there 4 points positioned form rectangle can use shape detection or corner detection detect , track points please see image below..
my naive implementation uses technique described @ opencv bounding boxes tracking of red blobs.
the following helper function used retrieve center of red objects detected:
/* get_positions: function retrieve center of detected blobs. * largely based on opencv's "creating bounding boxes , circles contours" tutorial. */ std::vector<cv::point2f> get_positions(cv::mat& image) { if (image.channels() > 1) { std::cout << "get_positions: !!! input image must have single channel" << std::endl; return std::vector<cv::point2f>(); } std::vector<std::vector<cv::point> > contours; cv::findcontours(image, contours, cv::retr_list, cv::chain_approx_simple); // approximate contours polygons , center of objects std::vector<std::vector<cv::point> > contours_poly(contours.size()); std::vector<cv::point2f> center(contours.size()); std::vector<float> radius(contours.size()); (unsigned int = 0; < contours.size(); i++ ) { cv::approxpolydp(cv::mat(contours[i]), contours_poly[i], 5, true ); cv::minenclosingcircle((cv::mat)contours_poly[i], center[i], radius[i]); } return center; }
i wrote code test approach in real-time capturing frames webcam. overall procedure quite similar @dennis described (sorry, coding when submitted answer).
ok, fun begins.
int main() { // open capture device. webcam id 0: cv::videocapture cap(0); if (!cap.isopened()) { std::cout << "!!! failed open webcam" << std::endl; return -1; } // let's create few window titles debugging purposes std::string wnd1 = "input", wnd2 = "red objs", wnd3 = "output"; // these hsv values used later isolate red-ish colors int low_h = 160, low_s = 140, low_v = 50; int high_h = 179, high_s = 255, high_v = 255; cv::mat frame, hsv_frame, red_objs; while (true) { // retrieve new frame camera if (!cap.read(frame)) break; cv::mat orig_frame = frame.clone(); cv::imshow(wnd1, orig_frame);
orig_frame
:
// convert bgr frame hsv easier separate colors cv::cvtcolor(frame, hsv_frame, cv_bgr2hsv); // isolate red colored objects , save them in binary image cv::inrange(hsv_frame, cv::scalar(low_h, low_s, low_v), cv::scalar(high_h, high_s, high_v), red_objs); // remove small objects (mostly noises) cv::erode(red_objs, red_objs, cv::getstructuringelement(cv::morph_rect, cv::size(3, 3))); cv::dilate(red_objs, red_objs, cv::getstructuringelement(cv::morph_rect, cv::size(7, 7))); cv::mat objs = red_objs.clone(); cv::imshow(wnd2, objs);
objs
:
// retrieve vector of points (x,y) location of objects std::vector<cv::point2f> points = get_positions(objs); // draw small green circle @ locations educational purposes (unsigned int = 0; < points.size(); i++) cv::circle(frame, points[i], 3, cv::scalar(0, 255, 0), -1, 8, 0); cv::imshow(wnd3, frame);
char key = cv::waitkey(33); if (key == 27) { /* esc pressed */ //cv::imwrite("out1.png", orig_frame); //cv::imwrite("out2.png", red_objs); //cv::imwrite("out3.png", frame); break; } } cap.release(); return 0; }
Comments
Post a Comment