# 跟踪算法sort

# 1.引言

在实现对画面当中的目标进行检测后，紧接着就会考虑到场景当中的这几个问题，我检测的目标会往哪个方向走，我检测的目标出现的时间和消失的时间，这就会引入另一个算法：跟踪算法，目前主流的几个跟踪算法方向如下：使用传统跟踪算法（SORT，DeepSORT），传统深度学习的跟踪算法（LSTM），大模型框架下的跟踪算法（MOTR，MOTR2）等。

# 算法逻辑

SORT的核心主要是有两个：使用卡尔曼滤波用于目标运动的预测和更新，使用匈牙利算法处理数据匹配的问题。

我们使用YOLO可以拿到比较稳定的输出目标框

输入的格式：

```plaintext
BBOX = [x, y, w, h, score, class]
```

输出格式：携带着稳定ID的跟踪结果

```plaintext
T_BBOX = [track_id, x, y, w, h, score, class]
```

算法的核心思想：

* 运动先验：每条轨迹都有KF，先预测当前帧的位置与尺度（得到预测框）。
    
* 空间一致：用预测框 vs 检测框的IOU构造代价矩阵。
    
* 全局分配：使用匈牙利算法在所有轨迹与检测框做全局最优匹配。
    
* 生存管理：新建/确认/保活/删除，抑制噪声与短时漏检。
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1766544890905/f0b469bb-921b-4d7e-b641-41cc091381aa.png align="center")

# 3.轨迹状态与卡尔曼滤波

## 3.1状态与量测

状态向量

$$x=[C_x,C_y,s,r,C_x',C_y',s']$$

* Cx, Cy：框中心；s：面积；r：宽高比w/h
    
* 点表示速度项（常速度模型）
    

量测向量

$$z=[C_x,C_y,s,r]^T$$

## **3.2 预测与更新**

* Predict：用状态转移矩阵 F 将 𝑥𝑡−1→𝑥𝑡∣𝑡−1，并得到预测协方差 𝑃𝑡∣𝑡−1
    
* Update：若和某检测匹配，用量测 𝑧𝑡 做卡尔曼更新，得到 𝑥𝑡∣𝑡、𝑃𝑡∣𝑡；未匹配则仅保留预测（不确定性增加）
    

# 4.数据关联

## 4.1代价矩阵（Cost）

对每个“预测轨迹框” 𝑇𝑖pred与“当前检测框” 𝐷𝑗

$$C = 1-IOU$$

* 若 IoU𝑖𝑗&lt;iou\_threshold（如 0.3），将该对视为不可匹配（代价置大数或直接屏蔽）。
    

## **4.2 匈牙利匹配（线性分配）**

在代价矩阵 C 上做全局最小化，得到三类集合：

* **matches**：配对成功的（轨迹 i ↔ 检测 j）
    
* **unmatched\_tracks**：本帧未匹配到检测的轨迹
    
* **unmatched\_dets**：本帧未被任何轨迹消费的检测
    

# 5.生命周期管理：新建-确认-保活-删除

* **新建（spawn）**：对每个未匹配检测，初始化一条新轨迹（KF 状态由检测框转换）。
    

* **确认（confirm）**：为避免噪声检测，轨迹需连续命中 ≥ min\_hits（如 3）才标记为 confirmed 并对外输出。出。
    

* **保活（ageing）**：未匹配轨迹仅预测，time\_since\_update += 1；在 ≤ max\_age（如 30 帧）期间允许“隐身”，便于遮挡后“接回”。
    

* **删除（prune）**：time\_since\_update &gt; max\_age 的轨迹被移除。
    

# 6.完整工作流程

* **检测**：从检测器取本帧框，按 类别/ROI 过滤。
    
* **预测**：对所有存活轨迹执行 KF Predict，得到预测框。
    
* **造价**：计算 预测框 vs 检测框 的 IoU，构造代价矩阵；IoU 低于阈值的对剔除。
    
* **匹配**：匈牙利算法求全局最优分配，得到匹配/未匹配集合。
    
* **更新**：匹配上的轨迹执行 KF Update；未匹配轨迹仅预测并记一次未命中。
    
* **新建**：对未匹配检测生成新轨迹。
    
* **清理**：删除超龄轨迹；达到 min\_hits 的轨迹由 tentative→confirmed
    
* **输出**：仅输出 confirmed 轨迹作为跟踪结果（用于计数/统计/上游预测）。
    

# 7.参考实现

```python
tracks   = []     # 轨迹对象：KF、id、age、hits、time_since_update、status 等
next_id  = 1
iou_thr  = 0.3
min_hits = 3
max_age  = 30

for frame in video_stream:
    dets = detector(frame)                       # [[x1,y1,x2,y2,score,cls], ...]
    dets = filter_by_roi_and_class(dets)

    # 1) KF 预测
    for t in tracks:
        t.kf.predict()
        t.pred_box = state_to_box(t.kf.x)

    # 2) IoU 代价矩阵（IoU < iou_thr 的对置为大数或剔除）
    C = build_cost_matrix(tracks, dets, iou_thr=iou_thr)

    # 3) 匈牙利匹配
    matches, u_trks, u_dets = hungarian_assign(C)

    # 4) 更新匹配到的轨迹
    for i, j in matches:
        z = box_to_meas(dets[j])                 # z = [cx,cy,s,r]
        tracks[i].kf.update(z)
        tracks[i].time_since_update = 0
        tracks[i].hits += 1
        tracks[i].age  += 1
        tracks[i].status = 'confirmed' if tracks[i].hits >= min_hits else 'tentative'

    # 5) 未匹配轨迹仅预测（已在 step 1 完成）
    for i in u_trks:
        tracks[i].time_since_update += 1
        tracks[i].age += 1

    # 6) 为未匹配检测新建轨迹
    for j in u_dets:
        t = new_track_from_det(dets[j], next_id) # 初始化 KF、id、计数器等
        tracks.append(t)
        next_id += 1

    # 7) 删除超龄
    tracks = [t for t in tracks if t.time_since_update <= max_age]

    # 8) 输出仅 confirmed 的轨迹
    outputs = [(t.id, state_to_box(t.kf.x)) for t in tracks if t.status == 'confirmed']
    yield outputs
```

# 8.参数选择与工程实践

* iou\_threshold（默认 ~0.3）：低了易误配，高了易漏配；小目标/抖动大可稍降（0.2–0.3）。
    
* min\_hits（2–4）：越大越能抑制假框，但轨迹“生效”更慢。
    

* max\_age（与 FPS 相关）：30 FPS 场景可先取 30（≈1s 隐身）；低 FPS/遮挡重可取 45–60。
    
* 按类分轨：car/bus/truck/person 分别跑一套 SORT，避免跨类错配。
    

* 计数/统计：仅对 confirmed 轨迹计数；跨线后对 同 track\_id 做短 TTL 去重，防止抖动重复计数。
    
* 低 FPS/快速运动：适当调大 KF 的 过程噪声 Q 或 max\_age，容忍更大的位移与预测误差。
    

* 可视化与日志：保存每帧的匹配关系、未匹配集合、IoU 分布，利于调参与复现。
    

# 9.常见问题和增强路线

**近距离交汇/遮挡 → ID 互换**

* 原因：SORT 只用 IoU，不看外观。
    

**解决（从轻到重）**：

* 运动门控（马氏距离 χ²）：将运动不合理的候选对直接剔除。
    
* DeepSORT：加入 ReID 外观特征 与 级联匹配（强烈改善 ID 稳定）
    
* OC-SORT：用光流/几何一致性改进时间关联（无外观也稳）。
    
* BoT-SORT / StrongSORT：更强的外观建模与相机补偿。
    
* ByteTrack：高/低置信两阶段关联，拥挤场景召回更高。
    
* 移动相机（行车记录仪）：考虑 相机运动补偿（CMC） 或选 OC-SORT/BoT-SORT。
    
* 多传感器融合：有毫米波/激光雷达时，把 距离/速度 加入门控或代价项，串号率会显著下降。
