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)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • python控制mt4自动交易软件下载_MT4 EA智能自动交易系统使用教程[通俗易懂]

    python控制mt4自动交易软件下载_MT4 EA智能自动交易系统使用教程[通俗易懂]1.首先,你要有一个EA,必须要有以ex4为扩展名的,如果只有mq4文件的话,就要用MetaTrader自带的编辑器MetaEditor打开,将mq4通过编译(compile)并且要不出现错误,才能在原存放mq4的文件夹下面得到一个同名的ex4文件。2.将这个ex4文件复制到MetaTrader4所在的文件夹下面的experts文件夹下,比如:D:\ProgramFiles\ACTCMeta…

    2022年5月30日
  • windows 执行 bat命令问题

    windows 执行 bat命令问题window环境下,通过DOS命令模式,调用bat脚本,执行jar包。可以正常打印jar包中的日志都指定日志文件。通过tomcat部署的某服务去调用时出现不可调用,也不打印日志问题。分两步来确定问题:1、参数是否传递给bat脚本;2、bat脚本中的java-jar是否正常执行了;问题1通过,在bat脚本入口处增加echoname:%1age:%2&gt;&g…

    2022年10月26日
  • JavaScript实现哈希表数据结构[通俗易懂]

    一、简单说明1、JavaScript是没有哈希表数据结构的,那么当我们需要用到类似哈希表这样的键值对数据结构时怎么办?答案就是自己实现一个,我们可以利用JavaScript的一些特性来实现自己的哈希表数据结构。2、首先,哈希表是一种键值对数据结构,键是唯一的,这个特征跟JavaScript的Object对象有点类似,Object对象的属性是唯一的,属性和值的映射就像是键值对一样,那么我们可以用一个…

    2022年4月9日
  • Java 程序员必须掌握的 4 大开源框架!

    Java 程序员必须掌握的 4 大开源框架!对于开发来说,我们在工作中普遍都会用到各个开源框架,比如最基础的Spring,使开发网络编程变得特别简单的Netty框架,还有成为目前微服务框架首选的SpringCloud等。在多个框架之上,我们仅需使用几行代码,即可实现业务需要的复杂功能,大大减少了工作量。也正因如此,不少人只会用框架,看不懂源码,不了解其底层机制与实现原理,成了一名只会搬运源码库的开发。说白了,就是真正牛逼的技术不属于你。可了解框架中的很多知识和代码,对解决开发中的类似问题是极其有帮助的。因为它们是经过时..

    2022年7月8日
  • 微信公众平台 获取用户openid

    微信公众平台 获取用户openid今天做微信公众号获取用户的openid,圆满成功,特此来一发。 第一步:理解逻辑。 1:获取openid的逻辑获得微信的openid,需要先访问微信提供的一个网址:这个网址名为url1,下面有赋值。通过这个网址,微信用来识别appid信息,在这个网址中,有一个属性redirect_uri,是微识别完appid后,进行跳转的操作,可以是网页,也可以是servlet,我这里用的是…

    2022年6月26日
  • 服务器pci数据捕获和信号处理 感叹号,PCI数据捕获和信号处理控制器win7驱动

    服务器pci数据捕获和信号处理 感叹号,PCI数据捕获和信号处理控制器win7驱动这是PCI数据捕获和信号处理控制器win7驱动下载,有些电脑在安装了系统后会在设备管理器中出现PCI数据捕获和信号处理控制器黄色感叹号提示,此时需要安装“IntelTurboBoost”驱动软件。软件介绍有时候我们装完系统的时候,各种驱动都安装完毕了,然后发现系统属性里面的设备管理器其他设备—PCI数据捕获和信号处理器控制器上还是有个问号,此款驱动就是解决这个问题的。PCI数据捕获和信号处理…

    2022年6月1日

发表回复

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

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