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

    }

相关推荐
林开落L7 分钟前
前缀和算法习题篇(上)
c++·算法·leetcode
远望清一色8 分钟前
基于MATLAB边缘检测博文
开发语言·算法·matlab
tyler_download10 分钟前
手撸 chatgpt 大模型:简述 LLM 的架构,算法和训练流程
算法·chatgpt
Prejudices20 分钟前
C++如何调用Python脚本
开发语言·c++·python
单音GG23 分钟前
推荐一个基于协程的C++(lua)游戏服务器
服务器·c++·游戏·lua
SoraLuna30 分钟前
「Mac玩转仓颉内测版7」入门篇7 - Cangjie控制结构(下)
算法·macos·动态规划·cangjie
我狠狠地刷刷刷刷刷33 分钟前
中文分词模拟器
开发语言·python·算法
鸽鸽程序猿34 分钟前
【算法】【优选算法】前缀和(上)
java·算法·前缀和
qing_04060339 分钟前
C++——多态
开发语言·c++·多态
孙同学_40 分钟前
【C++】—掌握STL vector 类:“Vector简介:动态数组的高效应用”
开发语言·c++