使用opencv的tracking模块跟踪目标

OpenCV跟踪模块算法介绍

OpenCV的tracking模块是一个功能强大的跟踪算法库,包含多种用于跟踪对象的算法。它可以帮助你在连续的视频帧中定位一个物体,例如人脸、眼睛、车辆等。

在OpenCV的tracking模块中,一些主要的跟踪算法包括:

  • 稀疏光流(Sparse optical flow):例如Kanade-Lucas-Tomashi (KLT)特征跟踪算法,跟踪图像中几个特征点的位置。
  • 卡尔曼滤波(Kalman Filtering):一种非常流行的基于先验运动信息的信号处理算法,用于预测运动目标的位置。这种算法的早期应用之一是导弹制导。
  • Meanshift和Camshift:这是定位密度函数最大值的算法,它们还用于跟踪。
    单目标跟踪器(Single object trackers):在这类跟踪器中,第一个帧使用矩形标记,以指示要跟踪的对象的位置。然后使用跟踪算法在后续帧中跟踪对象。在大多数实际应用程序中,这些跟踪器与对象检测器一起使用。
  • 多目标跟踪查找算法(Multiple object track finding algorithms):当我们有一个快速的目标检测器时,在每一帧中检测多个对象,然后运行一个跟踪查找算法来识别一个帧中的哪个矩形与下一个帧中的矩形相对应是有意义的。

这些算法各有优缺点,可以根据实际应用场景选择适合的算法。

具体调用步骤如下:

  1. 打开视频帧第一帧

  2. 框选目标,每选择一个目标按Enter键确认选择

  3. 按Esc退出框选模式

  4. 程序执行跟踪算法并绘制预测框

    #include <opencv2/opencv.hpp>
    #include <opencv2/tracking.hpp>
    #include "timestamp.hpp"

    using namespace cv;
    using namespace std;

    //加载静态库
    #if defined(_WIN32)&&defined(_DEBUG)
    #pragma comment(lib, "opencv_world346d.lib")
    #elif defined(_WIN32)
    #pragma comment(lib, "opencv_world346.lib")
    #endif

    // 支持的跟踪算法
    vector<string> trackerTypes = { "BOOSTING", "MIL", "KCF", "TLD", "MEDIANFLOW", "GOTURN", "MOSSE", "CSRT" };

    // 根据名字创建跟踪器
    Ptr<Tracker> createTrackerByName(string trackerType)
    {
    Ptr<Tracker> tracker;
    if (trackerType == trackerTypes[0])
    tracker = TrackerBoosting::create();
    else if (trackerType == trackerTypes[1])
    tracker = TrackerMIL::create();
    else if (trackerType == trackerTypes[2])
    tracker = TrackerKCF::create();
    else if (trackerType == trackerTypes[3])
    tracker = TrackerTLD::create();
    else if (trackerType == trackerTypes[4])
    tracker = TrackerMedianFlow::create();
    else if (trackerType == trackerTypes[5])
    tracker = TrackerGOTURN::create();
    else if (trackerType == trackerTypes[6])
    tracker = TrackerMOSSE::create();
    else if (trackerType == trackerTypes[7])
    tracker = TrackerCSRT::create();
    else {
    cout << "Incorrect tracker name" << endl;
    cout << "Available trackers are: " << endl;
    for (vector<string>::iterator it = trackerTypes.begin(); it != trackerTypes.end(); ++it)
    std::cout << " " << *it << endl;
    }
    return tracker;
    }

    // Fill the vector with random colors
    void getRandomColors(vector<Scalar> &colors, int numColors)
    {
    RNG rng(0);
    for (int i = 0; i < numColors; i++)
    colors.push_back(Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)));
    }

    int help(char* argv[])
    {
    std::cout << "please input arguments:" << argv[0] << "tracktype video.mp4 videoiotype"<< std::endl;

     return -1;
    

    }

    int main(int argc, char * argv[])
    {
    if(argc < 4){
    return help(argv);
    }

     cout << "默认算法是CSRT" << endl;
     cout << "支持的算法包括:" << endl;
     for (vector<string>::iterator it = trackerTypes.begin(); it != trackerTypes.end(); ++it)
         std::cout << " " << *it << endl;
    
     // 设置跟踪器类型。更改此设置以尝试不同的跟踪器。	字符串 trackerType;
     if(atoi(argv[1]) == 0)
         trackerType = "MOSSE";
     else if(atoi(argv[1]) == 1)
         trackerType = "KCF";
     else
         trackerType = "CSRT";
    
     // 设置跟踪算法和视频的默认值
     string videoPath = argv[2];
    
     // 使用跟踪算法初始化 MultiTracker
     vector<Rect> bboxes;
    
     // 创建视频捕获对象以读取视频
     cv::VideoCapture cap;
     if(atoi(argv[3]) == 0)
         cap.open(0);
     else{
         cap.open(videoPath);
     }
    
     Mat frame;
    
     // 如果取消读取视频文件,则退出
     if (!cap.isOpened())
     {
         cout << "Error opening video file " << videoPath << endl;
         return -1;
     }
    
     // read first frame
     cap >> frame;
    
     // 在对象上绘制边界框
     // selectROI 的默认行为是从中心开始绘制框
     // 当 fromCenter 设置为 false 时,可以从左上角开始绘制框
     bool showCrosshair = true;
     bool fromCenter = false;
     cout << "\n==========================================================\n";
     cout << "OpenCV 表示按 c 取消对象选择过程" << endl;
     cout << "这是行不通的。按 Esc 键退出选择过程" << endl;
     cout << "\n==========================================================\n";
     cv::selectROIs("MultiTracker", frame, bboxes, showCrosshair, fromCenter);
    
     // quit if there are no objects to track
     if (bboxes.size() < 1)
         return 0;
    
     vector<Scalar> colors;
     getRandomColors(colors, bboxes.size());
    
     // 创建多跟踪器
     Ptr<MultiTracker> multiTracker = cv::MultiTracker::create();
    
     // 初始化 Multitracker
     for (int i = 0; i < bboxes.size(); i++)
         multiTracker->add(createTrackerByName(trackerType), frame, Rect2d(bboxes[i]));
    
     // 处理视频和跟踪对象
     cout << "\n==========================================================\n";
     cout << "开始跟踪,按 ESC 键退出。" << endl;
     while (cap.isOpened())
     {
         // 从视频中获取帧
         cap >> frame;
    
         // 如果到达视频末尾,请停止程序
         if (frame.empty()) break;
         {
             timestamp ti("update");
             // 使用新帧更新跟踪结果
             multiTracker->update(frame);
         }
    
         // 绘制跟踪对象
         for (unsigned i = 0; i < multiTracker->getObjects().size(); i++)
         {
             rectangle(frame, multiTracker->getObjects()[i], colors[i], 2, 1);
         }
    
         // 显示帧
         imshow("MultiTracker1", frame);
    
         // 退出 X 按钮
         if (waitKey(1) == 27) break;
    
     }
    

    }

相关推荐
limingade1 小时前
手机实时提取SIM卡打电话的信令和声音-新的篇章(一、可行的方案探讨)
物联网·算法·智能手机·数据分析·信息与通信
jiao000014 小时前
数据结构——队列
c语言·数据结构·算法
迷迭所归处5 小时前
C++ —— 关于vector
开发语言·c++·算法
leon6255 小时前
优化算法(一)—遗传算法(Genetic Algorithm)附MATLAB程序
开发语言·算法·matlab
CV工程师小林5 小时前
【算法】BFS 系列之边权为 1 的最短路问题
数据结构·c++·算法·leetcode·宽度优先
Navigator_Z6 小时前
数据结构C //线性表(链表)ADT结构及相关函数
c语言·数据结构·算法·链表
Aic山鱼6 小时前
【如何高效学习数据结构:构建编程的坚实基石】
数据结构·学习·算法
white__ice6 小时前
2024.9.19
c++
天玑y6 小时前
算法设计与分析(背包问题
c++·经验分享·笔记·学习·算法·leetcode·蓝桥杯
姜太公钓鲸2336 小时前
c++ static(详解)
开发语言·c++