Files

165 lines
5.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# yolo + stable track 说明
这套逻辑的目标不是直接相信 ByteTrack 的 `raw id`,而是维护一个更稳定的 `stable id`。
## 1. 基本概念
- `raw id`
ByteTrack 当前帧给出的轨迹号,只表示短时 2D 跟踪结果,可能抖动、复用、换人。
- `stable id`
本节点自己维护的长期身份号,用于:
- `/target_observation`
- `/track_observations`
- RViz marker
- ReID gallery
- `primary target`
当前跟随目标。它只是某一个 `stable id`,不是单独一套编号。
## 2. 当前关联逻辑
每一帧大致按下面顺序运行:
1. `YOLO pose`
2. `ByteTrack`
3. `raw-id fast path`
- 如果某个 row 的 `raw id` 能续上上一帧同一个 `stable id`,先临时绑定
- 注意:这一步现在只是“初始猜测”,不是最终判决
4. `ReID`
- 对还没绑定的 row,和所有已有 `stable id` 的 gallery 做相似度比较
- 若满足 `match_threshold` 且领先第二名至少 `gap_threshold`,直接回绑旧 `stable id`
5. `single-person 3D fallback`
- 只在单人场景下启用
- 只服务当前 `primary target`
- 用于 ReID crop 不可用时的兜底恢复
6. `new stable id allocate`
- 如果和所有旧 `stable id` 都无法匹配
- 且同一个 ByteTrack `raw id` 连续出现满 `target_reid_confirm_hits_before_allocate`
- 才会申请一个新的 `stable id`
## 3. stable id 的原则
- `stable id` 是长期身份,不是当前画面里的顺位号
- 某个目标暂时丢失时,它原来的 `stable id` 会继续保留,直到 timeout age out
- 不能因为画面里少了一个人,就把别人的 `stable id` 顶上去
这也是为什么:
- `raw id` 可以变
- 但 `stable id` 应该尽量不变
## 4. gallery 更新原则
`gallery` 现在不会随意更新。
### 4.1 什么时候能进 gallery
只有在下列情况之一时,当前 feature 才允许写进对应 `stable id`:
- 该 row 通过 ReID 成功回绑到旧 `stable id`
- 该 row 已经拿到正式 `stable id`,并且到了定期 refresh 时机
- 该 row 是经过连续确认后刚申请到的新 `stable id`
### 4.2 什么时候不允许更新
如果一个 row 是通过 `raw-id fast path` 临时续上的,但 ReID 明显反对这个绑定,则:
- 该帧不会更新这个 `stable id` 的 gallery
- 必要时会直接撤销 fast-path 绑定,让后续 ReID 重新决定该 row 属于哪个旧 `stable id`
这样做是为了避免:
- ByteTrack 一次短时漂移
- 把错人的 feature 写进旧 `stable id`
- 进而污染整个 gallery
### 4.3 fallback dist 会不会更新 gallery
不会。
`fallback dist` 只负责在单人场景下帮 `primary target` 暂时保住 `stable id`,不负责更新外观库。
## 5. 默认关键参数
这些参数都在:
- [control_command.yaml](./config/control_command.yaml)
当前常用参数:
- `target_reid_gallery_size: 8`
每个 `stable id` 最多缓存 8 个 ReID feature
- `target_reid_feature_update_interval: 5`
最多每 5 帧尝试刷新一次 gallery
- `target_reid_match_threshold: 0.65`
- `target_reid_gap_threshold: 0.10`
- `target_reid_lost_timeout_frames: 150`
- `target_reid_confirm_hits_before_allocate: 5`
新人申请新 `stable id` 前,要求同一个 ByteTrack `raw id` 连续确认 5 帧
- `target_reid_3d_fallback_enabled: 1`
单人场景启用 3D fallback
## 6. debug topic
假设 `sync_topic_prefix=/odin/sync`,则当前会有这些调试输出:
- `/odin/sync/detection_img_debug/compressed`
调试图。未分配 `stable id` 的 detection 画白色;已分配 `stable id` 的 detection 画对应彩色。
- `/odin/sync/gallery_debug`
原始 `sensor_msgs/Image`,不是 compressed。
用于看 ReID gallery 当前缓存了哪些人像 crop。
当前布局是:
- 最多 8 行,对应 8 个 `stable id`
- 10 列,对应 gallery 槽位
此外还有:
- `/odin/sync/target_observation`
当前 primary target
- `/odin/sync/track_observations`
当前帧所有 fresh 3D 的 stable tracks
- `/odin/sync/detection_pos_cam`
- `/odin/sync/detection_pos_world`
## 7. debug_reid
开启:
- `debug_reid: 1`
后,会打印每一帧的 ReID 相似度矩阵,格式类似:
```text
[ReIDMatrix] prev_sid=1 bytetrack_id=[2,1] stable_id=[1,0] sims=[1->[sid0:0.905,sid1:0.508],2->[sid1:0.938,sid0:0.489]]
```
解释:
- `prev_sid`
上一时刻的 primary stable id
- `bytetrack_id=[...]`
当前帧 ByteTrack row 的 raw ids
- `stable_id=[...]`
当前系统最终给每个 row 绑定到的 stable ids
- `sims=[...]`
每个 ByteTrack row 和所有已有 `stable id` gallery 的相似度
这个日志主要用来排查:
- 为什么某个 row 没能回绑到旧 `stable id`
- 是 ByteTrack 漂了,还是 gallery 被污染了
- 当前绑定结果和 ReID 结果是否一致
## 8. 当前已知设计取向
这版实现明确偏向下面的目标:
- `stable id` 尽量稳定
- 允许 ByteTrack 暂时失败
- 不允许一次错误 fast-path 直接污染 gallery
- 在多人场景下,优先相信 ReID,不用 3D fallback 去硬改多人 stable id
如果后面还要继续调,最值得重点观察的是:
- `debug_reid` 的矩阵输出
- `/odin/sync/gallery_debug`
- 某个 `stable id` 的 gallery 是否被混入了别人的 crop