目标追踪DeepSort

一、卡尔曼滤波

        你可以在任何对某个动态系统有 “不确定信息” 的地方使用卡尔曼滤波器,并且可以对系统下一步的行为做出 “有根据的猜测”。即使混乱的现实干扰了你所猜测的干净运动,卡尔曼滤波器通常也能很好地确定实际发生了什么。它还可以利用你可能想不到要利用的疯狂现象之间的相关性!
        卡尔曼滤波器非常适合 “不断变化” 的系统。它们的优点是占用内存少(除了前一个状态,不需要保留任何历史记录),并且速度非常快,非常适合实时问题和嵌入式系统。
       举个例子:开车时如何确定自己的位置呢?我们根据车辆的运行,可以提供以下信息:①加速度信息,②里程表信息,③GPS信息。这三种信息都存在误差(噪音),但是他们都有用,可以综合的利用它们,估计出最优的位置,这就是卡尔曼滤波,本质上是优化估计算法。                                        

1.1一个定量的例子

        下面是个定量分析的例子:一个小车的位置更新:

状态向量x_{t}:位置和速度;                         小车加速度u_{t}

则经过\triangle t时刻后的位置:位置和速度

根据上式可以得出状态转移矩阵:

        任何状态都会受到外部环境的影响(例如压了一颗石头、例如突然猛刮大风),但是这些影响可能会促进状态,也可能抑制状态,它们的平均呈正态分布。

        这里的A就是上式中的Ft,B就是Bt,w_{k}是位置误差;y_{k}就是速度,v_{k}是速度误差。这就是状态转移方程。

卡尔曼滤波的本质上就是基于估计值和观测值进行综合判断

1.2 计算公式

        那么下一时刻的准确位置在哪呢?如下图,\hat{x}_{k-1}是上一时刻的预测值,它的正太分布的宽度相当于误差,\hat{x}_{k}是这一时刻的预测值,它的误差更大(因为它就是从\hat{x}_{k-1}这个本身就是“连蒙带猜”的结果得出来的,那么它的误差就更大),而y_{k}是测量值,也带有误差。

         那么如果根据\hat{x}_{k}y_{k}得出一个更加准确的值呢?科学家给出的一个方法:

        \hat{x}_{}^{-} 是先验估计;\hat{x}是后验估计;y_{k}是传感器;K_{k}是卡尔曼增益

1.3 两大核心模块

1.3.1 预测Prediction

        车辆在运行过程中,有些量保持着一定的关系(如某个人的眼睛中,这一时刻的车辆大小和下一时刻的车辆大小存在着一定的大小关系,当一个车远离这个人时,它不会瞬间变大,也不会瞬间变小,而是慢慢的变小)

单状态协方差矩阵就是其方差:

        P_{k}^{-}是协方差矩阵,它描述了一些量的关系,状态在更新(状态转移矩阵),同样的,关系也在更新,关系在更新时同样加上了噪音项Q(误差项),其实就是更新过程必然会受到外界干扰的影响。

        这就是预测阶段,预测状态估计值和协方差。

1.3.2 更新Update

        不建议大家看这个公式的推导,尤其是卡尔曼增益K_{k},推导过程及其复杂,科学家费了好大力气才推导出,已经超出了我们的学习范围了。

        对于我们的目标追踪,我们要对每一帧的要预测、更新,下一帧继续再预测、再更新,因为每一帧的状态肯定会改变的。预测完根据观测值进行修正,修正后的状态值去估计下一帧。

1.4 卡尔曼增益

卡尔曼增益K:式中R是偏差,C是转换矩阵(单状态,匀速)

        它的目的就是让最优估计值的方差最小(就是下图中的\hat{x}_{k}中的方差最小),它决定了卡尔曼滤波的核心作用。

若观测过程没有一点偏差,根据推导可得:\hat{x}_{k}=y_{k},即后验估计值就等于观测值;

若状态估计没有噪音时,根据推导可得:\hat{x}_{k}=x_{k}^{-},即后验估计值等于先验估计值。

二、追踪问题考虑的状态

均值(Mean):8维向量:

x=[cx,cy,r,h,vx,vy,vr,vh]

        以这名足球员为例,解释上述8个量。                                                                                          cx,cy就是这个检测框的中心点位置;r=h/w即宽高比,是这个检测框的长宽比例(这个值表明这个检测框不能瞬间变大或变小),h就是长度;                                                                                  vx,vy,vr,vh就是该方向(分别是x,y,r,h)上的速度变化。                                                  协方差矩阵:表示目标位置信息的不确定性,由8*8的矩阵表示

        追踪过程也分为两个阶段,每个track都要预测下一时刻的状态,并基于检测到的结果进行修正(匀速、线性、追踪通常是一帧一帧进行处理的)。

三、匈牙利匹配算法

        利用匈牙利匹配完成匹配的同时最小化代价矩阵(代价矩阵后面解释)即当前帧检测到的目标应该匹配到前面的哪个track呢?但是很多时候并不是最优匹配,而是尽可能的多匹配。

3.1 例子

匈牙利匹配的例子:给三个人分配三个任务,哪个人做哪个任务代价矩阵(时间)最小呢?

时间:分钟task1task2task3
Person1154045
Person2206035
Person3204024

特点:

方法:

上述过程了解即可,我们一般直接使用Python中的内置函数:用之前得有一个代价矩阵。

sklearn:linear_assignment();         scipy:linear_sum_assignment()直接做上述过程

3.2 代价矩阵的构建

        得到代价矩阵即可完成这个任务。那么在追踪任务中,如何构建这个代价矩阵呢? 这也是这个任务的难点。

        运动信息的匹配:卡尔曼估计出8个状态量,是下一帧的预测值,我们同时还有下一帧的检测值,即下一帧估计的结果和下一帧实际的结果,可以构建一个代价矩阵。

        外观匹配(ReID):这是deepsort中最重要的,就是提供了外观信息

        IOU匹配(BBOX):BoundingBox的匹配,即预测的新位置框和检测到的实际位置框进行匹配,哪个IOU大,那就是IOU损失小。

        匈牙利匹配会根据这三项分别构造代价矩阵。

        ReID特征:追踪人所用到了ReID,如果追踪其他目标需要自己训练。ReID是一个很简单的网络(因为我们想实时检测,就不能构造复杂的网络),对输入的bbox进行特征提取,返回128维特征: 

        在实际运用时,他的每一帧的检测框都会存在一个list中,每个是128维向量,而下一帧会有检测框,也会有128维向量,他会和前面的每一帧进行计算余弦相似度,看哪个是最大的,把他们俩当作距离。track的list数量是有上线的,默认是100个。

四、追踪任务的基本流程

目标检测+追踪对检测到的bbox提取各项特征后进行匹配)

4.1 Sort算法(是deepsort的前身)

  1. 卡尔曼预测与更新
  2. 匈牙利匹配返回结果
  3. 将预测后的tracks和当前帧中的detections进行匹配(IOU匹配)

注意:没有ReID等深度学习特征

4.2 DeepSORT算法

        与Sort算法最大的区别在于,多了MatchingCascade过程。它代码写的挺难理解的,论文写的也十分抽象,但原理非常简单,是这样的:                                假如某个人因为某些原因在某些帧中没被检测到(如守门员扑球时形态会发生剧烈变化,此时很难被检测到,但是他会很快恢复原来状态),这些人并不是被“干掉”,他可能在下面帧会被检测到,原论文提出一个值MaxAge,就是最大尝试次数,论文给的默认值是70帧,即从检测框消失,到70帧以后也没有找到能匹配上的,就会删除该tracks。                       MatchingCascade,假设现在有track1,track2,track3,...,track10,假如track1全部匹配到100帧,丢失0帧,track2因为种种原因(如遮挡、匹配错误等)丢失5帧,tracks3丢失10帧,tracks10丢失60帧。现在第101帧来了,它含有10个bbox,而 MatchingCascade就会让这10个bbox优先匹配track1,即优先匹配丢失最少的(如果假如前5个都没有丢失,那么同时匹配这前5个)循环执行70次。                                                                                                                               在MatchingCascade匹配完成后,再进行IOU匹配。但是并不是所有的track能进入MatchingCascade匹配,只有连续3帧能匹配上的,才进行MatchingCascade匹配(图中的左边的Confirmed),然后其他的就是Unconfirmed。MatchingCascade匹配也包含了卡尔曼估计以及ReID特征。                                                                                                                                                 其它的Unconfirmed进行IOU Match,看能不能找到,不能的就是Unmatched Tracks然后看是否是Confirmed,不是的话(Unconfirmed)直接删除,是Confirmed就看是否大于MaxAge(70帧)

4.3 Matching Cascade级联匹配

        级联匹配:代价函数由运动特征(卡尔曼预测)与ReID特征计算的距离组成(新的代价矩阵)。其中gating_threshold是门单元,就是阈值上限,若它的IOU距离大于阈值上限,则它们的匹配不能完成(即就是太离谱的拼接会去除)。

        级联匹配是个循环,追踪过程肯定会有些track会丢失目标,如missing age=20,丢失了20帧,而匹配过程会从missing age=0开始,也就是没丢过的先匹配,然后按顺序,丢失最多的后匹配,默认上限是70.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/59056.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构与算法——Java实现 53.力扣938题——二叉搜索树的范围和

生命的意义 在于活出自我 而不是成为别人眼中的你 —— 24.11.3 938. 二叉搜索树的范围和 给定二叉搜索树的根结点 root,返回值位于范围 [low, high] 之间的所有结点的值的和。 示例 1: 输入:root [10,5,15,3,7,null,18], low 7, high 15 …

微信小程序scroll-view吸顶css样式化表格的表头及iOS上下滑动表头的颜色覆盖、z-index应用及性能分析

微信小程序scroll-view吸顶css样式化表格的表头及iOS上下滑动表头的颜色覆盖、z-index应用及性能分析 目录 微信小程序scroll-view吸顶css样式化表格的表头及iOS上下滑动表头的颜色覆盖、z-index应用及性能分析 1、iOS在scroll-view内部上下滑动吸顶的现象 正常的上下滑动吸顶…

免费好用又好看且多端自动同步第三方终端工具Termius你值得拥有

使用目的: 本地终端功能一样,都是为了登录服务器查看日志等操作。 本地终端 优点:方便简单,无需额外下载安装、免费。 缺点:每次都需要重新登陆输入命令,步骤繁琐无法简化;不能跨端同步。 第…

Unity引擎材质球残留贴图引用的处理

大家好,我是阿赵。   这次来分享一下Unity引擎材质球残留贴图引用的处理 一、 问题 在使用Unity调整美术效果的时候,我们很经常会有这样的操作,比如: 1、 同一个材质球切换不同的Shader、 比如我现在有2个Shader,…

【electron+vue3】使用JustAuth实现第三方登录(前后端完整版)

实现过程 去第三方平台拿到client-id和client-secret,并配置一个能够外网访问回调地址redirect-uri供第三方服务回调搭建后端服务,引入justauth-spring-boot-starter直接在配置文件中定义好第一步的三个参数,并提供获取登录页面的接口和回调…

Jetson OrinNX平台CSI相机导致cpu load average升高问题调试

1. 前言 硬件: Orin NX JP: 5.1.2, R35.4.1 用v4l2-ctl --stream-mmap -d0 命令去获取相机数据时, 用top查看cpu使用情况, CPU占用率很低,但load average在1左右, 无任何程序运行时,load average 为0 用ps -aux 查看当前进程情况,发现有两个系统进程vi-output, …

ComfyUI | FLUX-ControlNet,FLUX-LoRA和FLUX-IPAdapter等工作流【附下载】

本文重点提要 本文将介绍Flux模型及安装指引,文末附所有工作流下载方式ComfyUI FLUX工作流分享:包含FLUX Txt2Img、FLUX Img2Img、FLUX LoRA、FLUX ControlNet、FLUX Inpainting、FLUX NF4和Upscale、FLUX IPAdapter、Flux LoRA训练器、Flux Latent UpscalerFLUX简介 1.1 前…

第六十三周周报 GGNN

文章目录 week63 GGNN摘要Abstract一、文献阅读1. 题目2. abstract3. 网络架构3.1 数据处理部分3.2 门控图神经网络3.3 掩码操作 4. 文献解读4.1 Introduction4.2 创新点4.3 实验过程4.3.1 传感器设置策略4.3.2 数据集4.3.3 实验设置4.3.4 模型参数设置4.3.5 实验结果 5. 结论总…

【Linux】从零开始使用多路转接IO --- poll

碌碌无为,则余生太长; 欲有所为,则人生苦短。 --- 中岛敦 《山月记》--- 从零开始使用多路转接IO 1 前言1 poll接口介绍3 代码编写4 总结 1 前言 上一篇文章我们学习了多路转接中的Select,其操作很简单,但有一些缺…

Verilog实现的莫尔斯电码发生器

莫尔斯或者摩尔斯电码(Morse Code),发明于1837年(另有一说是1836年),通过不同的排列顺序来表达不同的英文字母、数字和标点符号,在这里作一简单处理,仅产生点(Dit)和划(Dah),时长在0.25秒之内为点,超过为划…

【系统架构设计师】七、设计模式

7.1 设计模式概述 设计经验在实践者之间日益广泛地利用,描述这些共同问题和解决这些问题的方案就形成了所谓的模式。 7.1.1 设计模式的历史 建筑师Christopher Alexander首先提出了模式概念,他将模式分为了三个部分: 特定的情景&#xff…

Maven介绍,IDEA集成方式

概述 什么是Maven? Maven 的正确发音是[ˈmevən],Maven在美国是一个口语化的词语,代表专家、内行的意思。 一个对 Maven 比较正式的定义是这么说的: Maven 是一个项目管理工具,它包含了一个项目对象模型 (POM:Proj…

pyav保存视频

目录 imageio替代pyav imageio替代pyav import imageio import numpy as np import torch# 创建一个随机的图像张量,形状为 (N, C, H, W) # 这里 N 30(帧数),C 3(通道数),H 64(…

stl_stack/queue

一.适配器 stack和queue实际上并不能算是一种容器,而是一种容器适配器。而适配器作为stl的6大组件之一,其实是一种设计模式。适配器模式其实就是将一个类的接口(该接口无法直接满足客户的需求)转换成客户希望的另一个接口&#x…

利用Docker Compose构建微服务架构

💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 利用Docker Compose构建微服务架构 引言 Docker Compose 简介 安装 Docker Compose 创建项目结构 编写 Dockerfile 前端 Dockerf…

lru_cache用法

在python中,lru_cache是一个装饰器, 是 Python 标准库中 functools 模块的一部分。lru_cache 装饰器可以用来为一个函数添加一个缓存系统。这个缓存系统会存储函数的输入和对应的输出。如果函数被调用,并且给出了已经缓存过的输入&#xff0c…

Redis未授权访问漏洞复现和修复建议

Redis未授权访问漏洞利用(总结) 一、漏洞介绍及危害1.1 原理1.2 漏洞影响版本1.3 漏洞危害1.4 实战中redis常用命令 二、漏洞复现2.1 环境准备2.1.1 靶机安装redis服务器2.1.2 kali安装Redis客户端(Redis-cli) 三、漏洞利用3.1 利…

无人机之集群控制方法篇

无人机的集群控制方法涉及多个技术和策略,以确保多架无人机能够协同、高效地执行任务。以下是一些主要的无人机集群控制方法: 一、编队控制方法 领航-跟随法(Leader-Follower) 通过设定一架无人机作为领航者(长机&am…

流水线商品标签如何快速打印?商品标签自定义打印软件操作方法

一、概述 【软件可定制详情点文章最后信息卡片】 流水线商品标签如何快速打印?商品标签自定义打印软件操作方法 ‌定义与用途‌ 商品标签打印软件,即用于打印商品标签的应用软件。标签包含产品上的文字、商品详情等说明信息 如图,可以预先…

Python - PDF 分割成单页、PDF 转图片(PNG)

文章目录 PDF 分割成一页页的 PDFPDF 转 PNGPDF 分割成一页页的 PDF import fitz def split_pdf(pdf_path, save_dir):source_pdf = fitz.open(pdf_path)# 遍历source_pdf中的每一页,page_number从0开始计数 for idx