《Observation-Centric SORT: Rethinking SORT for Robust Multi-Object Tracking》论文阅读笔记

SORT and OC-SORT


Abstract

作者提出基于运动特征的模型近年来未被完全开发,现有的很多算法往往假设物体线性运动,因此对于非线性或遮挡情况效果不好,需要高帧率的视频。作者强调了observation对于恢复丢失的track以及减小线性运动模型带来的误差的重要性,提出了OC-SORT,并且在KITTI、DanceTrack上实现SOTA。

1. Introduction

作者希望设计一个运动模型来应对多目标跟踪任务中出现的遮挡及非线性运动问题,目前大部分运动模型误差来源于假设物体线性运动。作者希望在不利用外貌特征的前提下解决这些问题并提高跟踪的鲁棒性。
SORT是一个常用的运动模型算法,使用卡尔曼滤波来估计物体的运动。不同于estimation-centric的SORT方法,作者提出了observation-centric的方法,解决了SORT带来的三大问题:

  1. sensitive to state noise:对于高帧率视频,目标位移的噪声可能就和位移大小本身差不多,会提高对噪声的敏感性
  2. error accumulation:当没有新的检测结果与当前轨迹匹配时,误差会不断累积
  3. estimation-centric:SORT依赖于卡尔曼滤波的预测,observations仅仅作为辅助

为了解决上述问题,作者提出了本文的三项创新点

  1. observation-centric online smoothing(OOS):对于跟踪中断后又重新与检测结果匹配的轨迹,对该目标上次消失前最后一次观测到再次被重新观测之间建立一个虚拟轨迹,并利用该轨迹来平滑卡尔曼滤波参数
  2. observation-centric momentum(OCM):在cost matrix中加入了轨迹方向的一致性,证明了对相隔比较大的两点之间的方向进行估计可以减少噪声
  3. observation-centric recovery(OCR):为了减少在短时内目标因遮挡成为inactive的问题,作者提出了根据它们新就旧观测进行恢复的策略

OC-SORT的贡献可总结为以下三点:

  1. 分析了SORT的三大limitations
  2. 提出OC-SORT并创新性设计了OOS、OCM、OCR
  3. 在MOT基准上达到新SOTA

2. Related Works

回顾了一些经典的motion models,以及基于检测的跟踪,利用外观信息的跟踪,以及基于Transformer的跟踪方法,但是这些方法在很多情况下都有局限性。

3. Rethinking SORT

3.1 Background

介绍了Kalman Filter和SORT,KF可分解为预测更新两部分,在预测部份通过t-1帧的信息预测第t帧,计算公式如下
在这里插入图片描述
并利用第t帧的观测信息来更新当前帧的状态,如下所示
在这里插入图片描述
SORT是一个基于KF的运动模型,其中的状态 x \rm{x} x为包含7个元素的元组 x = [ u , v , s , r , u ˙ , v ˙ , s ˙ ] \rm{x} = [u, v, s, r, \dot{u}, \dot{v}, \dot{s}] x=[u,v,s,r,u˙,v˙,s˙] ( u , v ) (u, v) (u,v)代表二维坐标, s s s代表尺度, r r r代表bbox的比例,后三项为导数。观测结果 z = [ u , v , w , h , c ] T \rm{z} = [u, v, w, h, c]^T z=[u,v,w,h,c]T,其中 ( u , v ) (u,v) (u,v)为坐标, ( w , h ) (w, h) (w,h)为宽高, c c c为置信度。
SORT使用线性运动模型,因此transition model可以表示为
在这里插入图片描述
从而可以得到相邻两帧的位置关系
在这里插入图片描述
当视频帧率较高的时候,SORT在非线性运动情况下也能达到较好的效果,因为在较短的时间间隔内,物体可认为是线性运动。

3.2 Limitations of SORT

3.2.1 Sensitive to State Noise

假设物体坐标的满足 u ∼ N ( μ u , σ u 2 ) , v ∼ N ( μ v , σ v 2 ) u \sim N(\mu_u, \sigma_u^2), v \sim N(\mu_v, \sigma_v^2) uN(μu,σu2),vN(μv,σv2),由于线性运动,可以得到速度如下
在这里插入图片描述
从而速度估计结果满足 δ u ˙ ∼ N ( 0 , 2 σ u 2 ( Δ t ) 2 ) , δ v ˙ ∼ N ( 0 , 2 σ v 2 ( Δ t ) 2 ) \delta_{\dot{u}} \sim N(0, \frac{2\sigma_u^2}{(\Delta t)^2}), \delta_{\dot{v}} \sim N(0, \frac{2\sigma_v^2}{(\Delta t)^2}) δu˙N(0,(Δt)22σu2),δv˙N(0,(Δt)22σv2),因此通过连续帧估计速度得到的噪声值最大。

3.2.2 Temporal Error Magnification

对于公式(5)的分析,我们假设前后两帧的运动估计是相互独立的,但对于KF,当前状态的位置估计量依赖于先前状态。当观测结果存在时,可以利用观测结果来指导KF的更新阶段。但当观测结果不存在时,KF只能基于自己的预测来进行更新。
考虑一段在第t帧与第t+T帧之间被遮挡的轨迹,假设速度的噪声分布 δ u t ˙ ∼ N ( 0 , 2 σ u 2 ) , δ v t ˙ ∼ N ( 0 , 2 σ v 2 ) \delta_{\dot{u_t}} \sim N(0,2\sigma_u^2), \delta_{\dot{v_t}} \sim N(0,2\sigma_v^2) δut˙N(0,2σu2),δvt˙N(0,2σv2),第t+T帧的位置估计为
在这里插入图片描述
其噪声分布满足 δ u ˙ t + T ∼ N ( 0 , 2 T 2 σ u 2 ) , δ v ˙ t + T ∼ N ( 0 , 2 T 2 σ v 2 ) \delta_{\dot{u}_{t+T}} \sim N(0,2T^2\sigma_u^2), \delta_{\dot{v}_{t+T}} \sim N(0,2T^2\sigma_v^2) δu˙t+TN(0,2T2σu2),δv˙t+TN(0,2T2σv2),可见在没有观测结果的情况下,噪声会不断累积放大。

3.2.3 Estimation-Centric

KF的一个很大的问题在于它是以estimation为中心的,外部的observation只是用于辅助更新,对于一个鲁棒的跟踪器,其往往需要更多关注观察的结果而非KF的状态估计。

4 Observation-Centric SORT

4.1 Observation-centric Online Smoothing (OOS)

当一个轨迹中断后,重新与观测结果关联时,作者使用OOS为该对象构建一条虚拟轨迹,从跟踪丢失之前的最后一个检测开始,到新匹配到检测结束。沿着这个虚拟轨迹,平滑卡尔曼滤波器参数,以获得更好的目标位置估计。

4.2 ObservationCentric Momentum (OCM)

线性运动模型假定速度方向一致,然而由于物体的非线性运动和状态噪声,这种假设往往不成立。较短的时间间隔内物体可认为是线性运动,但是由于噪声的存在,很难去充分利用物体运动方向的连续性信息。作者提出了OCM,将动量添加到成本矩阵中,如下所示
在这里插入图片描述
X ^ \hat{X} X^为目标的估计状态矩阵, Z Z Z为检测的状态矩阵, V V V是包含由之前两次时差观测值计算的现有轨迹的方向。 C I o U ( , ) C_{\rm{IoU}}( , ) CIoU(,)计算负对检测框和预测值之间的IoU值, C v C_v Cv计算轨迹的方向和由轨迹的历史检测和新检测形成的方向, λ λ λ是权重因子。该方法使用与轨迹相关的检测值进行方向计算,以避免估计状态下的误差累积,我们可以自己权衡观测点之间的时间差。在线性运动模型下,噪声大小与两个观测点的时间差成正比。在很短的时间间隔内,轨迹可以近似看成线性的,所以时间差不能太大。

4.3 ObservationCentric Recovery (OCR)

由于检测器的不可靠,检测物体发生重叠和非线性运动,常常发生轨迹中断。作者提出OCR,轨迹的回复依赖于检测值而不是错误的估计值。当轨迹丢失后检测目标再出现时,直接将丢失轨迹时检测值和重新出现的检测值相关联以恢复轨迹。

5 Experiments

5.1 Experimental Setup

介绍了在数据集、实现、评价标准的一些内容。

5.2 Benchmark Results

  1. MOT17,私有检测
    在这里插入图片描述
  2. MOT20,私有检测
    在这里插入图片描述
  3. MOT17,公共检测
    在这里插入图片描述
  4. MOT20,公共检测
    在这里插入图片描述
  5. DanceTrack测试集
    在这里插入图片描述
  6. KITTI测试集
    在这里插入图片描述

5.3 Ablation Study

  1. OOS、OCM、OCR组件消融实验
    在这里插入图片描述
  2. OOS虚拟轨迹假设类型消融实验
    在这里插入图片描述
  3. OCM中 Δ t \Delta t Δt取值消融实验
    在这里插入图片描述
  4. 后处理插值方法消融实验
    在这里插入图片描述

6 Conclusion

分析了SORT的不足之处,提出了基于观测结果的OC-SORT,在非线性运动以及遮挡情况下取得了较好的效果。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
这个错误可能是因为您的 Eigen 版本太旧,不支持 `mean()` 方法。您可以尝试更新 Eigen 版本,或者使用 Eigen 的 `MatrixBase` 类型和 `mean()` 函数来计算均值。 以下是使用 `MatrixBase` 和 `mean()` 函数来计算均值的修改后的代码: ```c++ #include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> using namespace Eigen; class VARModel { public: VARModel(int p); void addObservation(const VectorXd& observation); void estimateCoefficients(); VectorXd predict(int steps); private: int p_; int n_; std::vector<VectorXd> observations_; MatrixXd A_; VectorXd b_; }; VARModel::VARModel(int p) : p_(p), n_(0), A_(p, p), b_(p) { A_.setZero(); b_.setZero(); } void VARModel::addObservation(const VectorXd& observation) { if (n_ == 0) { n_ = observation.size(); } observations_.push_back(observation); } void VARModel::estimateCoefficients() { int T = observations_.size() - p_; MatrixXd X(T, p_ * n_); VectorXd y(T * n_); for (int i = 0; i < T; ++i) { for (int j = 0; j < p_; ++j) { X.block(i, j * n_, 1, n_) = observations_[i + j].transpose(); } y.segment(i * n_, n_) = observations_[i + p_]; } A_ = (X.transpose() * X).inverse() * X.transpose() * y; b_ = y.mean() - A_.transpose() * X.colwise().mean(); } VectorXd VARModel::predict(int steps) { VectorXd prediction(n_ * steps); VectorXd x(n_ * p_); for (int i = 0; i < p_; ++i) { x.segment(i * n_, n_) = observations_.back() - b_; } for (int i = 0; i < steps; ++i) { x.segment(0, n_ * (p_ - 1)) = x.segment(n_, n_ * (p_ - 1)); x.segment(n_ * (p_ - 1), n_) = A_.transpose() * x + b_; prediction.segment(i * n_, n_) = x.segment(n_ * (p_ - 1), n_); } return prediction; } int main() { int p = 2; VARModel model(p); VectorXd observation(2); observation << 1.0, 2.0; for (int i = 0; i < 10; ++i) { model.addObservation(observation); observation += VectorXd::Random(2); } model.estimateCoefficients(); VectorXd prediction = model.predict(5); std::cout << "Predictions: " << std::endl << prediction << std::endl; return 0; } ``` 在这个修改后的实现中,我们使用 `colwise()` 方法和 `mean()` 函数来计算矩阵的每一列的均值,得到一个 p 维向量。然后,我们使用这个向量来计算 b。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值