opencv视频跟踪「建议收藏」

什么是对象跟踪?简而言之,在视频的连续帧中定位对象称为跟踪。该定义听起来很直接,但在计算机视觉和机器学习中,跟踪是一个非常广泛的术语,涵盖概念上相似但技术上不同的想法。例如,通常在对象跟踪下研究以下所有不同但相关的想法密集光流:这些算法有助于估计视频帧中每个像素的运动矢量。 稀疏光流:这些算法,如Kanade-Lucas-Tomashi(KLT)特征跟踪器,跟踪图像中几个特征点的位置…

大家好,又见面了,我是你们的朋友全栈君。

什么是对象跟踪?

简而言之,在视频的连续帧中定位对象称为跟踪

该定义听起来很直接,但在计算机视觉和机器学习中,跟踪是一个非常广泛的术语,涵盖概念上相似但技术上不同的想法。例如,通常在对象跟踪下研究以下所有不同但相关的想法

  1. 密集光流:这些算法有助于估计视频帧中每个像素的运动矢量。
  2. 稀疏光流:这些算法,如Kanade-Lucas-Tomashi(KLT)特征跟踪器,跟踪图像中几个特征点的位置。
  3. 卡尔曼滤波:一种非常流行的信号处理算法,用于根据先前的运动信息预测运动物体的位置。该算法的早期应用之一是导弹制导!还提到这里,“是指导阿波罗11号登月舱的降落到月球车载计算机有一个卡尔曼滤波器”。
  4. Meanshift和Camshift:这些是用于定位密度函数的最大值的算法。它们也用于跟踪。
  5. 单个对象跟踪器:在此类跟踪器中,第一帧使用矩形标记,以指示我们要跟踪的对象的位置。然后使用跟踪算法在后续帧中跟踪对象。在大多数实际应用中,这些跟踪器与物体检测器结合使用。
  6. 多个对象跟踪查找算法:在我们有快速对象检测器的情况下,检测每个帧中的多个对象然后运行跟踪查找算法来识别一个帧中的哪个矩形对应于下一帧中的矩形是有意义的。

跟踪与检测

如果你曾经玩过OpenCV人脸检测,你知道它可以实时工作,你可以轻松地检测每一帧中的脸部。那么,为什么你需要首先进行跟踪?让我们探讨一下您可能想要跟踪视频中对象的不同原因,而不仅仅是重复检测。

  1. 跟踪比检测更快:通常跟踪算法比检测算法更快。原因很简单。当您跟踪在前一帧中检测到的对象时,您对该对象的外观了解很多。您还可以知道前一帧中的位置以及其运动的方向和速度。因此,在下一帧中,您可以使用所有这些信息来预测下一帧中对象的位置,并围绕对象的预期位置进行小搜索,以准确定位对象。一个好的跟踪算法将使用它对该对象的所有信息,而检测算法总是从头开始。因此,在设计有效系统时,通常每隔n 次运行一次物体检测在其间的n-1帧中采用跟踪算法的帧。为什么我们不直接检测第一帧中的对象并随后跟踪?确实,跟踪可以从它拥有的额外信息中受益,但是当它们长时间落在障碍物后面时,或者如果它们移动速度太快以至于跟踪算法无法赶上时,您也可能会失去对象的跟踪。跟踪算法累积错误也很常见,跟踪对象的边界框会慢慢偏离其正在跟踪的对象。为了通过跟踪算法解决这些问题,每隔一段时间运行一次检测算法。检测算法在对象的大量示例上进行训练。因此,他们对对象的一般类有更多的了解。另一方面,
  2. 当检测失败时,跟踪可以提供帮助:如果您在视频上运行人脸检测器并且人脸被对象遮挡,则人脸检测器很可能会失败。另一方面,良好的跟踪算法将处理某种程度的遮挡。在下面的视频中,您可以看到MIL跟踪器的作者Boris Babenko博士演示MIL跟踪器如何在遮挡下工作。
  3. 跟踪保留标识:对象检测的输出是包含对象的矩形数组。但是,该对象没有附加标识。例如,在下面的视频中,检测红点的检测器将输出对应于它在帧中检测到的所有点的矩形。在下一帧中,它将输出另一个矩形数组。在第一帧中,特定点可以由阵列中位置10处的矩形表示,并且在第二帧中,它可以在位置17处。当在帧上使用检测时,我们不知道哪个矩形对应于哪个对象。另一方面,跟踪提供了一种字面连接点的方法!

#include <opencv2/opencv.hpp>

#include <opencv2/tracking.hpp>

#include <opencv2/core/ocl.hpp>

 

using namespace cv;

using namespace std;

 

// Convert to string

#define SSTR( x ) static_cast< std::ostringstream & >( \

( std::ostringstream() << std::dec << x ) ).str()

 

int main(int argc, char **argv)

{

    // List of tracker types in OpenCV 3.4.1

    string trackerTypes[8] = {
"BOOSTING", "MIL", "KCF", "TLD","MEDIANFLOW", "GOTURN", "MOSSE", "CSRT"};

    // vector <string> trackerTypes(types, std::end(types));

 

    // Create a tracker

    string trackerType = trackerTypes[2];

 

    Ptr<Tracker> tracker;

 

    #if (CV_MINOR_VERSION < 3)

    {

        tracker = Tracker::create(trackerType);

    }

    #else

    {

        if (trackerType == "BOOSTING")

            tracker = TrackerBoosting::create();

        if (trackerType == "MIL")

            tracker = TrackerMIL::create();

        if (trackerType == "KCF")

            tracker = TrackerKCF::create();

        if (trackerType == "TLD")

            tracker = TrackerTLD::create();

        if (trackerType == "MEDIANFLOW")

            tracker = TrackerMedianFlow::create();

        if (trackerType == "GOTURN")

            tracker = TrackerGOTURN::create();

        if (trackerType == "MOSSE")

            tracker = TrackerMOSSE::create();

        if (trackerType == "CSRT")

            tracker = TrackerCSRT::create();

    }

    #endif

    // Read video

    VideoCapture video("videos/chaplin.mp4");

     

    // Exit if video is not opened

    if(!video.isOpened())

    {

        cout << "Could not read video file" << endl;

        return 1;

    }

 

    // Read first frame

    Mat frame;

    bool ok = video.read(frame);

 

    // Define initial bounding box

    Rect2d bbox(287, 23, 86, 320);

 

    // Uncomment the line below to select a different bounding box

    // bbox = selectROI(frame, false);

    // Display bounding box.

    rectangle(frame, bbox, Scalar( 255, 0, 0 ), 2, 1 );

 

    imshow("Tracking", frame);

    tracker->init(frame, bbox);

     

    while(video.read(frame))

    {    

        // Start timer

        double timer = (double)getTickCount();

         

        // Update the tracking result

        bool ok = tracker->update(frame, bbox);

         

        // Calculate Frames per second (FPS)

        float fps = getTickFrequency() / ((double)getTickCount() - timer);

         

        if (ok)

        {

            // Tracking success : Draw the tracked object

            rectangle(frame, bbox, Scalar( 255, 0, 0 ), 2, 1 );

        }

        else

        {

            // Tracking failure detected.

            putText(frame, "Tracking failure detected", Point(100,80), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0,0,255),2);

        }

         

        // Display tracker type on frame

        putText(frame, trackerType + " Tracker", Point(100,20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(50,170,50),2);

         

        // Display FPS on frame

        putText(frame, "FPS : " + SSTR(int(fps)), Point(100,50), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(50,170,50), 2);

 

        // Display frame.

        imshow("Tracking", frame);

         

        // Exit if ESC pressed.

        int k = waitKey(1);

        if(k == 27)

        {

            break;

        }

 

    }

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/127650.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • dategrip激活码(JetBrains全家桶)

    (dategrip激活码)本文适用于JetBrains家族所有ide,包括IntelliJidea,phpstorm,webstorm,pycharm,datagrip等。https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~C…

    2022年3月31日
    89
  • Apache struts2远程命令执行_CVE-2017-9805(S2-052)漏洞复现「建议收藏」

    Apache struts2远程命令执行_CVE-2017-9805(S2-052)漏洞复现「建议收藏」Apachestruts2远程命令执行_CVE-2017-9805(S2-052)漏洞复现一、漏洞概述ApacheStruts2的REST插件存在远程代码执行的高危漏洞,Struts2REST插件的XStream插件的XStream组件存在反序列化漏洞,使用XStream组件对XML格式的数据包进行反序列化操作时,未对数据内容进行有效验证,存在安全隐患,可被远程攻击。二…

    2022年7月14日
    39
  • Nginx(四):Nginx配置实战

    Nginx(四):Nginx配置实战

    2021年10月5日
    57
  • 问题解决——SolidWorks 已停止工作 (Windows7 + SolidWorks 2010 SP0.0)

    问题解决——SolidWorks 已停止工作 (Windows7 + SolidWorks 2010 SP0.0)

    2022年1月27日
    64
  • 多元logistic回归模型——spss步骤

    多元logistic回归模型——spss步骤多元 因变量为多分类变量 结果在三种及三种以上 如 机构养老 社区养老 居家养老 自变量 可以是分类变量或连续变量 建议是分类变量 协变量 必须是分类变量 案例 步骤 1 分析 回归 多项 logistic 打开主面板 因变量 自变量分别按照箭头指示移入对应的变量框内 点击 参考类别 按钮 默认勾选 最后一个类别 指以因变量和自变量的最后一个分类水平为参照 用其他分类依次与之对比 考察不同水平间的倾向 2 主面板中 点击 模型 打开 多项 logistic 回归 模型 对话框 勾

    2025年7月5日
    1
  • 实现labelme批量json_to_dataset方法

    实现labelme批量json_to_dataset方法labelme可以帮助我们快速的实现Mask-RCNN中数据集json文件的生成,然而还需要我们进一步的将json转成dataset,可以直接在cmd中执行labelme_json_to_dataset.exeC:\Users\Administrator\Desktop\total\1.json(路径),但是这个过程需要我们一个json文件的生成,过程很慢。一、打开abelm…

    2022年9月11日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号