[OpenCV实战]15 基于深度学习的目标跟踪算法GOTURN
目录
在这篇文章中,我们将学习一种基于深度学习的目标跟踪算法GOTURN。GOTURN在Caffe中搭建,现在已移植到OpenCV Tracking API,我们将使用此API在C ++和Python中使用GOTURN。
1 什么是对象跟踪和GOTURN
对象跟踪的目标是跟踪视频序列中的对象。使用视频序列的帧和边界框初始化跟踪算法,以获得我们感兴趣的对象的位置。跟踪算法输出所有后续帧的边界框。有关对象跟踪的更多详细信息,请查看我们关于OpenCV目标跟踪API的帖子。
https://blog.csdn.net/LuohenYJ/article/details/89029816
GOTURN是Generic Object Tracking Using Regression Networks的缩写,是一种基于深度学习的跟踪算法。
大多数跟踪算法都以在线方式进行训练。换句话说,跟踪算法学习在运行时不停获取被跟踪对象的特点。因此,许多实时跟踪器依赖于在线学习算法,这些算法通常比基于深度学习的解决方案快得多。GOTURN通过以离线方式学习对象的运动,改变了我们将深度学习应用于跟踪问题的方式。GOTURN模型在数千个视频序列上进行训练,不需要在运行时进行任何学习。
GOTURN主要论文见:
http://davheld.github.io/GOTURN/GOTURN.pdf
如上图所示GOTURN将两个裁剪帧作为输入,并输出第二帧中对象周围的边界框。在第一帧(也称为前一帧)中对象的位置是已知的,裁剪前一帧并且被裁剪帧大小为对象边界框的两倍大小。第一个裁剪框中的对象始终居中。用于裁剪第一帧的边界框也用于裁剪第二帧中对象的位置(也称为当前帧)。由于对象可能已移动,因此对象不在第二帧中居中。训练卷积神经网络(CNN)以预测第二帧中边界框的位置。
下图所示为GOTURN的架构。如前所述,它需要两个裁剪框作为输入。请注意,底部为前一帧,上面为第二帧(当前帧)。我们的目标就是在当前帧画出目标的边界框。
两个帧都通过一组卷积层。即CaffeNet架构的前五个卷积层。这些卷积层的输出被连接成长度为4096的单个矢量。输出层的节点有四个,表示预测框的左上角顶点坐标和右下角顶点坐标。
2 在OpenCV中使用GOTURN
作者发布了GOTURN的caffe模型。您可以使用Caffe尝试,但在本教程中,我们将使用OpenCV的跟踪API。步骤如下:
1)下载GOTURN模型文件
GOTURN的模型文件见:https://github.com/spmallick/goturn-files
需要下载的是GOTURN的caffemodel and prototxt文件。约370 MB。
2)把caffemodel和prototxt文件放到和函数调用文件cpp/py文件同一个目录下,文件名必须为goturn.caffemodel和goturn.prototxt,模型下载下来不用改名字就行了。
3)代码实现,类似其他OpenCV调用模块,OpenCV版本3.4.3以上
依然是创建跟踪函数模型,更新函数模型。当跟踪器失败时,tracker.update返回0(false)。如果我们将跟踪器与检测器一起使用,则可以使用此信息。当跟踪器发生故障时,检测器可用于检测对象并重新初始化跟踪器。
代码下载地址:
https://github.com/luohenyueji/OpenCV-Practical-Exercise
代码如下:
C++:
// GOTURN_SingleTracker.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/tracking.hpp>
using namespace cv;
using namespace std;
int main()
{
// Create tracker
Ptr<Tracker> tracker = TrackerGOTURN::create();
// Read video
VideoCapture video("video/chaplin.mp4");
// Exit if video is not opened
if (!video.isOpened())
{
cout << "Could not read video file" << endl;
return EXIT_FAILURE;
}
// Read first frame
Mat frame;
if (!video.read(frame))
{
cout << "Cannot read video file" << endl;
return EXIT_FAILURE;
}
// Define initial boundibg box
Rect2d bbox(287, 23, 86, 320);
// Uncomment the line below to select a different bounding box
//bbox = selectROI(frame, false);
// Initialize tracker with first frame and bounding box
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, "GOTURN Tracker", Point(100, 20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(50, 170, 50), 2);
// Display FPS on frame
putText(frame, "FPS : " + to_string(int(fps)), Point(100, 50), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(50, 170, 50), 2);
// Display frame.
imshow("Tracking", frame);
// Exit if ESC pressed.
if (waitKey(1) == 27) break;
}
return 0;
}
python:
# Import modules
import cv2, sys, os
if not (os.path.isfile('goturn.caffemodel') and os.path.isfile('goturn.prototxt')):
errorMsg = '''
Could not find GOTURN model in current directory.
Please ensure goturn.caffemodel and goturn.prototxt are in the current directory
'''
print(errorMsg)
sys.exit()
# Create tracker
tracker = cv2.TrackerGOTURN_create()
# Read video
video = cv2.VideoCapture("chaplin.mp4")
# Exit if video not opened
if not video.isOpened():
print("Could not open video")
sys.exit()
# Read first frame
ok,frame = video.read()
if not ok:
print("Cannot read video file")
sys.exit()
# Define a bounding box
bbox = (276, 23, 86, 320)
# Uncomment the line below to select a different bounding box
bbox = cv2.selectROI(frame, False)
# Initialize tracker with first frame and bounding box
ok = tracker.init(frame,bbox)
while True:
# Read a new frame
ok, frame = video.read()
if not ok:
break
# Start timer
timer = cv2.getTickCount()
# Update tracker
ok, bbox = tracker.update(frame)
# Calculate Frames per second (FPS)
fps = cv2.getTickFrequency() / (cv2.getTickCount() - timer);
# Draw bounding box
if ok:
# Tracking success
p1 = (int(bbox[0]), int(bbox[1]))
p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3]))
cv2.rectangle(frame, p1, p2, (255,0,0), 2, 1)
else :
# Tracking failure
cv2.putText(frame, "Tracking failure detected", (100,80), cv2.FONT_HERSHEY_SIMPLEX, 0.75,(0,0,255),2)
# Display tracker type on frame
cv2.putText(frame, "GOTURN Tracker", (100,20), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (50,170,50),2);
# Display FPS on frame
cv2.putText(frame, "FPS : " + str(int(fps)), (100,50), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (50,170,50), 2);
# Display result
cv2.imshow("Tracking", frame)
# Exit if ESC pressed
k = cv2.waitKey(1) & 0xff
if k == 27:
break
3 GOTURN优缺点
与其他基于深度学习的跟踪器相比,GOTURN速度更快。它在Caffe的GPU上以100FPS运行,在OpenCV CPU中以20FPS运行。即使跟踪器是通用的,理论上,通过使用特定类型的对象偏置训练集,可以在特定对象(例如行人)上获得优异的结果。
个人观点:
GOTURN速度和MIL水平差不多,如果是在特定对象上进行目标跟踪,精度能够达到KCF算法的水平。如果不是特定对象,精度和BOOSTING差不多。特定对象是指模型训练集的场景。总的来说GOTURN不推荐,还不如用KCF算法。除非你有大量数据训练GOTURN模型。不过有这个数据和算法还不如训练目标检测模型,每帧都检测。
4 参考
https://www.learnopencv.com/goturn-deep-learning-based-object-tracking/
本文来自博客园,作者:落痕的寒假,转载请注明原文链接:https://www.cnblogs.com/luohenyueji/p/16970322.html