【深度学习|目标跟踪】StrongSort 详解(以及StrongSort++)

news2025/4/25 8:16:35

StrongSort详解

  • 1、论文及源码
  • 2、DeepSort回顾
  • 3、StrongSort的EMA
  • 4、StrongSort的NSA Kalman
  • 5、StrongSort的MC
  • 6、StrongSort的BOT特征提取器
  • 7、StrongSort++的AFLink
  • 8、未完待续

1、论文及源码

在这里插入图片描述
论文地址:https://arxiv.org/pdf/2202.13514
源码地址:https://github.com/dyhBUPT/StrongSORT?tab=readme-ov-file

2、DeepSort回顾

参考此篇博客

3、StrongSort的EMA

  EMA即指数加权移动平均,在StrongSort中,self.track在update时,会将当前提取到的目标特征向量进行如下两步操作:

  • 将特征向量归一化
  • 指数加权移动平均

在代码中的体现,在track脚本文件中,Track类:
在这里插入图片描述
相比较于DeepSort中将每次的匹配上的目标的特征向量直接存储到对应track的gallery中,StrongSort的做法可以有效的平滑视频中间由于遮挡,噪声或其他不利因素导致的目标特征的衰减,使得在特征在匹配时的准确率能够有效提升。
  在Trackerupdate的最后,我们会更新对应track的特征库:
在这里插入图片描述

nn_matching脚本中的NearestNeighborDistanceMetric类中:
在这里插入图片描述
这里的self.budget可以在config.yaml中指定,意思是存储当前帧的前多少帧的特征进特征库。本质上还是和DeepSort一样,给每个track弄了个特征库,只不过特征库中的特征向量是从第一帧开始就进行指数加权移动平均并归一化的特征向量。

4、StrongSort的NSA Kalman

  在DeepSort中使用的是一个普通的kalman filter,即通过状态量直接估计下一时刻的状态,只有位置信息,而StrongSort中融合了目标的置信度信息,在计算噪声的均值和方差时,加入了track对应的检测目标的置信度信息,自适应的调整噪声。自适应计算噪声协方差的公式:
在这里插入图片描述
其中,Rk是预设的常数测量噪声协方差,Ck 是状态 k 下的检测置信度分数。即当置信度高时,意味着这次检测的结果有较小的噪声,对下次的状态预测的影响较小。
  现在来看一下源码中关于NSA Kalman的流程:

  • strong_sort.py中StrongSort类的self.tracker.predict()
  • 进入tracker.py中的Tracker类的predict()方法,遍历self.tracks然后进入track的predict()预测,然后进入track.py中的Track类的predict()预测,然后进入kalman_filter.py中的KalmanFilter类中的predict()方法来计算均值和方差。
  • 然后回到strong_sort.py中的self.tracker.update(),进入tracker.py的Tracker类的update()方法,经过self._match()匹配完成之后,会得到匹配列表,未匹配的跟踪,未匹配的检测。然后我们遍历匹配列表来,跟新我们已经匹配上的track,进入track.py中的Track类的update()方法,在这里我们会看到加入了检测框的confidence来更新均值和方差:
    在这里插入图片描述
  • 进入kalman_filter.py中的KalmanFilter类中的update()方法,进入self.project()方法计算出融合了confidence后的均值和方差。

这便是代码中NSA Kalman的一个实现过程。

5、StrongSort的MC

  在DeepSort中,虽然说结合了外观特征和运动特征来进行跟踪,但是DeepSort的lambda权重是设置成0或1的,因此并没有真正的结合外观特征追踪和运动特征追踪,只是将他们分成两个阶段分别匹配。而在StrongSort中,在外观特征匹配阶段,引入了一个mc_lambda权重作用在运动特征的门控矩阵上,结合外观代价矩阵来计算得到最后的cost_matrix,公式如下:
在这里插入图片描述
代码如下:
在这里插入图片描述
这是在_match()方法中的gated_metric()方法中调用。

6、StrongSort的BOT特征提取器

  这是一个关于行人重识别的特征提取网络,具体的还没有深入了解过,我个人觉得这里的特征提取器用什么不是StrongSort的亮点,毕竟这个模块是个即插即用的模块,用不同的分类网络或者孪生网络训练出来的特征提取网络都可以用在这个地方。

7、StrongSort++的AFLink

  AFLink提出将两段30帧(可以自己调整,修改AFLink的分类网络重新训练即可)的时空序列作为输入,这两段tracklets分别是1 * 30 * 3维度的一个特征向量,其中30表示帧数,3分别表示帧数(时间),x,y(空间),即结合了时空的一段序列。网络将会输出这两段tracklets的相似置信度。

  • AFLink网络的定义:
    在这里插入图片描述
"""
@Author: Du Yunhao
@Filename: model.py
@Contact: dyh_bupt@163.com
@Time: 2021/12/28 14:13
@Discription: model
"""
import torch
from torch import nn

class TemporalBlock(nn.Module):
    def __init__(self, cin, cout):
        super(TemporalBlock, self).__init__()
        self.conv = nn.Conv2d(cin, cout, (7, 1), bias=False)
        self.relu = nn.ReLU(inplace=True)
        self.bnf = nn.BatchNorm1d(cout)
        self.bnx = nn.BatchNorm1d(cout)
        self.bny = nn.BatchNorm1d(cout)

    def bn(self, x):
        x[:, :, :, 0] = self.bnf(x[:, :, :, 0])
        x[:, :, :, 1] = self.bnx(x[:, :, :, 1])
        x[:, :, :, 2] = self.bny(x[:, :, :, 2])
        return x

    def forward(self, x):
        x = self.conv(x)
        x = self.bn(x)
        x = self.relu(x)
        return x


class FusionBlock(nn.Module):
    def __init__(self, cin, cout):
        super(FusionBlock, self).__init__()
        self.conv = nn.Conv2d(cin, cout, (1, 3), bias=False)
        self.bn = nn.BatchNorm2d(cout)
        self.relu = nn.ReLU(inplace=True)

    def forward(self, x):
        x = self.conv(x)
        x = self.bn(x)
        x = self.relu(x)
        return x


class Classifier(nn.Module):
    def __init__(self, cin):
        super(Classifier, self).__init__()
        self.fc1 = nn.Linear(cin*2, cin//2)
        self.relu = nn.ReLU(inplace=True)
        self.fc2 = nn.Linear(cin//2, 2)

    def forward(self, x1, x2):
        x = torch.cat((x1, x2), dim=1)
        x = self.fc1(x)
        x = self.relu(x)
        x = self.fc2(x)
        return x


class PostLinker(nn.Module):
    def __init__(self):
        super(PostLinker, self).__init__()
        self.TemporalModule_1 = nn.Sequential(
            TemporalBlock(1, 32),
            TemporalBlock(32, 64),
            TemporalBlock(64, 128),
            TemporalBlock(128, 256)
        )
        self.TemporalModule_2 = nn.Sequential(
            TemporalBlock(1, 32),
            TemporalBlock(32, 64),
            TemporalBlock(64, 128),
            TemporalBlock(128, 256)
        )
        self.FusionBlock_1 = FusionBlock(256, 256)
        self.FusionBlock_2 = FusionBlock(256, 256)
        self.pooling = nn.AdaptiveAvgPool2d((1, 1))
        self.classifier = Classifier(256)

    def forward(self, x1, x2):
        x1 = x1[:, :, :, :3]
        x2 = x2[:, :, :, :3]
        x1 = self.TemporalModule_1(x1)  # [B,1,30,3] -> [B,256,6,3]
        x2 = self.TemporalModule_2(x2)
        x1 = self.FusionBlock_1(x1)
        x2 = self.FusionBlock_2(x2)
        x1 = self.pooling(x1).squeeze(-1).squeeze(-1)
        x2 = self.pooling(x2).squeeze(-1).squeeze(-1)
        y = self.classifier(x1, x2)
        if not self.training:
            y = torch.softmax(y, dim=1)
        return y


if __name__ == '__main__':
    x1 = torch.ones((3, 1, 30, 3))
    x2 = torch.ones((3, 1, 30, 3))
    m = PostLinker()
    m.eval()
    # 提取第一个维度的第二个元素作为置信度(0表示第一个维度,1表示该维度的索引)
    y1 = m(x1, x2)[0, 1].detach().cpu().numpy()
    print(y1)

输入两个tracklets,维度分别是[1, 1, 30, 3];
           ||
           v
Temporal module: 特征层维度[1, 256, 6, 3];
           ||
           v
Fusion module: 特征层维度[1, 256, 6, 1];
           ||
           v
Pooling + Squeeze:特征层维度[1, 256];
           ||
           v
Classifier:特征层维度[1, 2];

  • AFLink的推理:
    AFLink是一个离线模块,在目标检测+跟踪推理完成后,将每一帧的track信息(帧数,位置)保存到txt中,然后离线的使用AFLink读取这个txt来得到最终的推理结果,也将序列信息保存到txt中。我们可以根据txt中的帧数和坐标信息来将检测结果可视化在视频中。

8、未完待续

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

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

相关文章

Scala关于成绩的常规操作

score.txt中的数据: 姓名,语文,数学,英语 张伟,87,92,88 李娜,90,85,95 王强,78,90,82 赵敏,92,8…

OpenAI Whisper 语音识别 模型部署及接口封装

环境配置: 一、安装依赖: pip install -U openai-whisper 或者,以下命令会从这个存储库拉取并安装最新的提交,以及其Python依赖项: pip install githttps://github.com/openai/whisper.git 二、安装ffmpeg: cd …

草图大师2020安装教程附安装包下载

软件介绍 草图大师(Sketchup)是由谷歌公司推出的一款环保型3D建模软件。草图大师可以快速和方便地创建、观察和修改三维创意,具有沿路径放样、导入的2D物体可随视角转动、布尔运算等功能。传统铅笔草图的优雅自如,现代数字科技的…

野火直播 5.7.5x | 频道丰富,有国外频道,部分支持回看

野火直播是一款专为电视盒子设计的电视直播软件,提供海量的电视直播资源和丰富的内容选择。涵盖全球多地的电视台直播源,包括央视、卫视、地方台、海外台等上千个电视频道。软件界面简洁,操作便捷,支持高清流畅播放,并…

题解 洛谷 Luogu P1182 数列分段 Section II 二分答案 C/C++

题目传送门: P1182 数列分段 Section II - 洛谷 | 计算机科学教育新生态https://www.luogu.com.cn/problem/P1182思路: 二分答案,每次以区间 [l, r] 中点 m 为每段和的阈值 判断在此前提下,划分段数是否不大于 M 是就记录答案…

Rust语言俄罗斯方块(漂亮的界面案例+详细的代码解说+完美运行)

tetris-demo A Tetris example written in Rust using Piston in under 500 lines of code 项目地址: https://gitcode.com/gh_mirrors/te/tetris-demo 项目介绍 "Tetris Example in Rust, v2" 是一个用Rust语言编写的俄罗斯方块游戏示例。这个项目不仅是一个简单…

Hot100 - 除自身以外数组的乘积

Hot100 - 除自身以外数组的乘积 最佳思路: 此问题的关键在于通过两次遍历,分别计算从左侧和右侧开始的累积乘积,以此避免使用额外的除法操作。 时间复杂度: 该算法的时间复杂度为 O(n),因为我们只需要遍历数组两次。…

通过抓包,使用frida定位加密位置

首先我们抓取一下我们要测试的app的某一个目标api,通过抓api的包,得到关键字。 例如:关键字:x-sap-ri 我们得到想要的关键字后,通过拦截 类,寻找我们的关键字,及找到发包收包的位置&#xff0c…

【模型学习之路】TopK池化,全局池化

来学学图卷积中的池化操作 目录 DataBatch Dense Batching Dynamic Batching DataBatch 存取操作 TopKPooling GAP/GMP 一个例子 后话 DataBatch 当进行图级别的任务时,首先的任务是把多个图合成一个batch。 在Transformer中,一个句子的维度是…

<项目代码>YOLOv8 停车场空位识别<目标检测>

YOLOv8是一种单阶段(one-stage)检测算法,它将目标检测问题转化为一个回归问题,能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法(如Faster R-CNN),YOLOv8具有更高的…

如何在Python中进行数学建模?

数学建模是数据科学中使用的强大工具,通过数学方程和算法来表示真实世界的系统和现象。Python拥有丰富的库生态系统,为开发和实现数学模型提供了一个很好的平台。本文将指导您完成Python中的数学建模过程,重点关注数据科学中的应用。 数学建…

ThingsBoard规则链节点:GCP Pub/Sub 节点详解

目录 引言 1. GCP Pub/Sub 节点简介 2. 节点配置 2.1 基本配置示例 3. 使用场景 3.1 数据传输 3.2 数据分析 3.3 事件通知 3.4 任务调度 4. 实际项目中的应用 4.1 项目背景 4.2 项目需求 4.3 实现步骤 5. 总结 引言 ThingsBoard 是一个开源的物联网平台&#xff…

【工具变量】城市供应链创新试点数据(2007-2023年)

一、测算方式:参考C刊《经济管理》沈坤荣和乔刚老师(2024)的做法,使用“供应链创新与应用试点”的政策虚拟变量(TreatPost)表征。若样本城市为试点城市,则赋值为 1,否则为 0&#xf…

小程序租赁系统开发的优势与应用解析

内容概要 随着科技的迅猛发展,小程序租赁系统应运而生,成为许多企业优化业务的重要工具。首先,它提升了用户体验。想象一下,用户只需轻轻一点,就能够浏览和租赁心仪的商品,这种便捷的过程使繁琐的操作大大…

Spring MVC练习(前后端分离开发实例)

White graces:个人主页 🙉专栏推荐:Java入门知识🙉 🐹今日诗词:二十五弦弹夜月,不胜清怨却飞来🐹 ⛳️点赞 ☀️收藏⭐️关注💬卑微小博主🙏 ⛳️点赞 ☀️收藏⭐️关注&#x1f4…

使用IDEA构建springboot项目+整合Mybatis

目录 目录 1.Springboot简介 2.SpringBoot的工作流程 3.SpringBoot框架的搭建和配置 4.用Springboot实现一个基本的select操作 5.SpringBoot项目部署非常简单,springBoot内嵌了 Tomcat、Jetty、Undertow 三种容器,其默认嵌入的容器是 Tomcat,…

不玩PS抠图了,改玩Python抠图

网上找了两个苏轼的印章图片: 把这两个印章抠出来的话,对于不少PS高手来说是相当容易,但是要去掉其中的水印,可能要用仿制图章慢慢描绘,图章的边缘也要慢慢勾画或者用通道抠图之类来处理,而且印章的红色也不…

ElasticSearch的下载和基本使用(通过apifox)

1.概述 一个开源的高扩展的分布式全文检索引擎,近乎实时的存储,检索数据 2.安装路径 Elasticsearch 7.8.0 | Elastic 安装后启动elasticsearch-7.8.0\bin里的elasticsearch.bat文件, 启动后就可以访问本地的es库http://localhost:9200/ …

26届JAVA 学习日记——Day16

2024.11.27 周三 尽量在抽出时间做项目,持续学习优化简历,等到基础的八股都熟悉、leetcode热题100刷完、苍穹外卖项目AI项目彻底完成投简历,目标是找到日常实习,然后边做边准备暑期实习。 八股 WebSocket WebSocket是什么&…

Javaweb 前端 HTML css 案例 总结

顶部导航栏 弹性布局 搜索表单区域 表单标签 表单标签,表单项 复选,一次选多个 隐藏域,看不到,但会传参数 text输入框 radio单选 男女,是 前端页面上显示的值 搜索表单区域 button 按钮 表格数据展示区域 fo…