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;
}

在这里插入图片描述

多目标追踪

#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;
}

在这里插入图片描述

发布了7 篇原创文章 · 获赞 15 · 访问量 1747

猜你喜欢

转载自blog.csdn.net/weixin_44747240/article/details/104109997
今日推荐