当前位置:网站首页>opencv视频跟踪「建议收藏」
opencv视频跟踪「建议收藏」
2022-07-25 14:04:00 【全栈程序员站长】
大家好,又见面了,我是你们的朋友全栈君。
什么是对象跟踪?
简而言之,在视频的连续帧中定位对象称为跟踪。
该定义听起来很直接,但在计算机视觉和机器学习中,跟踪是一个非常广泛的术语,涵盖概念上相似但技术上不同的想法。例如,通常在对象跟踪下研究以下所有不同但相关的想法
- 密集光流:这些算法有助于估计视频帧中每个像素的运动矢量。
- 稀疏光流:这些算法,如Kanade-Lucas-Tomashi(KLT)特征跟踪器,跟踪图像中几个特征点的位置。
- 卡尔曼滤波:一种非常流行的信号处理算法,用于根据先前的运动信息预测运动物体的位置。该算法的早期应用之一是导弹制导!还提到这里,“是指导阿波罗11号登月舱的降落到月球车载计算机有一个卡尔曼滤波器”。
- Meanshift和Camshift:这些是用于定位密度函数的最大值的算法。它们也用于跟踪。
- 单个对象跟踪器:在此类跟踪器中,第一帧使用矩形标记,以指示我们要跟踪的对象的位置。然后使用跟踪算法在后续帧中跟踪对象。在大多数实际应用中,这些跟踪器与物体检测器结合使用。
- 多个对象跟踪查找算法:在我们有快速对象检测器的情况下,检测每个帧中的多个对象然后运行跟踪查找算法来识别一个帧中的哪个矩形对应于下一帧中的矩形是有意义的。
跟踪与检测
如果你曾经玩过OpenCV人脸检测,你知道它可以实时工作,你可以轻松地检测每一帧中的脸部。那么,为什么你需要首先进行跟踪?让我们探讨一下您可能想要跟踪视频中对象的不同原因,而不仅仅是重复检测。
- 跟踪比检测更快:通常跟踪算法比检测算法更快。原因很简单。当您跟踪在前一帧中检测到的对象时,您对该对象的外观了解很多。您还可以知道前一帧中的位置以及其运动的方向和速度。因此,在下一帧中,您可以使用所有这些信息来预测下一帧中对象的位置,并围绕对象的预期位置进行小搜索,以准确定位对象。一个好的跟踪算法将使用它对该对象的所有信息,而检测算法总是从头开始。因此,在设计有效系统时,通常每隔n 次运行一次物体检测在其间的n-1帧中采用跟踪算法的帧。为什么我们不直接检测第一帧中的对象并随后跟踪?确实,跟踪可以从它拥有的额外信息中受益,但是当它们长时间落在障碍物后面时,或者如果它们移动速度太快以至于跟踪算法无法赶上时,您也可能会失去对象的跟踪。跟踪算法累积错误也很常见,跟踪对象的边界框会慢慢偏离其正在跟踪的对象。为了通过跟踪算法解决这些问题,每隔一段时间运行一次检测算法。检测算法在对象的大量示例上进行训练。因此,他们对对象的一般类有更多的了解。另一方面,
- 当检测失败时,跟踪可以提供帮助:如果您在视频上运行人脸检测器并且人脸被对象遮挡,则人脸检测器很可能会失败。另一方面,良好的跟踪算法将处理某种程度的遮挡。在下面的视频中,您可以看到MIL跟踪器的作者Boris Babenko博士演示MIL跟踪器如何在遮挡下工作。
- 跟踪保留标识:对象检测的输出是包含对象的矩形数组。但是,该对象没有附加标识。例如,在下面的视频中,检测红点的检测器将输出对应于它在帧中检测到的所有点的矩形。在下一帧中,它将输出另一个矩形数组。在第一帧中,特定点可以由阵列中位置10处的矩形表示,并且在第二帧中,它可以在位置17处。当在帧上使用检测时,我们不知道哪个矩形对应于哪个对象。另一方面,跟踪提供了一种字面连接点的方法!
#include <opencv2/opencv.hpp>
#include <opencv2/tracking.hpp>
#include <opencv2/core/ocl.hpp>
usingnamespacecv;
usingnamespacestd;
// Convert to string
#define SSTR( x ) static_cast< std::ostringstream & >( \
( std::ostringstream() << std::dec << x ) ).str()
intmain(intargc, 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;
return1;
}
// Read first frame
Mat frame;
boolok = 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
doubletimer = (double)getTickCount();
// Update the tracking result
boolok = tracker->update(frame, bbox);
// Calculate Frames per second (FPS)
floatfps = 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.
intk = waitKey(1);
if(k == 27)
{
break;
}
}
}
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/127650.html原文链接:https://javaforall.cn
边栏推荐
猜你喜欢

「数字安全」警惕 NFT的七大骗局

职场「数字人」不吃不睡007工作制,你「卷」得过它们吗?

Brush questions - Luogu -p1059 clear random number

What problems should SEOER pay attention to when baidu searches and attacks pirated websites?

Acquisition data transmission mode and online monitoring system of wireless acquisition instrument for vibrating wire sensor of engineering instrument

Interpretation of featdepth self-monitoring model for monocular depth estimation (Part 2) -- use of openmmlab framework

Mongodb source code deployment and configuration

Nuc980 set up SSH xshell connection

Tm1637 four digit LED display module Arduino driver with second dot

OKA通证权益解析,参与Okaleido生态建设的不二之选
随机推荐
MySQL 01: Source command
Brush questions - Luogu -p1047 trees outside the school gate
实现一个家庭安防与环境监测系统(二)
依迅总经理孙峰:公司已完成股改,准备IPO
CDA level Ⅰ 2021 new version simulation question 1 (with answers)
Interpretation of featdepth self-monitoring model for monocular depth estimation (Part 2) -- use of openmmlab framework
Working principle of Lora to 4G and gateway repeater
Goldfish rhca memoirs: cl210 management storage -- object storage
移动端网站,独立APP,网站排名策略有哪些?
伯克利博士『机器学习工程』大实话;AI副总裁『2022 ML就业市场』分析;半导体创业公司大列表;大规模视频人脸属性数据集;前沿论文 | ShowMeAI资讯日报
【配置Hifive1-revB】设备管理器中不识别端口,Can not connect to J-Link via USB的解决办法
Brush questions - Luogu -p1085 unhappy Jinjin
手里有点钱可以投资哪些理财产品?
Depth estimation self-monitoring model monodepth2 paper summary and source code analysis [theoretical part]
mysql 01: source命令
Brush questions - Luogu -p1152 happy jump
[learning record] plt.show() solution to flash back
swiper 一侧或两侧露出一小部分
Brush questions - Luogu -p1075 prime factor decomposition
Brush questions - Luogu -p1035 series summation