当前位置: 首页 > news >正文

【目标追踪】MUTR3D: A Multi-camera Tracking Framework via 3D-to-2D Queries

这里写自定义目录标题

    • 1 摘要
    • 2. 相关工作
      • 2.1 基于摄像头的 3D 多目标跟踪
      • 2.2 基于摄像头的 3D 检测
      • 2.3 基于查询的检测与跟踪
    • 3. 方法
      • 3.1 基于查询的三维目标跟踪
      • 3.2 多摄像头 Track Query 解码
      • 3.3 查询初始化与特征提取
      • 3.4 三维目标参数化
      • 3.5 查询生命周期管理
      • 3.6 查询更新与运动模型

这里写自定义目录标题)
code: https://github.com/a1600012888/MUTR3D
git: https://arxiv.org/pdf/2205.00613

MUTR3D: A Multi-camera Tracking Framework via 3D-to-2D Queries

1 摘要

准确且一致的多摄像头三维跟踪是基于视觉的自动驾驶系统中的关键组件。该任务涉及在复杂场景下对跨多个摄像头的三维动态目标进行建模。由于深度估计、遮挡和外观歧义等原因,这一问题本质上充满挑战。此外,目标在时间和不同摄像头之间并不能始终保持一致关联。为了解决这些问题,我们提出了一个端到端的多摄像头三维跟踪框架 MUTR3D。与以往方法不同,MUTR3D 并不显式依赖目标的空间或外观相似度,而是引入了三维跟踪查询(3D track query),用于为每个跨帧跨摄像头出现的目标构建空间与外观一致的轨迹。在每一帧中,MUTR3D 使用相机变换将三维跟踪器与其在多视图下的二维观测联系起来,然后利用这些跨摄像头的特征对跟踪结果进行迭代更新。MUTR3D 通过集合到集合的损失函数来度量预测结果和真值之间的差异,因此无需任何后处理步骤(如非极大值抑制、边界框关联或目标重识别)。在 nuScenes 数据集上,MUTR3D 相较于最先进的方法,在 AMOTA 指标上平均提升了 5.3 个点。代码已开源: https://github.com/a160012888/MUTR3D 。

贡献(Contributions)

  1. 首个端到端多摄像头三维跟踪框架
    到目前为止,MUTR3D 是首个真正无缝融合检测与跟踪、并去除所有常用后处理(包括 NMS、框关联、Re-ID 等)的多摄像头 3D MOT 方法。与现有的“先检测再跟踪”方法不同,我们的方法隐式地建模了目标轨迹的空间与外观变化。

  2. 创新的三维跟踪查询(3D Track Query)
    我们为每条轨迹分配一个可更新的三维参考点和查询特征,每一帧从所有可见摄像头的图像特征中抽取信息,用于端到端地创建、跟踪和终止轨迹。来自同一查询的不同帧输出自然地构成了完整的目标生命周期,无需额外匹配或关联模块。

  3. 领先的实验表现
    在 nuScenes 仅视觉的三维跟踪基准上,MUTR3D 达到了 27.0% 的 AMOTA,相比现有最优方法提升了 5.3 个百分比,且在多摄像头设置下显著降低了身份切换次数(ID switch)。

2. 相关工作

2.1 基于摄像头的 3D 多目标跟踪

传统的三维多目标跟踪往往借助卡尔曼滤波或简单的 3D IoU/距离度量,对每帧检测结果进行状态预测与关联。近年随着深度学习的发展,也出现了在特征空间中学习运动模型与外观特征的做法,或者基于图神经网络的关联方法。

2.2 基于摄像头的 3D 检测

最新算法多沿用两阶段思路:先用单目深度或 BEV 模型获取三维候选,再对其优化。但在多摄像头场景下直接在 3D 空间中协同融合多视角特征,尚有待深入研究。

2.3 基于查询的检测与跟踪

DETR 首创了基于查询(query)的集合式检测思想,TransTrack、MOTR 等将其扩展到 2D 跟踪。MUTR3D 则将查询扩展到多摄像头三维场景,并引入运动模型以处理 3D 目标的时序变化。

3. 方法

detection 600 query: 一直检测当前帧的新目标(new query)
tracking 300 query: 维护之前累计的追踪目标(old query)
第一帧: 
ref_points正常生成
这时候检测的都是新目标,如果检测出的物体》=一定阈值,会将detection中的query当作active query移植到old query中。detection query 和GT做匹配。
第一帧结束检测后,对ref_points进行运动补偿velo_update();
mem_bank进行更新
qim对活跃的query抽取并生成fp第二帧:
detection 600 query:检测new目标
tracking 300 query: 检测old目标
匹配分两步做:
old query先做和GT能匹配上的indice1; 
剩余没有匹配上的GT和没有匹配上的query进行匹配,获得indice2;
indice1和indice2的融合是最终第二帧计算loss的匹配matched_idx 关心的是 “这条查询在当前帧该对上哪一个 GT?” 
obj_idx 则是 “这条查询属于哪个全局 track(哪辆车/哪行人)?” tracking id
mem_bank进行更新
qim对活跃的query抽取并生成fp
检测结束后,对ref_points进行运动补偿velo_update();第三帧:
重复, 300个old query是长度是动态变化的;这里没有讲增加fp的增加,如果逻辑太难理解,可以先去除fp来实现;这里tracking帧间的融合信息都是Instances

3.1 基于查询的三维目标跟踪

查询类型

  1. 新生查询(newborn queries):用于检测当前帧中新出现的目标。

  2. 老生查询(old queries):用于持续跟踪之前已出现且未消失的目标。

  3. 标签分配(label assignment)
    按照 Hungarian 一对一匹配原则,新生查询与当前帧 GT 匹配来产生检测监督,老生查询以相同 GT 进行跟踪监督。

在这里插入图片描述

3.2 多摄像头 Track Query 解码

Transformer 解码头同时对查询进行自注意力(query–query)和跨注意力(query–image)操作,跨注意力会将三维参考点投影到各相机像素平面,双线性插值得到多层次特征,再结合查询自身特征输出当前帧的候选框。

3.3 查询初始化与特征提取

初始化:为每个新生查询分配一个可学习的三维参考点 𝑐𝑖,通过共享 MLP 从查询嵌入 𝑞𝑖解码得到。
特征提取:将 𝑐𝑖 透视投影到每个相机图像平面,基于 FPN 多尺度特征用加权和得到点特征,再与查询嵌入结合,为解码提供跨摄像头信息。

3.4 三维目标参数化

使用两个小型全连接网络(FFN)分别回归三维框的中心位置增量、尺寸和朝向,以及类别置信度。三维框中心最终表示为:xi=ci+MLP(qi)x_i =c_i + MLP(q_i) xi=ci+MLP(qi)

3.5 查询生命周期管理

移除条件

新生查询若分类分数低于阈值 t new,则视为无效并删除。老生查询若连续 𝑇 帧分数低于阈值 t old
​,则终止该轨迹。训练阶段,所有与“空目标”匹配的查询会被标记为 inactive,不再更新。

3.6 查询更新与运动模型

过滤掉过期查询后,保留的老生查询会被更新其特征和三维参考点,以建模目标动态并补偿自车运动。本文采用一种基于查询预测速度 𝑣𝑖的运动模型:
ci←Rt+1−1(Rt(ci+viΔt)+Tt−Tt+1),\mathbf{c}_i \leftarrow R_{t+1}^{-1}\Bigl( R_t\bigl(\mathbf{c}_i + \mathbf{v}_i\,\Delta t\bigr) + T_t - T_{t+1} \Bigr)\,,ciRt+11(Rt(ci+viΔt)+TtTt+1),

其中 (𝑅𝑡,𝑇𝑡) 为当前帧自车位姿,Δt 为帧时差,速度由一个小型 FFN 从查询特征中预测并以 GT 监督。

def _generate_empty_tracks(self):'''Returns:'''track_instances = Instances((1, 1))num_queries, dim = self.query_embedding.weight.shape  # (300, 256 * 2) device = self.query_embedding.weight.devicequery = self.query_embedding.weighttrack_instances.ref_pts = self.reference_points(query[..., :dim // 2]) # 获得第一帧的ref point# init boxes: xy, wl, z, h, sin, cos, vx, vy, vzbox_sizes = self.bbox_size_fc(query[..., :dim // 2])pred_boxes_init = torch.zeros((len(track_instances), 10), dtype=torch.float, device=device)pred_boxes_init[..., 2:4] = box_sizes[..., 0:2]pred_boxes_init[..., 5:6] = box_sizes[..., 2:3]track_instances.query = query #检测querytrack_instances.output_embedding = torch.zeros((num_queries, dim >> 1), device=device)track_instances.obj_idxes = torch.full((len(track_instances),), -1, dtype=torch.long, device=device)# 记录全局的tracking id,长度都味dim//2, query的长度track_instances.matched_gt_idxes = torch.full((len(track_instances),), -1, dtype=torch.long, device=device)  #记录和上一帧匹配的idx,默认-1track_instances.disappear_time = torch.zeros((len(track_instances), ), dtype=torch.long, device=device)  #infer使用track_instances.scores = torch.zeros((len(track_instances),), dtype=torch.float, device=device) track_instances.track_scores = torch.zeros((len(track_instances),), dtype=torch.float, device=device) #分类得分的最高值# xy, wl, z, h, sin, cos, vx, vy, vztrack_instances.pred_boxes = pred_boxes_init #目标其他的属性,xyzwhlyaw,vlocitytrack_instances.pred_logits = torch.zeros((len(track_instances), self.num_classes),dtype=torch.float, device=device) #分类的回归mem_bank_len = self.mem_bank_len track_instances.mem_bank = torch.zeros((len(track_instances), mem_bank_len, dim // 2),dtype=torch.float32, device=device) #用于mem bank中时序融合track_instances.mem_padding_mask = torch.ones((len(track_instances), mem_bank_len),dtype=torch.bool, device=device)  #用于mem bank中时序融合track_instances.save_period = torch.zeros((len(track_instances), ), dtype=torch.float32, device=device) #infer使用return track_instances.to(self.query_embedding.weight.device)

这里作者类别loss是1对多的,为了是防止检测的抖动,但是后续这种方式在bev range的边缘处会出现消失不掉的query,这里还是建议loss的匹配都用1对1的匹配;

http://www.xdnf.cn/news/1127431.html

相关文章:

  • 快速了解 HTTPS
  • 【BUG处理】构建APK时遇到错误:‘flutter‘ 命令未被识别。这通常表示您的系统中未安装Flutter SDK或环境变量配置不正确。
  • 【亲测有效】ubuntu20.04服务器新建用户+vnc配置教程
  • 基于按键开源MultiButton框架深入理解代码框架(二)(指针的深入理解与应用)
  • 【橘子分布式】Thrift RPC(编程篇)
  • OMPL安装问题:CMake报错找不到ompl依赖
  • Linux探秘坊-------14.信号
  • Axios 完整功能介绍和完整示例演示
  • OSPFv3中LSA参数
  • 【Luogu】每日一题——Day3. P6392 中意 (数学 取模)
  • 【深度学习优化算法】06:动量法
  • Sentinel热点参数限流完整示例实现
  • 高温车间(60℃+)如何选高温/宽温边缘网关设备?
  • 如何把手机ip地址切换到外省
  • Datawhale 25年7月组队学习coze-ai-assistant Task1学习笔记:动手实践第一个AI Agent—英伦生活口语陪练精灵
  • 学习C++、QT---26(QT中实现记事本项目实现文件路径的提示、现在我们来学习一下C++类模板、记事本的行高亮的操作的讲解)
  • etcd自动压缩清理
  • QT——QComboBox组合框控件
  • Flink实战项目——城市交通实时监控平台
  • 函数柯里化详解
  • Luban配置教程
  • 如何在simulink中怎么获取足端轨迹代码解释?
  • 【卡尔曼滤波第六期】集合变换卡尔曼滤波 ETKF
  • PyTorch笔记7----------计算机视觉基础
  • SSM框架学习DI入门——day2
  • flutter弹窗:fluttertoast
  • AI-Compass LLM训练框架生态:整合ms-swift、Unsloth、Megatron-LM等核心框架,涵盖全参数/PEFT训练与分布式优化
  • 开通保存图片权限
  • 专业文档搜索工具,快速定位文本内容
  • 简单2步配置CadenceSkill开发编辑器,支持关键字高亮