【StrongSort 03】多轨迹算法StrongSort改进点

Strongsort改进点

StrongSORT(论文 StrongSORT: Make DeepSORT Great Again )在 DeepSORT 基础上提出的四项在线改进 + 一项相机运动补偿。本工程全部实现为可开关参数,五项统一默认开启 (测试脚本加对应 --no-nsa / --no-ema / --no-mc / --no-wo-c / --no-ecc 关闭)。全部改进都在线逐帧完成,无离线后处理(原版 StrongSORT 的 AFLink、GSI 未引入)。


一、NSA------卡尔曼观测噪声按置信度自适应

针对的问题:DeepSORT 的卡尔曼滤波对所有检测一视同仁,观测噪声 R 固定。但检测置信度有高有低------低置信度框位置往往更不准,用同样的 R 去修正状态,会把不可靠的观测"当真",污染预测。

改进做法:观测噪声随检测置信度缩放,置信度越低、观测噪声越大、这帧观测的话语权越小。

R N S A = ( 1 − c k ) 2 ⋅ R R_{NSA} = (1 - c_k)^2 \cdot R RNSA=(1−ck)2⋅R

其中 c k c_k ck 是当前帧检测置信度。置信度 0.9 的框噪声缩到 0.01 倍(修正力度大),置信度 0.3 的框噪声缩到 0.49 倍(修正力度小)。

源码位置 :strong_sort/sort/kalman_filter.py

函数 行为
project(mean, covariance, confidence, nsa) 第 150-151 行:if nsa: std = [(1 - confidence) * x for x in std],噪声标准差逐项乘 (1−置信度),R = diag(std²)
update(mean, covariance, measurement, confidence, nsa) 第 184 行:把 confidence 和 nsa 透传给 project,新息协方差 S = HPHᵀ + R_NSA

链路 :检测置信度从 Track.update()(track.py 第 169-171 行)透传给 kf.update,再传入 kf.project。置信度一路从检测走到滤波核,无额外存储。

开关与参数 :--no-nsa 关闭(默认开启)。


二、EMA------特征指数滑动平均替代特征库

针对的问题:DeepSORT 每条轨迹维护一个特征库(Gallery,最多 nn_budget 条),匹配时取与库内所有特征的最小距离。问题有二:① 库里积攒了目标早期(可能已被遮挡前)的外观,外观变化后老特征拖后腿;② 库存取和逐条比对有开销,且库容超限后"踢掉最老的"策略并不可靠。

改进做法:轨迹特征不再攒库,而是每帧与检测特征做指数滑动平均,只保留一条不断更新的平滑特征:

e f = α ⋅ e f − 1 + ( 1 − α ) ⋅ f k α = 0.9 e_f = \alpha \cdot e_{f-1} + (1 - \alpha) \cdot f_k \qquad \alpha = 0.9 ef=α⋅ef−1+(1−α)⋅fkα=0.9

新特征只占 10% 的权重------单帧错检、光照突变不会立刻带偏轨迹特征;而目标外观的真实渐变(转动、缩放)会随时间平滑跟进。平滑结果重新归一化。

源码位置 :strong_sort/sort/track.py Track.update() 第 173-179 行

python 复制代码
feature = detection.feature / np.linalg.norm(detection.feature)
if self._ema:
    smooth_feat = self._ema_alpha * self.features[-1] + (1 - self._ema_alpha) * feature
    smooth_feat /= np.linalg.norm(smooth_feat)
    self.features = [smooth_feat]      # 库里永远只有这一条平滑特征
else:
    self.features.append(feature)      # 关闭时退回 DeepSORT 的 Gallery 攒库

配套改动 :EMA 模式下特征库容量自动置 1(strong_sort/__init__.py 工厂函数:nn_budget = 1 if args.ema else args.nn_budget)------库里本来就只有一条,容量无需更大;NearestNeighborDistanceMetric.distance 与库内单条特征做一次余弦即为代价。

开关与参数 :--no-ema 关闭(默认开启),--ema-alpha 调平滑系数(默认 0.9)。


三、MC------关联代价融合外观与运动

针对的问题:DeepSORT 的外观关联只看特征余弦距离,马氏距离只用来"一刀切"门控(超阈值直接禁止配对,阈值内不参与代价)。两个候选检测外观都很像、又都在门控内时,目标运动趋势的信息被浪费了。

改进做法:把马氏运动距离按权重揉进关联代价,两路信息加权融合:

c i j = λ ⋅ c a p p e a r a n c e + ( 1 − λ ) ⋅ d M a h a l a n o b i s λ = 0.98 c_{ij} = \lambda \cdot c_{appearance} + (1 - \lambda) \cdot d_{Mahalanobis} \qquad \lambda = 0.98 cij=λ⋅cappearance+(1−λ)⋅dMahalanobisλ=0.98

外观仍是主导(0.98),运动距离作为细微裁决项------外观打平时,预测位置更近的那个检测胜出。

源码位置 :strong_sort/sort/linear_assignment.py gate_cost_matrix() 第 220-227 行

python 复制代码
gating_threshold = kalman_filter.chi2inv95[4]
...
cost_matrix[row, gating_distance > gating_threshold] = gated_cost   # 先门控:物理上不可能的配对写死 1e+5
if mc:                                                               # 再融合:λ·外观 + (1−λ)·马氏
    cost_matrix[row] = mc_lambda * cost_matrix[row] + (1 - mc_lambda) * gating_distance

注意顺序:先门控后融合------被门控的格子 1e+5 也会被融合拉低一点,但量级仍远超配对上限 max_distance,不会造成错误配对。

开关与参数 :--no-mc 关闭(默认开启),--mc-lambda 调融合系数(默认 0.98)。


四、woC------去掉匹配级联,单轮全局匹配

针对的问题:DeepSORT 的外观匹配是"级联"的:按轨迹丢失帧数分层(刚丢 1 帧的先匹配,丢 2 帧的下一层......),一层一轮匈牙利算法。设计初衷是让新检测优先分给最近见过的轨迹,但代价是:① 分层后每层只跟一部分轨迹比,全局最优可能被层序拆散;② 多层循环多轮匈牙利,开销更大。

改进做法:不分层,全部确认轨迹与全部检测一轮全局匈牙利匹配比完(级联深度等效为 1)。StrongSORT 论文的消融实验显示,检测质量足够好时级联的"优先级"并不必要,单轮全局匹配反而又快又准。

源码位置 :strong_sort/sort/linear_assignment.py matching_cascade() 第 149-158 行(wo_c 分支)

python 复制代码
if wo_c:
    track_indices_l = [k for k in track_indices]     # 全部轨迹同一轮(不分层)
    matches_l, _, unmatched_detections = \
        min_cost_matching(distance_metric, max_distance, tracks, detections,
                          track_indices_l, unmatched_detections)
    matches += matches_l
else:                                                # 原版级联:按 time_since_update 分层逐层匹配
    for level in range(cascade_depth):
        ...

关闭 woC 时走 else 分支,行为与 DeepSORT 原版级联完全一致(第 160-175 行)。

开关与参数 :--no-wo-c 关闭(默认开启)。


五、ECC------相机运动补偿(默认开启)

针对的问题:卡尔曼预测假设相机静止------上一帧在 (100, 200) 的目标,这一帧预测外推就画在附近。相机一动(云台转动、车载),全部轨迹的预测框整体偏移,马氏门控和 IoU 匹配双双失效,ID 跳变。

改进做法:逐帧在线估计相机运动矩阵,先把上一帧的轨迹框"搬"到当前帧坐标系,再做卡尔曼预测和匹配:

① _camera_motion(strong_sort/strong_sort.py):当前帧 vs 上一帧灰度图(缩到 0.1 倍加速),调 ECC 算法估计欧氏变换矩阵 (旋转+平移,2x3);变换畸变过大(矩阵范数异常)时视为无运动。ECC 参数:eps=1e-5、max_iter=100、scale=0.1。

② Tracker.camera_update → Track.camera_update(strong_sort/sort/track.py):每条轨迹的 tlbr 两角做仿射变换,重写卡尔曼状态均值前 4 维------轨迹框先跟上相机,再进入本帧预测-匹配流程。

源码位置 :ecc.py 的 ECC() 函数(工程适配版,仅保留在线逐帧计算所需的 ECC 函数,核心是 cv2.findTransformECC)。

开关与参数 :--no-ecc 关闭(默认开启)。ECC 在缩到 0.1 倍的小图上迭代,开销很小(720p 实测约 2-3 毫秒/帧);静止相机的小幅抖动会被匹配容错吸收,开着对跟踪结果没有可见改善,介意可关闭;运动相机场景(持续平移/旋转)才能体现价值。


六、改进项速查表

改进 全称 作用环节 源码位置 默认 开关参数
NSA Noise Scale Adaptive Kalman Filter 卡尔曼修正(观测噪声) strong_sort/sort/kalman_filter.py project/update 开启 --no-nsa 关
EMA Exponential Moving Average 特征更新(轨迹外观记忆) strong_sort/sort/track.py Track.update 开启 --no-ema 关
MC Motion-aware Cost 外观匹配代价(融合马氏距离) strong_sort/sort/linear_assignment.py gate_cost_matrix 开启 --no-mc 关
woC without Cascade 外观匹配策略(去级联) strong_sort/sort/linear_assignment.py matching_cascade 开启 --no-wo-c 关
ECC Enhanced Correlation Coefficient 相机运动补偿(预测前校正) ecc.py ECC + strong_sort/strong_sort.py _camera_motion 开启 --no-ecc 关

各项相互独立、可任意组合:如只测 NSA 单项贡献,跑 --no-ema --no-mc --no-wo-c --no-ecc(保留 NSA);基线(全关、等价 DeepSORT)跑 --no-nsa --no-ema --no-mc --no-wo-c --no-ecc。对比分析方法见 test/analyze_track_compare.py 。

描述 链接
项目 基于 Ultralytics + StrongSort 多目标跟踪与改进
往期回顾 链接
数据集 数据集汇总
软件开发 深度学习软件开发汇总
相关推荐
4SAPI1 小时前
多国产模型混合调度与企业级治理生产选型指南:4SAPI、硅基流动与 OpenRouter 的架构权衡
大数据·人工智能·架构·php
武子康1 小时前
Cosmos Curator 总览:从一条样本的组成,选对数据处理入口
人工智能·后端·agent
XMAIPC_Robot1 小时前
-40~85℃宽温实测:RK3588 机器人控制器硬件底座,长时间 SLAM 定位稳定性验证
人工智能·fpga开发·机器人·边缘计算·arm+fpga·rk3588+fpga
傅科摆 _ py2 小时前
DP,贪心,堆和栈,二分力扣复习
开发语言·python·算法
锋行天下2 小时前
Langgraph 运行时上下文使用示例
人工智能
zandy10112 小时前
中电金信金融 AI 工程化实践:异构模型纳管、智能体治理与 AI 原生软件工厂
人工智能·金融
吴佳浩2 小时前
中小企业跑125B 大模型:显存装不下的时候,Strata 做了什么
人工智能·llm
学IT的周星星2 小时前
LangGraph:用「流程图」的方式编排 Agent
数据库·人工智能·大模型·llm·流程图·agent
NC 王炸2 小时前
不用 API Key,也能让网页调用 AI?Opera 把本地模型接进了浏览器
人工智能·浏览器扩展·ai 工具·本地 ai·opera·webai
锋行天下2 小时前
Langgraph 实现类似Langchain记忆上下文过长裁剪
人工智能·后端