ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

数据关联算法深度总结:从最近邻到MHT与深度学习

数据关联算法深度总结:从最近邻到MHT与深度学习 数据关联data association这个问题几乎是我这些年做过所有感知系统项目里最容易出问题、也最容易被低估的一环。做雷达目标跟踪的时候一个点迹该接在哪条航迹后面错了就是航迹断裂和目标号交换做视觉多目标跟踪的时候当前帧的一堆检测框和上一帧的轨迹怎么对应错了就是ID Switch身份跳变做SLAM的时候当前帧点云到底该和地图里的哪个关键帧对齐错了可能就是整个位姿图被污染。代码框架换了一茬又一茬底层真正决定上限的始终是数据关联那一个环节。这篇数据关联算法总结我自己维护了很多年从最早做雷达点迹-航迹关联到后来做视觉多目标跟踪再到现在碰SLAM和传感器融合几乎每个项目都会绕回同一个问题我到底该用哪种关联算法所以我把这些年用过的、看过别人用的、踩过坑的关联算法整理成一份持续更新的笔记。这篇文章是其中最关键的一部分适合刚接触多目标跟踪的初学者也适合已经在工程里被关联问题折磨过的开发者。我会尽量把每个算法的适用边界、数学直觉和工程代价都讲清楚而不是只堆公式。1. 先把问题框清楚数据关联到底在解哪一类数学问题1.1 为什么叫“关联”而不是“匹配”很多朋友第一次接触这个概念觉得数据关联不就是一个匹配问题吗把最近的点和最近的轨迹连起来就行。但真实场景远比这复杂。匹配通常是已知两边集合找一个一一对应关联则是在一定不确定性下决定“哪些量测属于哪些目标”同时还要处理新目标出现、旧目标消失、虚假量测、漏检、遮挡、目标交叉等一系列情况。举个例子雷达某一帧扫出12个点迹当前系统里维护着8条航迹。你不能简单说把每个点迹分给最近的航迹因为有的点迹可能是虚警有的点迹可能是新目标第一次被发现有的航迹这一帧可能没有对应的点迹漏检还有两个目标交叉时点迹和航迹的对应关系本身就模糊。也就是说数据关联是带不确定性的、多对多的分配问题匹配只是它在运气最好时的一种特例。1.2 一个组合爆炸问题数据关联的数学形式其实很简洁设当前有 n 条航迹或目标某一帧来了 m 个量测我们要找到一个映射关系 a: {1..m} → {0,1..n}其中0表示该量测被判为虚警或新目标。听起来很简单但问题的规模增长得非常快。不考虑门控时n 个目标、m 个量测的可行关联方案数最粗糙的估计也在阶乘量级。10个目标10个量测不考虑其他限制完全分配的方案就有 10! 3,628,800 种到20个目标方案数到了 2.43×10^18普通算法根本枚举不完。这还没算每个量测可能是虚警、每个目标可能漏检的情况。所以数据关联领域的所有算法本质都是在做同一件事在不牺牲太多正确率的前提下用某种方式把搜索空间砍到可以接受的程度。1.3 数据关联的三个子问题我在做工程时习惯把数据关联拆成三个子问题这样定位问题会快很多候选生成也叫门控gating先粗筛一遍把明显不可能的量测排除掉只留下候选集合。代价计算对每个候选对航迹-量测计算一个“匹配成本”或“匹配似然”这步决定了后续分配的质量上限。分配/决策在候选集合基础上用某种策略确定最终关联可能是贪心、最优分配、概率加权也可能是延迟决策。这三个环节是相对独立的。实际项目里很多关联错误不是分配算法不行而是前面代价算错了或者门控根本没设对。后面讲每个算法时我都会把这三个环节串起来看。2. 从最近邻到全局最优分配匈牙利算法与马氏距离的成本逻辑2.1 最近邻为什么不够用最朴素的做法是最近邻Nearest NeighborNN每个量测分配给离它最近的航迹。每个航迹只取最近的一个量测一个量测也只能被一个航迹使用冲突时按距离优先。这个思路在目标稀疏、杂波少的场景确实能用但一旦两个目标靠得近或者杂波恰好出现在中间最近邻就很容易出错。我做雷达项目时遇到过一个典型场景两条航迹交叉交叉点附近有杂波点。最近邻把目标A的量测分给了航迹B以后航迹A只能去认领旁边一个杂波点结果两条航迹都开始偏最后互换身份。这种错误在工程里叫串扰track swap最近邻算法是完全无法避免的因为它只看单个候选对的局部距离不做全局统筹。2.2 把关联写成线性分配问题解决局部最优的正路是把关联建模成全局最优分配问题最常用的形式是线性分配Linear Assignment ProblemLAP。我们构造一个代价矩阵 C大小是 n×mC(i,j) 表示第 j 个量测分配给第 i 条航迹的代价。关联目标就变成了找到一组一一对应的分配使得总代价最小。这里代价不一定要用欧氏距离这是新手最容易忽略的地方。如果只用欧氏距离量测在不同维度上的量纲比如距离和速度会互相干扰而且没有把测量噪声的不确定性放进去。更合理的代价是马氏距离d² (z - Hx)ᵀ S⁻¹ (z - Hx)其中 z 是量测Hx 是预测的量测位置S 是新息协方差矩阵。欧氏距离在高斯分布呈扁椭圆状时会把距离椭圆中心近但方向偏差大的点当成最优点马氏距离则通过协方差矩阵做了白化把椭圆变成了圆再来量距离方向不对的点会被自动加大代价。2.3 匈牙利算法与工程实现线性分配问题的经典解法是匈牙利算法Hungarian Algorithm由 Kuhn 提出、Munkres 修订所以也叫 Kuhn-Munkres 算法。它的核心思想是利用标号label和可增广路径从任意初始分配出发不断找增广路来提升总匹配收益复杂度是 O(n³)。对大多数跟踪场景目标数在几十到几百这个量级O(n³) 完全够用。实际工程里我从不自己手写匈牙利算法。Python 环境下直接调 SciPyfrom scipy.optimize import linear_sum_assignment import numpy as np cost_matrix np.array([ [0.6, 1.2, 5.0], [5.0, 0.3, 0.9], [1.0, 4.0, 0.8] ]) row_ind, col_ind linear_sum_assignment(cost_matrix) print(row_ind, col_ind) # 每行匹配到的列索引注意 SciPy 里 linear_sum_assignment 求解的是最小值问题如果你的算法算出来是相似度/概率这种越大越好的量记得取负号。另外如果矩阵不是方形它也能自动按较小的维度求分配空出来的另一边会保持未匹配。这对处理“量测数不等于航迹数”非常有用。如果目标数量很大几百上千匈牙利算法的 O(n³) 会成为瓶颈这时可以换 Jonker-Volgenant 的 LAPJV 算法实际速度通常比标准匈牙利快好几倍在 MOT 挑战赛的官方代码里也经常看到。2.4 门控、哑元与“不匹配”的选项把代价矩阵喂给匈牙利之前一定要做门控。门控就是在代价矩阵里把那些距离太远的候选对直接去掉不允许它们参与分配。门限一般取马氏距离的卡方检验阈值。比如二维量测取 d² 9.21对应自由度2的卡方分布在置信度0.99时的临界值。这样做的意义不仅是砍计算量更重要的是防止某个航迹去配一个运动方向上完全离谱的量测。还有一个工程细节代价矩阵里必须留“不匹配”选项否则匈牙利算法会强行给每条航迹分一个量测。做法是给矩阵加哑元dummy通常是把超过门限的代价设置为一个很大的数或者为未分配的量测额外加一行/列。分配结果里如果某条航迹匹配上了哑元就认为它这一帧没有量测关联如果某个量测匹配上了哑元则认为它可能是新目标或虚警。接下来再用航迹起始和删除逻辑去处理。这一套“门控 马氏距离代价 匈牙利分配”的组合就是 SORT 和 Deep SORT 等视觉跟踪器在数据关联环节的核心。SORT 更极端直接把代价换成了检测框的 IOU交并比好处是免去了外观描述子和运动模型的调参坏处是一旦目标被遮挡几帧IOU 失去重叠跟踪就断了。3. 概率世界下的关联PDA和JPDA如何处理杂波与漏检3.1 全邻的思想起点匈牙利算法解决的是“把所有量测当作候选、硬选一个”的问题但有时候我们不想做硬决策。比如雷达在强杂波环境下每个目标附近有多个量测都说自己是来自这个目标的回波。你很难确定哪一个是真实的但你可以给每个候选算一个“它是真回波”的概率然后按概率加权去更新目标状态。这就是概率数据关联Probabilistic Data AssociationPDA的基本思想由 Bar-Shalom 等人提出也叫“全邻All-Neighbor”滤波。PDA 适合单目标跟踪目标只有一个当前帧有若干有效回波其中最多一个来自目标本身其余都是杂波。目标状态更新不是用某一个量测而是用所有候选回波的加权和权重就是每个回波属于目标的概率 βᵢ。3.2 多目标版本 JPDA把 PDA 扩展到多目标就是联合概率数据关联Joint Probabilistic Data AssociationJPDA。核心变化在于多条航迹争夺同一个量测时各航迹的关联概率不能独立算必须考虑联合事件。一个联合事件 θ 由每个目标的关联选择组成限制条件有两个每个量测最多只能源于一个目标每个目标最多只能接收一个量测。所有满足条件的联合事件构成一个集合然后通过贝叶斯公式计算每个联合事件的后验概率再边缘化得到每个“航迹-量测对”的关联概率 β_jt。目标状态更新时x̂ Σⱼ β_jt · xⱼ每个候选量测按概率加权参与状态更新。这听起来很完备但有个致命问题联合事件的数量随着目标和量测数急剧膨胀。教科书上的标准 JPDA 是星型结构star-structured组合爆炸当目标数和量测数超过十几个联合事件枚举就是灾难。所以工程里基本不会用原始 JPDA而是用修正版比如只考虑最可能的子事件或者用 Cheap JPDA 这类近似。3.3 轨迹合并问题与我的实测经验JPDA 最著名的毛病是轨迹合并track coalescence。当两个目标靠得很近时JPDA 会给两条航迹分配几乎一样的加权量测集合结果两条航迹的状态估值会互相靠近最后粘在一起变成一个目标。我在仿真里见过非常明显的效果两个目标并行接近后JPDA 输出的两条轨迹逐渐靠拢速度也都变成了同一个平均速度。缓解轨迹合并的常见做法是把关联概率往 0/1 方向锐化也就是把权重极端化减少软加权的影响或者直接在距离很近时切回硬决策。但说实话在密集多目标场景JPDA 不是我最优先的选择它更适合“目标数量少但杂波密”的场景比如红外小目标跟踪、雷达低可观测目标跟踪。目标数量超过10个还想稳定跟踪我建议直接看 MHT 或深度学习方法。3.4 PDA和JPDA需要的模型精度用概率关联算法时你对运动模型和滤波器的精度要求会比硬决策算法高得多。因为概率加权的结果里每一项权重都依赖预测的新息协方差 S。如果卡尔曼滤波器调得不一致比如过程噪声 Q 给得太大S 会虚胖门控范围变大杂波进入候选集的概率增加关联概率也会失真。我一般在调 PDA/JPDA 前会先做一个一致性检验统计新息innovation的归一化平方 NIS d²如果它在大部分时间超出卡方分布的置信区间说明滤波器协方差给得不匹配。协方差不准概率关联就是空中楼阁。这一步检查放在排查任何关联异常的第一步都不过分。4. 不急着下结论多假设跟踪MHT的延迟决策机制4.1 “布局未来”的关联哲学匈牙利和 JPDA 都是拿到一帧就立刻确定关联决策差别只是硬决策还是软决策。但某些场景下当前帧信息根本不够最合理的做法是“先不拍板把多种可能都留着等未来几帧信息够了再做最终裁决”。这就是多假设跟踪Multiple Hypothesis TrackingMHT。我第一次看 MHT 论文时觉得这思路太奢侈了保留若干候选航迹每个候选航迹其实是“对同一条目标的一条关联历史假设”随着帧数增加用似然判断这棵假设树里哪个分支最合理把不合理分支剪掉。它相当于把决策从“点估计”变成了“路径估计”。在检测率低、目标密集、航迹交叉多的场景MHT 的效果显著好于 JPDA。4.2 航迹树、全局假设与概率递推MHT 的数据结构核心是航迹树track tree树的根是航迹起始每个节点是一次“航迹 量测”的关联事件节点包括“和某个量测关联”和“没有量测漏检”两类。一条从根到叶的路径就是一个航迹假设。但 MHT 还有一个全局一致性约束所有航迹假设之间必须不相冲突即同一个量测不能被两条航迹同时使用。所以最后要维护的是若干全局假设global hypothesis每个全局假设是一组互相不冲突的航迹树节点的组合。全局假设的概率由量测似然、检测概率、虚警率递推更新。最后阶段我们按全局假设概率选取 K 个最优假设K-best用 Murty 算法求 K 个最优分配保留概率最大的那几个其余剪掉。剪枝还有两个经典手段N-scan backtrack 剪枝——当新的量测到来时只保留根节点往前 N 帧内概率最高的子节点分支确保树的深度不会无限增长以及直接限制全局假设数量 K 和树节点数量。4.3 工程落地复杂但值得MHT 的工程实现复杂度比前面所有算法都高维护的数据结构也更多。我见过不少团队在尝试 MHT 时代码量翻了几倍还可能引入内存泄漏和实时性问题。所以在描述它的优点后必须说清楚代价内存开销大每条假设都是一棵不断生长的树目标一多节点数是天文数字。参数敏感检测概率、虚警率这些先验参数直接决定假设概率的排序给错参数后 MHT 的表现可能还不如匈牙利。实时性需要工程技巧比如延迟决策控制在 N 帧以内K 值限制在20以内再配合多线程优化。但是一旦场景真的需要它收益也非常明显。我做机场场面监视雷达的项目时目标密集、速度快、检测率还不稳定用 JPDA 会出现轨迹交换换 MHT 以后即使目标交叉全局假设仍能保持身份一致性。这也是为什么空管、声呐、多目标跟踪这类高要求领域MHT 长期是标配方案。5. 地图层面上的数据关联JCBB与SLAM中的保守匹配5.1 SLAM里的错误关联是不可逆的前面讲的算法背景都是“目标跟踪”侧重当前帧量测与既有航迹的对应。SLAM 里有一个同样的难题但犯错代价完全不同回环检测loop closure时当前帧传感器数据要和整个历史地图做关联一旦关联错了后端图优化会把这个错误约束当成强约束然后把整个地图都扭曲掉。所以在 SLAM 的数据关联中我最看重的是“保守”。宁可漏检一次回环也不能错误关联一次回环。漏检最多丢失一个闭环修正机会错检则会直接破坏地图一致性而且很难人工排查。5.2 从单个相容到联合相容SLAM 早期最常用的数据关联是最近邻特征匹配把当前帧观测到的地标特征和地图里已有的地标特征做距离最近匹配。这在特征点清晰、独特性强时有效但遇到重复纹理、相似结构单特征匹配很容易出错。Neira 和 Tardós 提出的联合相容性分支定界Joint Compatibility Branch and BoundJCBB算法提供了一个更强的判据。它的核心思想是判断一组关联是否合理不能只看两两单点匹配而要看这组关联在误差传播下的联合分布是否一致。也就是把当前帧的一组量测和对应的一组地图特征放在一起计算联合马氏距离D eᵀ S⁻¹ e其中 e 是一组量测和预测的联合残差向量S 是联合新息协方差。即使某些单点匹配都满足阈值组合起来不一致的关联联合距离会变得非常大从而被拒绝。JCBB 用分支定界搜索所有可能的关联组合搜索过程中一旦发现某个分支的联合距离超限就整体剪掉。这比“逐点匹配再RANSAC筛选”要严格很多。5.3 现代SLAM里的关联其实是一套组合拳现在做视觉 SLAM、激光 SLAM很少有人只用一个关联算法了。实际系统里通常是一层层漏斗外观/描述子匹配ORB 特征描述子、ICP 或 NDT 粗配准先召回候选。几何验证RANSAC 剔除错误匹配或做 PnP/ICP 求解相对位姿并检验内点数。时间一致性确认回环候选要连续多帧都能被验证成功才真正接受。这套组合拳的本质就是把数据关联从“一次分配”升级成“多阶段验证”。JCBB 在这里可以理解为几何验证阶段的严格版判据特别适合激光 SLAM 中稠密地标做联合关联。我在实际项目里遇到过一个很典型的反例长廊场景下两端的视觉特征几乎一样词袋模型召回了好几个相似回环如果只靠描述子直接关联地图会沿走廊方向被拉长。加上几何验证和时间一致性后那些假回环全部被拒掉。5.4 图优化视角下的关联质量再往深一层看数据关联在 SLAM 里不仅负责“找对应”还决定了图优化中每个约束的信息矩阵权重。错误关联塞给后端的是一条错误的边权重越大破坏越强。所以我在调试后端优化前会先检查前端关联给出的约束残差如果某条回环约束的初始残差异常大肯定是关联错了必须先删掉不要指望优化器能“拉回来”。这个顺序很多新手容易搞反。6. 工程选型与调参心得从雷达到视觉再到SLAM6.1 一张表看清各算法的定位这些年我被问得最多的问题是“我到底该用哪个算法”我的回答永远是“看你的场景更接近哪种病”。下面这张表是我自己在选型时反复用的也方便你对照参考算法计算复杂度抗杂波/虚警密集目标表现实现成本典型场景NN 最近邻O(n)差差极低目标稀疏、风险可接受GNN 匈牙利O(n³)中中低视觉MOT、SORT类PDA单目标线性强不适用中雷达单目标杂波环境JPDA联合事件高强中易轨迹合并较高少量目标、杂波密度高MHT很高需剪枝最强最强高空管、声呐、密集目标JCBB分支搜索对错误关联保守用于特征关联中高SLAM特征/点云匹配注意这里没有“哪个算法更好”只有“哪个算法更匹配你的噪声和密度条件”。6.2 容易被忽略的三个坑第一个坑时间戳没对齐就做关联。多传感器融合时雷达帧和相机帧的时间戳如果差了几十毫秒目标运动又比较快算出来的马氏距离整体都会偏大门控直接漏掉真实量测。做关联之前先做时间同步和运动补偿这一步省不得。第二个坑门控阈值只调大小不回头修协方差。很多人发现漏关联第一反应是把门控阈值调大。但阈值变大后引入的是源源不断的假候选关联概率、分配结果都会被污染。正确的排查顺序是先看 NIS 是否服从理论分布确认滤波协方差匹配再调门控阈值。第三个坑硬决策算法里忘了处理“未匹配”结果。匈牙利算法输出的结果必须把未匹配的航迹和量测分开处理。未匹配的航迹要判断是否保持外推、延迟删除未匹配的量测要判断是新目标起始还是虚警。很多跟踪器“跟丢目标”不是因为关联算法不行而是新目标起始条件太苛刻或者航迹删除太慢导致状态陈旧。6.3 选型决策树与一个实测案例简单总结我的选型逻辑目标是单个但杂波强PDA。目标不多10、杂波中等且需要概率平滑JPDA 或近似 JPDA。目标多、密度高、允许离线微调MHT。目标多、硬件算力有限且检测质量好匈牙利 门控 好的代价模型。做 SLAM 特征关联/回环验证JCBB 或几何验证组合拳。计算资源充沛、样本充足可学习关联下一节。举一个实测案例我之前做园区内无人车的激光雷达目标跟踪需要同时跟踪行人和车辆目标数最多时有30多个。一开始参考论文用 JPDA直接把目标状态算崩了联合事件爆炸到帧率掉到个位数后来把场景拆成“靠近自车、杂波少”和“远距离、降采样严重”两部分前者用匈牙利 马氏距离后者用简化的 PDA 维持航迹不灭才最终达到实时且稳定的效果。这说明工程里算法不是越复杂越好而是越适配越好。6.4 可视化调参是我最推荐的手段如果你问我调试关联问题最有效的手段是什么我一定说把代价矩阵画出来看。把每一帧的代价矩阵渲染成热力图行列是航迹和量测颜色代表代价高低你会非常直观地看到门控有没有生效、哪些候选对在竞争、阈值设得是否合理。二维热力图比任何日志都直观。很多肉眼很难从数字里发现的系统性偏置在图上一眼就能看出来。7. 深度学习时代的数据关联可学习代价与经典分配的组合7.1 深度学习到底改变了什么很多人觉得深度学习会彻底取代传统数据关联算法但以我的观察来看它首先取代的只是“代价计算”这一环节而不是“分配决策”本身。传统方法里代价矩阵要么来自马氏距离要么来自手工特征相似度都需要专家调运动模型、噪声参数深度学习则可以直接学习一个代价模型让网络从数据里自动提炼“什么才算匹配”。Deep SORT 就是一个典型它没有改匈牙利和卡尔曼滤波只是把代价从纯马氏距离换成了“马氏距离 CNN外观特征余弦距离”的加权组合。外观特征一加入目标遮挡几帧后重新出现ID Switch 的概率大幅下降。这其实就是用深度特征替换了手工特征。7.2 图神经网络、端到端跟踪与一个反直觉的发现再进一步研究者开始把数据关联建模成图上的边权预测问题。把每一帧的检测框当作节点候选关联当作边用图神经网络GNN在图上做消息传递节点之间互相交换信息最终输出每条边的匹配概率然后再用匈牙利算法做全局最优匹配。这类方法比如 MPN Tracker在复杂的遮挡场景下比纯几何代价强不少。还有一条路线是尝试彻底绕开显式关联比如 CenterTrack 从检测中心点热力图出发通过预测目标中心在两帧之间的偏移量来做贪心最近邻关联把关联问题简化成“同一点如何移动”。更激进的 DETR 系列则通过集合预测直接输出目标轨迹不再显式构造代价矩阵。但有意思的是DETR 在训练时计算损失函数仍然需要求解集合元素之间的最优二分匹配用的还是匈牙利算法。研究了一大圈最后发现深度学习内部依然嵌套着经典分配。这个反直觉的发现也说明数据关联作为底层结构比很多人想象的要更基础。7.3 我对学习式关联的工程建议如果要做落地方案我不会一上来就上端到端跟踪网络。我会优先考虑“可学习代价 经典分配”的中间路线用 Re-ID 网络或者一个小型 GNN 生成检测框之间的相似度之后用门控过滤掉离谱候选再交给匈牙利或 MHT 框架做分配。原因有三个可解释性关联错了可以检查是代价模型的问题还是分配逻辑的问题。稳定性纯端到端网络在训练分布之外的表现很难预测经典约束能兜底。调试效率单独训练 Re-ID 特征比训练整个跟踪系统要快得多训练数据也更易构造。当然如果有大算力和丰富的场景数据端到端方法的上限确实更高。但工程和实验是两回事稳定可控才是上线系统的第一需求。8. 持续维护这份总结后面还会更新什么数据关联这个方向这些年变化非常快我写这篇总结时也在同步整理新的笔记。后面计划补充的内容包括分布式传感器网络中航迹-航迹关联Track-to-Track Fusion的具体做法尤其是多雷达系统里公共误差源带来的关联偏置问题还有基于 GOSPA 损失直接优化关联和状态的端到端跟踪方法——这类方法重新定义了“跟踪效果好”本身的标准很有意思。如果你在实际项目里用某个算法遇到了奇怪的关联问题比如目标号频繁跳变、航迹在交叉点交换、SPA 地图回环错检欢迎多交流。算法是死的场景是活的很多时候一个参数调整就能救回来但前提是你真的理解正在用的算法在做什么以及它在哪个环节上会产生误判。
返回列表