利用OpenCV进行对象跟踪的示例代码
作者:AI浩 发布时间:2023-05-28 14:14:54
OpenCV 对象跟踪
这篇文章使用 OpenCV 中内置的八种不同的对象跟踪算法,实现对物体的跟踪。
首先,介绍一下8种跟踪算法。
然后,演示如何使用OpenCV实现这些跟踪算法。
最后,对本文做总结。
OpenCV 对象 *
OpenCV 八种对象 * :
BOOSTING Tracker:基于用于驱动 Haar 级联 (AdaBoost) 背后的机器学习的相同算法,但与 Haar 级联一样,已有十多年的历史。这个 * 很慢,而且效果不太好。仅出于遗留原因和比较其他算法而感兴趣。 (最低 OpenCV 3.0.0)
MIL Tracker:比 BOOSTING * 更准确,但在报告失败方面做得很差。 (最低 OpenCV 3.0.0)
KCF * :内核化相关过滤器。比 BOOSTING 和 MIL 更快。与 MIL 和 KCF 类似,不能很好地处理完全遮挡。 (最低 OpenCV 3.1.0)
CSRT Tracker:判别相关滤波器(具有通道和空间可靠性)。往往比 KCF 更准确,但速度稍慢。 (最低 OpenCV 3.4.2)
MedianFlow Tracker:很好地报告失败;但是,如果运动中的跳跃太大,例如快速移动的物体,或者外观快速变化的物体,模型就会失败。 (最低 OpenCV 3.0.0)
TLD * :我不确定 TLD * 的 OpenCV 实现或实际算法本身是否存在问题,但 TLD * 极易出现误报。我不推荐使用这个 OpenCV 对象 * 。 (最低 OpenCV 3.0.0)
MOSSE Tracker:非常非常快。不如 CSRT 或 KCF 准确,但如果您需要纯粹的速度,这是一个不错的选择。 (最低 OpenCV 3.4.1)
GOTURN Tracker:OpenCV 中唯一基于深度学习的目标检测器。它需要额外的模型文件才能运行(本文不会涉及)。我最初的实验表明,尽管据说它可以很好地处理查看变化,但使用起来还是有点痛苦(尽管我最初的实验并没有证实这一点)。我将尝试在以后的帖子中介绍它,但与此同时,请看一下 Satya 的文章。 (最低 OpenCV 3.2.0)
个人建议:
当需要更高的对象跟踪精度并且可以容忍较慢的 FPS 吞吐量时,请使用 CSRT
当需要更快的 FPS 吞吐量但可以处理稍低的对象跟踪精度时使用 KCF
当需要纯粹的速度时使用 MOSSE
物体跟踪
在开始算法之前,先写辅助方法和类。
fps类:
import datetime
class FPS:
def __init__(self):
# 定义开始时间、结束时间和总帧数
self._start = None
self._end = None
self._numFrames = 0
def start(self):
# 开始计时
self._start = datetime.datetime.now()
return self
def stop(self):
# 停止计时
self._end = datetime.datetime.now()
def update(self):
# 增加在开始和结束间隔期间检查的总帧数
self._numFrames += 1
def elapsed(self):
# 返回开始和结束间隔之间的总秒数
return (self._end - self._start).total_seconds()
def fps(self):
# 计算每秒帧数
return self._numFrames / self.elapsed()
请打开一个新文件,将其命名为 object_tracker.py ,定义resize方法,等比例缩放图片。
import cv2
from fps import FPS
def resize(image, width=None, height=None, inter=cv2.INTER_AREA):
# 初始化要调整大小的图像的尺寸并抓取图像大小
dim = None
(h, w) = image.shape[:2]
# 如果宽高都为None,则返回原图
if width is None and height is None:
return image
# 检查宽度是否为None
if width is None:
# 计算高度的比例并构造尺寸
r = height / float(h)
dim = (int(w * r), height)
# 否则,高度为 None
else:
# 计算宽度的比例并构造尺寸
r = width / float(w)
dim = (width, int(h * r))
resized = cv2.resize(image, dim, interpolation=inter)
return resized
定义全局变量:
videos = 0
tracker_type = 'kcf'
我们的命令行参数包括:
videos:输入视频文件或者摄像头的ID。
tracker_type: * 的类型,接下来的代码定义了 * 列表。
接下来定义不同类型的 * :
# 提取 OpenCV 版本信息
(major, minor) = cv2.__version__.split(".")[:2]
# 如果我们使用 OpenCV 3.2 或之前版本,我们可以使用特殊的工厂函数来创建我们的对象 *
if int(major) == 3 and int(minor) < 3:
tracker = cv2.Tracker_create(tracker_type)
# 否则,对于 OpenCV 3.3 或更新版本,我们需要显式调用对应的对象 * 构造函数:
else:
# 初始化一个字典,将字符串映射到其对应的 OpenCV 对象 * 实现
OPENCV_OBJECT_TRACKERS = {
"csrt": cv2.TrackerCSRT_create,
"kcf": cv2.TrackerKCF_create,
"boosting": cv2.legacy.TrackerBoosting_create,
"mil": cv2.TrackerMIL_create,
"tld": cv2.legacy.TrackerTLD_create,
"medianflow": cv2.legacy.TrackerMedianFlow_create,
"mosse": cv2.legacy.TrackerMOSSE_create
}
# 使用我们的 OpenCV 对象 * 对象字典获取适当的对象 *
tracker = OPENCV_OBJECT_TRACKERS[tracker_type]()
在OpenCV 3.3之前,必须使用cv2.Tracker_create创建 * 对象,并传递 * 名称的大写字符串。
对于OpenCV 3.3+,可以使用各自的函数调用创建每个 * ,例如cv2.TrackerCSRT_create。字典OPENCV_OBJECT_TRACKERS包含8个内置OpenCV对象 * 中的七个。它将对象 * 命令行参数字符串(键)与实际的OpenCV对象 * 函数(值)进行映射。
# 初始化我们要追踪的物体的边界框坐标
initBB = None
vs = cv2.VideoCapture(videos)
fps = None
initBB初始化为None,此变量将保存我们使用鼠标选择的对象的边界框坐标。
接下来,初始化VideoCapture对象和FPS计数器。
让我们开始循环来自视频流的帧:
# 循环播放视频流中的帧
while True:
# 抓取当前帧。
(grabbed, frame) = vs.read()
if not grabbed:
break
# 调整框架大小并获取框架尺寸。
frame = resize(frame, width=500)
(H, W) = frame.shape[:2]
# 检查是否正在跟踪一个对象
if initBB is not None:
# 抓取物体的新边界框坐标
(success, box) = tracker.update(frame)
# 检查跟踪是否成功
if success:
(x, y, w, h) = [int(v) for v in box]
cv2.rectangle(frame, (x, y), (x + w, y + h),
(0, 255, 0), 2)
# 更新 FPS 计数器
fps.update()
fps.stop()
# 初始化在框架上显示的信息集
info = [
("Tracker", tracker_type),
("Success", "Yes" if success else "No"),
("FPS", "{:.2f}".format(fps.fps())),
]
# 遍历信息元组并将它们绘制在框架上
for (i, (k, v)) in enumerate(info):
text = "{}: {}".format(k, v)
cv2.putText(frame, text, (10, H - ((i * 20) + 20)),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)
# 显示输出帧
cv2.imshow("Frame", frame)
key = cv2.waitKey(1) & 0xFF
抓住一个帧,如果获取不到帧,则退出。
为了使对象跟踪算法能够更快地处理帧,我们将输入帧的大小调整为500像素。
然后输出框架的高和宽。
如果已选择对象,则需要更新对象的位置。 update方法将定位对象的新位置并返回成功布尔值和对象的边界框。
如果成功,我们在框架上绘制新的,更新的边界框位置。
更新FPS。
初始化显示的文本信息列表。随后,绘制到frame上。
显示输出帧。
# 使用's'键选择一个边界框来跟踪
if key == ord("s"):
# 选择跟踪的对象的边界框(选择 ROI 后按 ENTER 或 SPACE)
initBB = cv2.selectROI("Frame", frame, fromCenter=False,
showCrosshair=True)
# 使用提供的边界框坐标启动 OpenCV 对象 * ,然后也启动 FPS 吞吐量估计器
tracker.init(frame, initBB)
fps = FPS().start()
# 如果 `q` 键被按下,则退出循环
elif key == ord("q"):
break
vs.release()
cv2.destroyAllWindows()
按下“s”键时,使用cv2.selectROI“选择”对象ROI。此时,视频帧冻结,用鼠标绘制跟踪对象的边界框。
绘制完边界框,然后按“ENTER”或“SPACE”确认选择。如果需要重新选择区域,只需按“ESCAPE”即可。
然后,启动OpenCV 对象 * ,再启动 FPS 吞吐量估计器。
最后一个段代码只是处理我们已经脱离循环的情况。释放所有指针并关闭窗口。
来源:https://blog.csdn.net/hhhhhhhhhhwwwwwwwwww/article/details/122815739


猜你喜欢
- 一、Tesseract-OCR 是什么An OCR Engine that was developed at HP Labs between
- 增加索引可以提高查询效率。增加索引就是增加一个索引文件,存放的是数据的地址,类似与我们文档的目录,在查找过程中可以不用从书的内容查找,直接根
- 前言相信大家都知道任何版本控制系统的一个最有的用特性就是“撤销 (undo)”你的错误操作的能力。在 Git 里,“撤销” 蕴含了不少略有差
- 编写程序,完成“名片管理器”项目需要完成的基本功能:添加名片删除名片修改名片查询名片退出系统程序运行后,除非选择退出系统,否则重复执行功能m
- 总括pandas的索引函数主要有三种:loc 标签索引,行和列的名称iloc 整型索引(绝对位置索引),绝对意义上的几行几列,起始索引为0i
- Quoted-printable 可译为“可打印字符引用编码”、“使用可打印字符的编码”,我们收邮件,查看信件原始信息,经常会看到这种类型的
- 本文实例讲述了Python中的True,False条件判断用法。分享给大家供大家参考。具体分析如下:对于有编程经验的程序员们都知道条件语句的
- 之前有写利用md5方式来做差异备份,但是这种md5方式来写存在以下问题:•md5sum获取有些软连接的MD5值存在问题 •不支持对空目录进行
- 本文详细讲述了CI框架整合smarty步骤。分享给大家供大家参考,具体如下:Ci结合smarty的配置步骤:1. 第一步配置ci和下载sma
- 1 squeeze(): 去除size为1的维度,包括行和列。至于维度大于等于2时,squeeze()不起作用。行、例:>>&g
- 连接MySQL时出现1449与1045异常解决办法mysql 1449 : The user specified as a definer
- AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用
- 1.lower()将字符串中的大写字母转换成小写字母语法:str.lower()#举例:str1 = "LiBai is a bo
- asp采集常用的几个FUCTION如:利用流保存文件,利用fso检测文件是否存在,利用fso检测文件夹是否存在,保存文件,取得远程数据等1.
- 初学者可能都会遇到一个小问题就是:在用IPython的时候,可以使用类似%matplotlib inline的Magic Function(
- 0、背景今天看到了一个比较诡异的写法,for后直接跟了else语句,起初还以为是没有缩进好,查询后发现果然有这种语法,特此分享。之前写过c+
- 例如下面这段代码 { var temp = "12"; } alert(temp); //输出 12 如果按照通常的编程
- 本文实例为大家分享了python自动化生成IOS的图标,供大家参考,具体内容如下每次上架之前都要生成十几个图片感觉无聊麻烦,考虑使用脚本处理
- 作为Python开发者,你迟早都会用到图形用户界面来开发应用。本文将推荐一些 Python GUI 框架,希望对你有所帮助,如果你有其他更好
- Go+ 语言的安装和环境配置有些复杂,官方教程也没有写的很详细。通过控制台编写和运行 Go+ 程序很不方便。本文从零开始,详细介绍 Go+