opencv3之目标跟踪(单目标、多目标)

对于刚入门的opencv玩家,提起目标跟踪,马上想起的就是camshift,但是camshift跟踪往往达不到我们的跟踪要求,包括稳定性和准确性。

opencv3.1版本发行后,集成了多个跟踪算法,即tracker,大部分都是近年VOT竞赛榜上有名的算法,虽然仍有缺陷存在,但效果还不错。

ps:我在知乎上看到一个目标跟踪的介绍,感觉不错,链接在此!

单目标跟踪很简单,放一个官方例程供参考(opencv官方):

#include #include #include #include #include #include using namespace std; using namespace cv; int main( int argc, char** argv ){ // show help if(argc<2){ cout<< " Usage: tracker \n" " examples:\n" " example_tracking_kcf Bolt/img/%04d.jpg\n" " example_tracking_kcf faceocc2.webm\n" << endl; return 0; } // declares all required variables Rect2d roi; Mat frame; // create a tracker object Ptr tracker = TrackerKCF::create(); // set input video std::string video = argv[1]; VideoCapture cap(video); // get bounding box cap >> frame; roi=selectROI("tracker",frame); //quit if ROI was not selected if(roi.width==0 || roi.height==0) return 0; // initialize the tracker tracker->init(frame,roi); // perform the tracking process printf("Start the tracking process, press ESC to quit.\n"); for ( ;; ){ // get frame from the video cap >> frame; // stop the program if no more images if(frame.rows==0 || frame.cols==0) break; // update the tracking result tracker->update(frame,roi); // draw the tracked object rectangle( frame, roi, Scalar( 255, 0, 0 ), 2, 1 ); // show image with the tracked object imshow("tracker",frame); //quit on ESC button if(waitKey(1)==27)break; } return 0; }

其中, 跟踪器的创建可选以下几种,代表使用的跟踪算法;

  • MIL
  • BOOSTING
  • MEDIANFLOW
  • TLD
  • KCF

eg-- Ptr tracker = Tracker::create("KCF"); 

多目标跟踪使用的是MultiTracker,如MultiTracker myTracker("KCF"),注意两点,添加目标用其成员函数myTracker.add(Mat src, Rect2d roi),获得跟踪结果使用myTracker.update(Mat src, vector targets),跟踪结果的序号即vector的序号。

以下代码为跟踪鼠标框选的目标,跟踪的目标个数大概为10个(原则上是没有上限的,但我电脑比较烂,目标多了会卡)#include #include "opencv2/opencv.hpp" #include using namespace cv; using namespace std; bool selectObject = false; Point origin;//用于保存鼠标选择第一次单击时点的位置 Rect selection;//用于保存鼠标选择的矩形框 int trackObject = 0; /*------------------------------- 函数功能 显示轨迹 --------------------------------*/ void displayTrajectory(Mat img, vector traj, Scalar s) { if (!traj.empty()) { for (size_t i = 0; i < traj.size() - 1; i++) { line(img, traj[i], traj[i + 1], s, 2, 8, 0); } } } /*------------------------------- 鼠标控制 --------------------------------*/ void onMouse(int event, int x, int y, int, void*) { if (selectObject)//只有当鼠标左键按下去时才有效,然后通过if里面代码就可以确定所选择的矩形区域selection了 { selection.x = MIN(x, origin.x);//矩形左上角顶点坐标 selection.y = MIN(y, origin.y); selection.width = std::abs(x - origin.x);//矩形宽 selection.height = std::abs(y - origin.y);//矩形高 selection &= Rect(0, 0, src.cols, src.rows);//用于确保所选的矩形区域在图片范围内 //rectangle(src,selection,Scalar(0,0,255),2); } switch (event) { case CV_EVENT_LBUTTONDOWN: origin = Point(x, y); selection = Rect(x, y, 0, 0);//鼠标刚按下去时初始化了一个矩形区域 selectObject = true; break; case CV_EVENT_LBUTTONUP: selectObject = false; if (selection.width > 0 && selection.height > 0) trackObject = -1; break; } } int main(int argc, char *argv[]) { namedWindow("tracker"); setMouseCallback("tracker", onMouse(), 0); MultiTracker myTracker("KCF"); vector> trajectorys;//轨迹记录 int objectCounter = 0; VideoCapture cap(0);//打开默认的摄像头 if (!cap.isOpened()) { return -1; } Mat src; bool stop = false; while (!stop) { cap>>src; if (selectObject) { rectangle(src, selection, Scalar(0, 0, 255), 2, 8, 0); } if (trackObject < 0) { myTracker.add(src, selection); Point cen = Point(selection.x + selection.width / 2.0, selection.y + selection.height / 2.0); trajectorys.resize(objectCounter + 1); trajectorys[objectCounter].push_back(cen);//从[0]开始初始化轨迹起始点 objectCounter++;//待跟踪目标个数加1 trackObject = 1; } if (trackObject) { vector r; myTracker.update(src, r); size_t s = r.size(); RNG rng; for (size_t i = 0; i < s; i++) { Scalar scalar = Scalar(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256)); rectangle(src, r[i], scalar, 2, 8, 0); Point C = Point(r[i].x + r[i].width / 2.0, r[i].y + r[i].height / 2.0); trajectorys[i].push_back(C); displayTrajectory(src, trajectorys[i], scalar); char name[10]; sprintf_s(name, "%d", (i + 1)); putText(src, name, r[i].tl(), 3, 0.8, Scalar(0, 255, 255), 2, 8, false); } } imshow("tracker", src); if (waitKey(30) == 27) //Esc键退出 { stop = true; } } return 0; }

你可能感兴趣的:(OPENCV/图像处理,目标跟踪)