Advertisement

Opencv之目标追踪大法:单目标与多目标追踪

阅读量:

Opencv之目标追踪大法:单目标/多目标追踪

  • 武汉加油,中国加油
  • 单目标追踪
  • 多目标追踪

武汉加油,中国加油

在家无聊,一开始准备用模板匹配写一个目标追踪,今天逛论坛,发现Opencv自带追踪大法,赶紧了一番,发现效果还行,速度快的不要不要的。
但是缺陷也是非常的明显,准确度不敢恭维,非常容易丢目标,误差不断累积,以至于最后越来越不准确,还有就是目标消失后,矩形框会一直存在。
话不多说,直接上代码,注释很详细,不多解释。
其实单目标追踪跟多目标追踪的方法是一样的具体如下,自由发挥。

单目标追踪

复制代码
    #include <opencv2/core/utility.hpp>
    #include <opencv2/tracking.hpp>
    #include <opencv2/videoio.hpp>
    #include <opencv2/highgui.hpp>
    #include <iostream>
    #include <cstring> 
    using namespace std;
    using namespace cv; 
    int main(){    
     Rect2d roi;    
     Mat frame;    
     //实例化跟踪器
     Ptr<TrackerKCF> tracker = TrackerKCF::create();
     //载入视频
     string video = "C:\ Users\ 14587\ Desktop\ test1.mp4"; 
     VideoCapture cap(video);
     //载入摄像头
     //VideoCapture cap(0);
     if (!cap.isOpened())    
     {     
      printf("can not load video");
      return 0;    
     }    
     cout << "按s进入目标选择" << endl;   
     cout << "按空格键进入目标追踪" << endl; 
     cout << "按q退出" << endl;
     cap >> frame;  
     while (1)   
     {        
      char key = waitKey(15);    
      // 按d跳下一帧   
      cap >> frame;
      resize(frame, frame, Size(600, 400));
      // 按s进入目标选择
      if (key == 's')     
      {        
       break;     
      }    
      namedWindow("目标选择", WINDOW_NORMAL);
      imshow("目标选择", frame);   
     }    
     //销毁第一个窗口进入追踪窗口
     destroyWindow("目标选择"); 
     //鼠标框选ROL目标
     roi = selectROI("tracker", frame);  
     if (roi.width == 0 || roi.height == 0)   
      return 0;   
     //init 初始化最初要跟踪的区域
     tracker->init(frame, roi);    
     //进入追踪
     printf("开始追踪\n");   
     while(cap.read( frame) ){   
      resize(frame, frame, Size(600, 400));
      // 播放完销毁窗口  
      if (frame.rows == 0 || frame.cols == 0) {    
       destroyWindow("tracker");        
       break;       
      }        
      // update 有新的数据来之后更新位置        
      tracker->update(frame, roi);    
      // 绘制矩形框  
      rectangle(frame, roi, Scalar(255, 0, 0), 2, 1);     
      // 窗口显示  
      imshow("tracker", frame);  
      waitKey(30);
      // q退出    
      if (char(waitKey(1)) == 'q') 
      {     
       destroyWindow("tracker");       
       break;      
      }   
     }    
     return 0;
    }
    
    cpp
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-07-12/6YdDhmgW8OKzcuCV9vqsRUL1yanX.png)
在这里插入图片描述

多目标追踪

复制代码
    #include<opencv2\opencv.hpp>
    #include<opencv2\tracking.hpp>
    using namespace cv;
    using namespace std;
    int main(int arc, char** argv)
    {
     //加载摄像头
     //VideoCapture capture(0);
     //加载视频文件
     VideoCapture capture;
     capture.open("C:\ Users\ 14587\ Desktop\ test1.mp4");
     if (!capture.isOpened())
     {
      printf("can not load video");
      return 0;
     }
     cout << "按s进入目标选择" << endl;
     cout << "按enter/space确定选择" << endl;
     cout << "按c取消选择" << endl;
     cout << "按esc进入追踪" << endl;
     //实例化一个多目标跟踪器的对象        
     MultiTracker trackers;
     Mat frame;
     capture.read(frame);
     //进入帧目标选择
     while (1)
     {
      char key = waitKey(15);
      capture >> frame;
      // 按s进入目标选择
      if (key == 's')
      {
       break;
      }
      //调整视频大小
      resize(frame, frame, Size(600, 400));
      namedWindow("目标选择", CV_WINDOW_AUTOSIZE);
      imshow("目标选择", frame);
     }
     //鼠标选择目标
     resize(frame, frame, Size(600, 400));
     vector<Rect> rois;
     selectROIs("目标选择", frame, rois, false);
     //传入的边界框数据类型是Rect2d,因为涉及到计算,所以需要double类型,需要转换一下。 
     vector<Rect2d> obj;
     vector<Ptr<Tracker>> algorithms;
     for (auto i = 0; i < rois.size(); i++)
     {
      obj.push_back(rois[i]);
      algorithms.push_back(TrackerKCF::create());
     }
     //添加目标 
     trackers.add(algorithms, frame, obj);
     destroyWindow("目标选择");
     //进入追踪
     while (capture.read(frame))
     { 
      //调整视频大小
      resize(frame, frame, Size(600, 400));
      //更新目标  
      trackers.update(frame, obj);
      //绘制矩形框
      for (auto j = 0; j < obj.size(); j++)
      {
       rectangle(frame, obj[j], Scalar(255, 0, 0), 2, 1);
      }
      namedWindow("目标追踪", CV_WINDOW_AUTOSIZE);
      imshow("目标追踪", frame);
      char c = waitKey(15);
      if (c == 27)
      {
       break;
      }
     }
     waitKey(0);
     return 0;
    }
    
    cpp
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-07-12/a0odGb5pUkOFLByhjXIEQfC63lJx.png)
在这里插入图片描述

全部评论 (0)

还没有任何评论哟~