多目标跟踪
多目标跟踪(Multi-Object Tracking, MOT)是计算机视觉中的核心任务:给定一段连续视频,既要检测每一帧中的所有物体,还要在不同帧之间将同一个物体关联起来,为每个物体分配一个唯一且稳定的身份标识(ID)。它是自动驾驶、智能监控、运动分析等应用的基础。前置阅读:目标检测与 YOLO、光流。
目标检测(如 YOLO)回答”每一帧里有什么、在哪里”,但它把每一帧当作独立的图片——第 1 帧检测到的”3 号行人”和第 2 帧检测到的”5 号行人”在检测器眼里毫无关联。多目标跟踪要在此基础上回答一个额外问题:“第 1 帧的这个人,在第 2 帧跑到哪里去了?”
为什么需要跟踪? 检测只能给出”某一瞬间的快照”,而真实世界是连续的。自动驾驶需要知道”前面那辆车正在加速还是减速”,安防需要知道”同一个人在画面里停留了多久”,体育分析需要知道”球员的跑动轨迹是什么”——这些都需要跨帧的身份一致性。
三种范式的直觉:
- 检测优先(Detection-Based, 又称 Tracking-by-Detection):先逐帧检测所有物体,然后在帧间做关联。绝大多数主流方法(SORT、DeepSORT、ByteTrack)属于此类。优点是检测和跟踪解耦,可以随时升级检测器。
- 检测与跟踪联合(Joint Detection-Tracking):一个网络同时完成检测和特征嵌入(ReID),端到端训练。代表方法有 FairMOT、JDE。优点是推理快,缺点是检测和 ReID 的目标可能互相冲突。
- 无需检测的跟踪(Detection-Free Tracking):第一帧手动或自动初始化目标位置,之后持续跟踪。典型方法如光流法、相关滤波跟踪、以及 2023 年 Meta 提出的 CoTracker。适合”只关心特定物体”的场景。
MOT 的核心挑战
Section titled “MOT 的核心挑战”| 挑战 | 描述 | 典型场景 |
|---|---|---|
| 遮挡(Occlusion) | 物体被其他物体或场景遮挡,短暂消失后重新出现 | 行人被柱子挡住、车辆被大车遮挡 |
| ID 切换(ID Switch) | 两个物体交叉经过后,跟踪器混淆了它们的身份 | 两个行人擦肩而过 |
| 密集场景 | 同一画面中大量物体紧挨,检测框重叠严重 | 拥挤的十字路口、商场的行人 |
| 外观变化 | 物体外观因光照、视角、形变而改变 | 白天到傍晚、正脸到侧脸 |
| 新目标进入 / 旧目标离开 | 管理轨迹的创建和销毁 | 行人走入/走出画面 |
跟踪框架总览
Section titled “跟踪框架总览”一句话总结 Tracking-by-Detection 框架:检测器给出当前帧”有哪些物体” → 用卡尔曼滤波预测已有轨迹”下一帧应该在哪里” → 用匈牙利匹配把检测结果和预测结果一一配对 → 更新轨迹状态。接下来逐一拆解每个模块。
卡尔曼滤波:轨迹状态预测
Section titled “卡尔曼滤波:轨迹状态预测”跟踪的核心难题之一:物体在两帧之间会移动,但检测器只在某一帧给出了位置。我们怎么预测物体”下一帧大概在哪里”?卡尔曼滤波(Kalman Filter) 是经典的解决方案——它假设物体的运动近似匀速,用上一帧的位置和速度来预测下一帧的位置,然后在检测到来时用检测结果修正预测。
卡尔曼滤波的直觉:想象你在追一个跑者,你只能每秒看到一次他的位置。在看不到他的那 0.99 秒里,你根据他上一秒的方向和速度猜测他在哪(预测步);当你再次看到他时,你发现猜偏了一点,于是把估计位置朝实际位置”拉”一点(更新步)。卡尔曼滤波就是在做这个”猜—修正”的循环,且用方差来量化”猜得有多不准”。
对于一个典型的 2D 边界框跟踪,状态向量包含中心坐标、宽高和它们的变化率(速度):
其中 是边界框中心, 是宽高, 表示对应量的速度。状态转移方程(预测步):
其中 是状态转移矩阵(编码”位置 += 速度 × Δt”的匀速运动假设), 是估计的协方差矩阵(衡量不确定性), 是过程噪声协方差。
当第 帧的检测结果 到来时,执行更新步:
其中 是观测矩阵(从状态空间映射到观测空间), 是观测噪声协方差, 是卡尔曼增益(Kalman Gain)——它决定了”更信任预测还是更信任检测”。
卡尔曼增益的物理意义:当 接近 (单位矩阵)时,表示检测很可靠,几乎完全采纳检测结果;当 接近 时,表示检测噪声太大,更信任预测值。增益的值由预测不确定性和观测噪声的相对大小自动决定——这就是卡尔曼滤波”自适应”的精髓。
数据关联:匈牙利匹配
Section titled “数据关联:匈牙利匹配”卡尔曼滤波给出了每条已有轨迹的”预测位置”,检测器给出了当前帧的”实际检测位置”。现在要把它们一一配对——这就是数据关联(Data Association) 问题。
首先构建一个代价矩阵(Cost Matrix) ,其中 表示将第 条轨迹与第 个检测配对的代价:
其中 是基于 IoU(Intersection over Union,交并比)的距离度量, 是基于外观特征的距离(DeepSORT 才有), 和 是权重。
SORT 纯用 IoU 距离:。然后用匈牙利算法(Hungarian Algorithm) 在代价矩阵上找到总代价最小的全局最优一一分配方案。
匈牙利算法(又称 Kuhn-Munkres 算法)解决的是二分图最优匹配问题:给定 条轨迹和 个检测,找到总代价最小的一一对应关系。时间复杂度为 或 (取决于实现)。只有代价低于某个阈值(Gate)的配对才会被接受——如果某条轨迹预测的位置和所有检测都对不上(代价都很高),说明物体可能被遮挡了,这条轨迹进入”暂时丢失”状态。
IoU 计算
Section titled “IoU 计算”IoU 是边界框相似度的标准度量:
其中 是两个框交集的面积, 是并集面积。IoU ∈ [0, 1],1 表示完全重合,0 表示完全不重叠。
为什么不用简单的中心点距离?因为两个框中心点可能很近但大小完全不同(比如一个大框和一个小框),IoU 同时考虑了位置和大小,更全面。
主要方法演进
Section titled “主要方法演进”SORT(2016):最简框架
Section titled “SORT(2016):最简框架”SORT(Simple Online and Realtime Tracking)由 Bewley 等人提出,是 Tracking-by-Detection 的极简方案:
- 检测:用任意检测器(Faster R-CNN / YOLO)逐帧检测
- 预测:每条轨迹用卡尔曼滤波预测下一帧位置
- 关联:仅用 IoU 构建代价矩阵 + 匈牙利匹配
- 管理:连续 帧未匹配的轨迹删除;新出现的检测初始化为”试探性轨迹”
优点:极快(260+ FPS,瓶颈在检测器),实现简单。
缺点:纯靠位置(IoU)关联,没有外观信息——当物体被遮挡后重新出现,或两个外观完全不同的物体运动轨迹交叉时,容易发生 ID 切换。
DeepSORT(2017):加入外观特征
Section titled “DeepSORT(2017):加入外观特征”DeepSORT(Deep Simple Online and Realtime Tracking)在 SORT 基础上引入了外观特征(Appearance Feature):
- 训练一个深度神经网络(在 ReID 数据集上预训练的 CNN)为每个检测框提取一个嵌入向量(Embedding)
- 代价矩阵融合运动距离和外观距离:
- 维护一个”最近 N 帧的外观特征库”,即使物体被短暂遮挡也能通过外观重新关联
ReID(Re-Identification,行人重识别):在不同摄像头、不同时间、不同视角下识别同一个人。ReID 模型学习将同一个人的不同图片映射到相近的向量空间位置,不同人的图片映射到远处。DeepSORT 用 ReID 特征来区分”谁是谁”——即使两个人位置交叉,外观特征不同就不会混淆。
DeepSORT 大幅降低了 ID 切换率,代价是需要额外运行 ReID 网络,速度有所下降。它是工业界最常用的 MOT 方案之一。
ByteTrack(2022):利用低分检测
Section titled “ByteTrack(2022):利用低分检测”ByteTrack(ECCV 2022)的关键洞察:高分检测(置信度 > 阈值)用来做可靠关联,低分检测(置信度低于阈值但不是噪声)不应该被丢弃——被遮挡的物体往往产生低分检测,这些低分检测恰好可以用来”桥接”遮挡前后的同一条轨迹。
ByteTrack 的两轮匹配策略:
- 第一轮:用高分检测与已有轨迹做匈牙利匹配(同样用卡尔曼滤波预测 + IoU 代价矩阵)
- 第二轮:第一轮未匹配的轨迹,再与低分检测做第二轮匹配——低分检测通常来自被遮挡物体的部分可见区域
- 第一轮未匹配的高分检测 → 初始化为新轨迹
优势:无需额外的 ReID 网络(速度快),但通过充分利用低分检测,显著减少了遮挡导致的轨迹断裂和 ID 切换。在 MOT17/20 基准上达到 SOTA,速度接近 SORT。
CoTracker(2023):点级跟踪的革新
Section titled “CoTracker(2023):点级跟踪的革新”CoTracker(由 Meta AI 在 2023 年提出)采取了完全不同的思路——它不跟踪边界框,而是跟踪点:
- 在视频的第一帧(或任意帧)选择一组点(可以是物体上的任意点,不限于边界框)
- 网络端到端预测这些点在整个视频中的位置——每个点始终指向”同一个物理位置”
- 基于 Transformer 架构,同时建模多个点的时空关系,能在遮挡期间”记住”点的位置并在重新可见时恢复跟踪
CoTracker 与传统 MOT 的区别:传统 MOT 跟踪”物体”(用边界框表示),输出”谁在哪一帧的什么位置”;CoTracker 跟踪”点”(像素级),输出”这个像素在所有帧中的对应位置”。CoTracker 更适合运动分析、3D 重建、视频编辑等需要密集或半密集对应关系的任务。
CoTracker 在 2024 年推出了 CoTracker3,用更少的训练数据实现了更好的半监督学习效果,降低了点跟踪模型的训练门槛。
其他重要方法
Section titled “其他重要方法”| 方法 | 年份 | 关键创新 |
|---|---|---|
| FairMOT | 2021 | 单网络同时做检测和 ReID,精心平衡两个任务的损失权重 |
| JDE(Joint Detection and Embedding) | 2020 | 将检测和 ReID 嵌入合并到一个网络中,共享 backbone |
| MOTR / MOTRv2 | 2022 | 将 Transformer 的 DETR 范式扩展到跟踪,用轨迹查询(Track Query)跨帧传递信息 |
| OC-SORT | 2023 | 观察中心化 SORT,修复卡尔曼滤波在非线性运动下的失效问题 |
| StrongSORT | 2023 | DeepSORT 的增强版,加入 ECC(Enhanced Correlation Coefficient)相机运动补偿和 BoT(Bag of Tricks) |
MOT 任务的评估比单纯的检测复杂得多——不仅要看检测准不准,还要看 ID 维持得好不好:
| 指标 | 全称 | 说明 |
|---|---|---|
| MOTA | Multi-Object Tracking Accuracy | 综合考虑漏检(FN)、误检(FP)和 ID 切换(IDSW)。 |
| MOTP | Multi-Object Tracking Precision | 检测框与真实框的平均重叠度,衡量定位精度 |
| IDF1 | ID F1 Score | 以 ID 一致性为核心的 F1 分数——平衡 ID 假阳性(IDFP)和 ID 假阴性(IDFN) |
| HOTA | Higher Order Tracking Accuracy | 2020 年提出的新标准,将检测精度(DetA)和关联精度(AssA)解耦,比 MOTA 更全面 |
| IDs/IDSW | ID Switches | ID 切换次数——同一物体被分配了不同 ID 的次数,越少越好 |
| Frag | Fragmentation | 轨迹碎片化次数——同一物体的轨迹被打断成多段的次数 |
为什么需要 HOTA? MOTA 长期是 MOT 的标准指标,但它过度偏向检测质量(FN 和 FP 占主导),ID 切换(IDSW)的权重很低。这导致很多方法只在检测上下功夫就能刷高 MOTA,却忽视关联质量。HOTA 将检测和关联乘法解耦:,让两个维度都被公平评估。
SORT 简化实现(概念演示)
Section titled “SORT 简化实现(概念演示)”"""SORT 核心逻辑的简化演示。实际使用请安装: pip install sort"""import numpy as npfrom scipy.optimize import linear_sum_assignment
class KalmanBoxTracker: """简化的卡尔曼滤波跟踪器(仅演示状态预测和更新)""" def __init__(self, bbox): # 状态向量: [cx, cy, w, h, vx, vy, vw, vh] self.x = np.zeros(8) self.x[:4] = bbox # 初始位置 self.P = np.eye(8) * 10.0 # 初始不确定性 self.id = None self.time_since_update = 0 self.hits = 1
def predict(self): """预测步: 匀速运动模型""" # F 矩阵简化: 位置 += 速度 self.x[0] += self.x[4] self.x[1] += self.x[5] self.x[2] += self.x[6] self.x[3] += self.x[7] self.time_since_update += 1 return self.x[:4].copy()
def update(self, bbox): """更新步: 用新检测修正预测""" # 简化版: 直接融合(真实实现用卡尔曼增益加权) self.x[:4] = 0.7 * self.x[:4] + 0.3 * bbox self.time_since_update = 0 self.hits += 1
def iou_batch(boxes_pred, boxes_det): """计算预测框和检测框之间的 IoU 矩阵""" # boxes: [x1, y1, x2, y2] 或 [cx, cy, w, h] # 返回 IoU 矩阵 [N_pred, N_det] # (此处省略详细实现,思路是对每对框计算交集/并集) pass
def associate(trackers, detections, iou_threshold=0.3): """匈牙利匹配关联""" if len(trackers) == 0 or len(detections) == 0: return [], list(range(len(detections))), list(range(len(trackers)))
# 1. 构建 IoU 代价矩阵 (1 - IoU) iou_matrix = iou_batch( np.array([t.predict() for t in trackers]), np.array(detections) ) cost_matrix = 1 - iou_matrix
# 2. 匈牙利算法求最优分配 row_ind, col_ind = linear_sum_assignment(cost_matrix)
matches, unmatched_dets, unmatched_trks = [], [], [] for r, c in zip(row_ind, col_ind): if iou_matrix[r, c] < iou_threshold: unmatched_dets.append(c) unmatched_trks.append(r) else: matches.append((r, c))
unmatched_dets += [d for d in range(len(detections)) if d not in col_ind] unmatched_trks += [t for t in range(len(trackers)) if t not in row_ind] return matches, unmatched_dets, unmatched_trks
# === 主循环(概念) ===# trackers = [] # 已有轨迹列表# for frame_detections in video_frames:# # 1. 预测 + 关联# matches, unmatched_dets, unmatched_trks = associate(trackers, frame_detections)# # 2. 匹配的: 更新轨迹# for trk_idx, det_idx in matches:# trackers[trk_idx].update(frame_detections[det_idx])# # 3. 未匹配检测: 创建新轨迹# for det_idx in unmatched_dets:# trackers.append(KalmanBoxTracker(frame_detections[det_idx]))# # 4. 未匹配轨迹: 超时则删除# trackers = [t for t in trackers if t.time_since_update < 30]使用 ByteTrack(生产级)
Section titled “使用 ByteTrack(生产级)”"""ByteTrack 实际使用示例。安装: pip install bytetracker 或使用官方仓库检测器输出格式: [x1, y1, x2, y2, score, class]"""# from bytetracker import BYTETracker
# # 初始化跟踪器# tracker = BYTETracker(# track_thresh=0.5, # 高分阈值 τ_high# track_buffer=30, # 轨迹保留帧数# match_thresh=0.8, # 匹配 IoU 阈值# )
# # 逐帧处理# for frame in video:# detections = yolo_model.predict(frame) # [N, 6]# # ByteTrack 内部自动处理两轮匹配# online_targets = tracker.update(detections)# for t in online_targets:# tlbr = t.tlbr # [x1, y1, x2, y2]# tid = t.track_id# cv2.rectangle(frame, tlbr[:2], tlbr[2:], (0, 255, 0), 2)# cv2.putText(frame, str(tid), tlbr[:2],# cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)- 检测器是上限:Tracking-by-Detection 方法的跟踪质量严重依赖检测器的精度。漏检导致轨迹断裂,误检导致虚假轨迹。先确保检测器在你的场景上表现良好,再考虑跟踪策略。
- 场景适配:行人密集场景(如 MOT Challenge)适合 ByteTrack / DeepSORT;车辆跟踪(如自动驾驶)通常运动更规律,Kalman + IoU 就足够;点级跟踪需求(如运动分析)用 CoTracker。
- 相机运动补偿:如果相机本身在移动(车载、无人机),需要在关联前做相机运动补偿——用图像配准(如 ECC 算法)或特征点匹配估计相机运动,将其从轨迹运动中扣除。
- 低分检测的利用:ByteTrack 的核心教训——不要简单丢弃低分检测。被遮挡物体往往只产生低分检测,它们是维持轨迹连续性的关键线索。
- ReID 模型选择:DeepSORT 原始论文用了一个在行人 ReID 数据集上训练的小 CNN。如果你的跟踪目标不是行人(如车辆、动物),需要用对应域的 ReID 模型,否则外观特征区分度不够。
- 后处理:如果最终应用容忍少量延迟,可以做全局优化(Global Linking)——利用未来帧的信息修正过去的关联决策(如用网络流或动态规划),通常能显著降低 ID 切换。
最新进展(2024-2025)
Section titled “最新进展(2024-2025)”- Point Tracking 走向成熟:CoTracker3(2024)引入半监督训练策略,用少量真实标注 + 大量合成数据训练,大幅降低标注成本。PIPs、TAPIR 等点跟踪方法也在快速迭代。
- Transformer + MOT:MOTR 将 DETR 的”集合预测”思路扩展到跟踪,用可学习的”轨迹查询(Track Query)“自动发现和维护轨迹——虽然精度有竞争力,但训练复杂度高,实时性仍是挑战。2024-2025 年的工作(如 Track-Anything、DEVA)在分割和跟踪的统一框架上继续推进。
- SAM + MOT:Meta 的 Segment Anything Model(SAM)与 MOT 结合,推动了从”边界框跟踪”到”像素级掩码跟踪”的升级。SAMURAI(2024)将 SAM 改造为视频目标分割与跟踪方法。
- 3D MOT:自动驾驶场景推动了 3D 多目标跟踪(点云 + 图像融合),代表方法如 SimpleTrack、PC3T。3D MOT 面临的关联问题与 2D 类似,但状态空间扩展到三维。
- 评估基准演进:HOTA 指标在 2020 年提出后逐渐成为社区共识。MOTChallenge 持续更新数据集,MOT22 增加了密集拥挤场景,DanceTrack 专门测试非线性运动和均匀外观下的跟踪能力。
- 自动驾驶感知:实时跟踪周围车辆、行人、骑行者的轨迹,预测它们的运动意图——是路径规划和碰撞避免的关键输入。
- 智能安防:监控视频中的人员轨迹分析,检测异常行为(如徘徊、聚集、越线),辅助安防决策。
- 体育分析:跟踪球员和球的运动轨迹,生成热力图、跑动距离、速度分析——NBA、英超等联赛已大规模采用。
- 零售分析:跟踪顾客在店内的移动路径,分析热门区域和停留时间,优化商品陈列。
- 视频编辑与特效:自动跟踪视频中的物体,实现背景替换、物体移除、运动模糊添加等后期效果。
| 术语 | 英文 | 解释 |
|---|---|---|
| 多目标跟踪 | Multi-Object Tracking (MOT) | 在视频中同时跟踪多个物体并维持身份一致性 |
| 轨迹 | Track / Trajectory | 同一物体在多帧中的连续位置序列 |
| ID 切换 | ID Switch (IDSW) | 同一物体被分配了不同 ID 的错误 |
| 卡尔曼滤波 | Kalman Filter | 基于线性高斯假设的最优递归状态估计方法 |
| 匈牙利算法 | Hungarian Algorithm | 解决二分图最优一一匹配的多项式时间算法 |
| 交并比 | Intersection over Union (IoU) | 两个边界框重叠度指标 |
| 行人重识别 | Person Re-Identification (ReID) | 在不同视角/摄像头下识别同一人的技术 |
| 检测优先跟踪 | Tracking-by-Detection | 先逐帧检测再做帧间关联的跟踪范式 |
| HOTA | Higher Order Tracking Accuracy | 解耦检测精度和关联精度的 MOT 评估指标 |
| 点跟踪 | Point Tracking | 跟踪像素级点而非边界框的跟踪范式 |
| 遮挡 | Occlusion | 物体被其他物体或场景部分或完全挡住 |
| 试探性轨迹 | Tentative Track | 新创建但尚未被确认的轨迹,需连续匹配若干帧才转为正式轨迹 |
- SORT:Bewley et al. 2016 “Simple Online and Realtime Tracking”(ICIP 2016)——极简跟踪框架,MOT 入门必读。
- DeepSORT:Wojke et al. 2017 “Simple Online and Realtime Tracking with a Deep Association Metric”(ICIP 2017)——加入 ReID 外观特征,大幅降低 ID 切换。
- ByteTrack:Zhang et al. 2022 “ByteTrack: Multi-Object Tracking by Associating Every Detection Box”(ECCV 2022)——利用低分检测的两轮匹配策略。
- CoTracker:Doersch et al. 2023 “CoTracker: It is Better to Track Together”(Meta AI, arXiv 2307.07635)——基于 Transformer 的点跟踪。
- HOTA:Luiten et al. 2021 “HOTA: A Higher Order Metric for Evaluating Multi-Object Tracking”(IJCV)——MOT 评估指标的革新。
- 检测基础:目标检测与 YOLO 介绍了检测器的原理,是 MOT 的前置知识。
- Transformer 在视觉中的应用:Transformer 架构 是理解 MOTR 等 Transformer 跟踪方法的基础。