使用opencv的tracking模块跟踪目标

本文介绍了OpenCV跟踪模块中的关键算法,如KLT、卡尔曼滤波、Meanshift/Camshift以及不同类型的单目标和多目标追踪器。详细展示了如何在C++中使用这些算法进行对象追踪,包括调用步骤和示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;

    }
}
### OpenCV 中 `tracking.hpp` 文件未找到的原因分析 在使用 OpenCV 进行开发时,如果遇到 `opencv2/tracking.hpp` 文件未找到的问题,通常是因为该模块并未被正确安装或启用。以下是可能原因及其解决方案: #### 1. **确认是否启用了 Tracking 模块** OpenCV 的某些高级功能(如对象跟踪模块)默认情况下不会自动编译到库中。Tracking 模块属于贡献模块 (contrib modules),需要单独下载并配置才能正常使用。 - 如果未启用 contrib 模块,则无法访问 `tracking.hpp` 头文件[^1]。 #### 解决方案: 下载 OpenCV Contrib 库,并确保 CMake 配置阶段启用了 `OPENCV_EXTRA_MODULES_PATH` 参数指向 contrib/modules 路径。具体操作如下: ```bash git clone https://github.com/opencv/opencv_contrib.git cd opencv_contrib git checkout tags/3.1.0 # 确保版本与主库一致 ``` 随后,在构建 OpenCV 时设置额外参数: ```cmake -D OPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules \ -D BUILD_opencv_tracking=ON .. ``` --- #### 2. **头文件路径缺失** 即使已经成功编译了带有 Tracking 模块OpenCV 版本,但如果链接器未能正确识别头文件路径,也可能导致此错误。 - 此类问题通常是由于环境变量或项目配置不完整引起的[^2]。 #### 解决方案: 验证项目的 include 路径是否包含了 OpenCV 安装目录下的子路径 `/include/opencv2` 和其他相关路径。例如: ```cpp #include <opencv2/core.hpp> #include <opencv2/tracking.hpp> // Ensure this is accessible. ``` 对于 Linux 或 macOS 用户,可以通过以下命令检查已安装的 OpenCV 包含哪些头文件: ```bash find /usr/local/include/opencv2 -name "*.hpp" ``` --- #### 3. **动态链接库丢失** 即便头文件存在,如果没有正确加载对应的共享库 (.so/.dll),程序仍然会报错。 - 动态链接库的缺失可能导致运行时崩溃或静态编译失败。 #### 解决方案: 重新生成 Makefile 并执行完整的编译流程,确保所有依赖项均已被正确处理。完成后更新系统的动态链接库缓存: ```bash sudo ldconfig ``` 或者手动指定 LD_LIBRARY_PATH: ```bash export LD_LIBRARY_PATH=/path/to/your/lib:$LD_LIBRARY_PATH ``` --- #### 示例代码片段 下面是一个简单的测试代码,用于验证 Tracking 模块的功能是否可用: ```cpp #include <iostream> #include <opencv2/tracking.hpp> int main() { try { cv::Ptr<cv::Tracker> tracker = cv::TrackerKCF::create(); // 创建 KCF Tracker 实例 std::cout << "Tracking module loaded successfully." << std::endl; } catch (const cv::Exception& e) { std::cerr << "Error loading tracking module: " << e.what() << std::endl; } return 0; } ``` --- ### 总结 通过上述步骤可以有效排查和修复 `opencv2/tracking.hpp` 文件未找到的问题。核心在于确保 contrib 模块已启用、头文件路径无误以及动态链接库正常工作。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

telllong

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值