利用OpenCV进行对象跟踪的示例代码

目录
  • OpenCV 对象跟踪
  • OpenCV 对象跟踪器
  • 物体跟踪
  • 总结

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 吞吐量估计器。

最后一个段代码只是处理我们已经脱离循环的情况。释放所有指针并关闭窗口。

总结

在今天的博客文章中,您学习了如何利用OpenCV进行对象跟踪。具体来说,我们回顾了OpenCV库中包含的8个对象跟踪算法(从OpenCV 3.4开始):

CSRT、KCF、Boosting、MIL、TLD、MedianFlow、MOSSE、GOTURN。

建议对大多数对象跟踪应用程序使用CSRT,KCF或MOSSE:

当需要更高的对象跟踪精度并且可以容忍更慢的FPS吞吐量时,请使用CSRT

当需要更快的FPS吞吐量时使用KCF,但可以处理稍低的对象跟踪精度

当需要纯粹的速度时使用MOSSE

到此这篇关于利用OpenCV进行对象跟踪的示例代码的文章就介绍到这了,更多相关OpenCV对象跟踪内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Opencv对象追踪的示例代码

    1 HSV上下限 颜色的HSV上下限如下表: 2 追踪单个颜色 import cv2 as cv import numpy as np cap = cv.VideoCapture(0) lower_color = np.array([0, 43, 46]) upper_color = np.array([10, 255, 255]) while cap.isOpened(): # 读取帧 _, frame = cap.read() # 转换颜色空间 BGR 到 HSV hsv = cv.cvtC

  • Python使用OPENCV的目标跟踪算法实现自动视频标注效果

    先上效果 1.首先,要使用opencv的目标跟踪算法,必须要有opencv环境 使用:opencv==4.4.0 和 opencv-contrib-python==4.4.0.46,lxml   这三个环境包. 也可以使用以下方法进行下载 : pip install opencv-python==4.4.0 pip install opencv-contrib-python==4.4.0.4 pip install lxml 2.使用方法: (1):英文状态下的 "s" 是进行标注 (

  • Python+OpenCV目标跟踪实现基本的运动检测

    目标跟踪是对摄像头视频中的移动目标进行定位的过程,有着非常广泛的应用.实时目标跟踪是许多计算机视觉应用的重要任务,如监控.基于感知的用户界面.增强现实.基于对象的视频压缩以及辅助驾驶等. 有很多实现视频目标跟踪的方法,当跟踪所有移动目标时,帧之间的差异会变的有用:当跟踪视频中移动的手时,基于皮肤颜色的均值漂移方法是最好的解决方案:当知道跟踪对象的一方面时,模板匹配是不错的技术. 本文代码是做一个基本的运动检测 考虑的是"背景帧"与其它帧之间的差异 这种方法检测结果还是挺不错的,但是需要

  • OpenCV实现对象跟踪的方法

    介绍 OpenCV 是一个很好的处理图像和视频的工具.无论你是想让你的照片呈现 90 年代的黑白效果,还是执行复杂的数学运算,OpenCV 都可以随时为你服务. 如果你对计算机视觉感兴趣,则必须具备 OpenCV 的知识.该库包含 2500 多种优化算法,可用于执行各种任务.它被谷歌.微软.IBM 等许多行业巨头使用,并被广泛用于研究小组.该库支持多种语言,包括 java.c++ 和 python. 本文将向你展示如何使用 OpenCV 中的一些基本功能来执行复杂的对象跟踪任务. 对象跟踪 对象

  • python结合opencv实现人脸检测与跟踪

    模式识别课上老师留了个实验,在VC++环境下利用OpenCV库编程实现人脸检测与跟踪. 然后就开始下载opencv和vs2012,再然后,配置了好几次还是配置不成功,这里不得不吐槽下微软,软件做这么大,这么难用真的好吗? 于是就尝试了一下使用python完成实验任务,大概过程就是这样子的: 首先,配置运行环境: 下载opencv和python的比较新的版本,推荐opencv2.4.X和python2.7.X. 直接去官网下载就ok了,python安装时一路next就行,下载的opencv.exe

  • 利用OpenCV进行对象跟踪的示例代码

    目录 OpenCV 对象跟踪 OpenCV 对象跟踪器 物体跟踪 总结 OpenCV 对象跟踪 这篇文章使用 OpenCV 中内置的八种不同的对象跟踪算法,实现对物体的跟踪. 首先,介绍一下8种跟踪算法. 然后,演示如何使用OpenCV实现这些跟踪算法. 最后,对本文做总结. OpenCV 对象跟踪器 OpenCV 八种对象跟踪器: BOOSTING Tracker:基于用于驱动 Haar 级联 (AdaBoost) 背后的机器学习的相同算法,但与 Haar 级联一样,已有十多年的历史.这个跟踪

  • 利用OpenCV实现质心跟踪算法

    目录 质心跟踪算法步骤 项目结构 使用 OpenCV 实现质心跟踪 实现对象跟踪驱动程序脚本 限制和缺点 目标跟踪的过程: 1.获取对象检测的初始集 2.为每个初始检测创建唯一的ID 3.然后在视频帧中跟踪每个对象的移动,保持唯一ID的分配 本文使用OpenCV实现质心跟踪,这是一种易于理解但高效的跟踪算法. 质心跟踪算法步骤 步骤1:接受边界框坐标并计算质心 质心跟踪算法假设我们为每一帧中的每个检测到的对象传入一组边界框 (x, y) 坐标. 这些边界框可以由任何类型的对象检测器(颜色阈值 +

  • Java利用Redis实现消息队列的示例代码

    本文介绍了Java利用Redis实现消息队列的示例代码,分享给大家,具体如下: 应用场景 为什么要用redis? 二进制存储.java序列化传输.IO连接数高.连接频繁 一.序列化 这里编写了一个java序列化的工具,主要是将对象转化为byte数组,和根据byte数组反序列化成java对象; 主要是用到了ByteArrayOutputStream和ByteArrayInputStream; 注意:每个需要序列化的对象都要实现Serializable接口; 其代码如下: package Utils

  • 利用Springboot实现Jwt认证的示例代码

    JSON Web Token是目前最流行的跨域认证解决方案,,适合前后端分离项目通过Restful API进行数据交互时进行身份认证 关于Shiro整合JWT,可以看这里:Springboot实现Shiro+JWT认证 概述 由于概念性内容网上多的是,所以就不详细介绍了 具体可以看这里:阮一峰大佬的博客 我总结几个重点: JWT,全称Json Web Token,是一种令牌认证的方式 长相: 头部:放有签名算法和令牌类型(这个就是JWT) 载荷:你在令牌上附带的信息:比如用户的id,用户的电话号

  • Opencv判断颜色相似的图片示例代码

    问题描述 有一个项目,大体是要判断一下一篇文章内的配图突不突兀. 素材准备 所以就从网上随便找了4张图: 可以看出,前3张图片从颜色上.从阅读感受上,应该是相似的,而最后一张应该是不同的. 而当我们只对图片做缩放(为了跑得快),然后用bgr通道出直方图算相似度时: 却发现,只有第一张和第二张图片的相似度是大于0.5的,而第二.三张,以及第三.四张图片之间的相似度几乎都小于等于0.1. 思考方法 于是,经过思考后我觉得,判断两张图片在颜色上相不相似,其本质在于判断其直方图分布的形状相不相似,而不应

  • Python+Opencv实现数字识别的示例代码

    一.什么是数字识别?   所谓的数字识别,就是使用算法自动识别出图片中的数字.具体的效果如下图所示: 上图展示了算法的处理效果,算法能够自动的识别到LCD屏幕上面的数字,这在现实场景中具有很大的实际应用价值.下面我们将对它的实现细节进行详细解析. 二.如何实现数字识别?   对于数字识别这个任务而言,它并不是一个新的研究方向,很久之前就有很多的学者们在关注这个问题,并提出了一些可行的解决方案,本小节我们将对这些方案进行简单的总结. 方案一:使用现成的OCR技术. OCR,即文字识别,它是一个比较

  • OpenCV实战之图像拼接的示例代码

    目录 背景 实现步骤 一.读取文件 二.单应性矩阵计算 三.图像拼接 总结 背景 图像拼接可以应用到手机中的全景拍摄,也就是将多张图片根据关联信息拼成一张图片: 实现步骤 1.读文件并缩放图片大小: 2.根据特征点和计算描述子,得到单应性矩阵: 3.根据单应性矩阵对图像进行变换,然后平移: 4.图像拼接并输出拼接后结果图: 一.读取文件 第一步实现读取两张图片并缩放到相同尺寸: 代码如下: img1 = cv2.imread('map1.png') img2 = cv2.imread('map2

  • openCV实现图像融合的示例代码

    目录 1. 概念 2. 流程 3 代码 1. 概念 图像融合: 两幅图片叠加在一起,形成前景背景的效果. 2. 流程 (1)读入要融合的两幅图片.(2)把两幅图片调整到统一大小,方便下一步叠加.(3)对两幅图片按照一定的权重相加.(4)显示图片.img1,img2 --> resize --> cv2.addWeighted()–>show addWeighted方法: 函数原型: void addWeighted(InputArray src1, double alpha, Input

随机推荐