# 单目3D测距周期性波动问题分析与解决方案

## 1. 文档目标

本文档聚焦当前双 ROI 单目 3D 检测部署方案中出现的“目标测距周期性波动”问题，结合现有实现分析可能成因，并给出可落地的改进方案与推荐推进顺序。

本文档不替代 `tools/model_inference/docs/two_roi_model_design.md`。凡涉及当前部署链路的事实性描述，仍以现有推理脚本及其依赖模块为准。

---

## 2. 问题描述

当前模型在部分场景下会出现如下现象：

- 同一目标在连续帧中的测距结果呈现周期性起伏
- 目标实际距离变化不大，但 `z3d` 或 `center_3d.z` 存在明显波动
- 波动往往与车辆颠簸、路面不平、减速带、桥头跳车等场景同步出现

初步分析表明，该问题很可能与自车俯仰姿态变化有关。当自车颠簸时，目标在图像中的垂直位置会发生上下起伏，而当前单帧单目 3D 模型会将这类图像变化部分解释为距离变化。

---

## 3. 与当前实现的关系

### 3.1 当前实现中的关键链路

结合现有设计与代码实现，测距波动问题存在以下可能传播链路：

1. 当前灭点计算依赖静态标定中的 `pitch`

```text
vp_y = cv - focal_v * tan(pitch)
```

2. 当前 `camera4.json` 在 case 开始时加载一次，后续帧默认复用同一份标定，不会按帧更新 `pitch / roll`。

3. 当前 ROI 裁剪在 `y` 方向上直接依赖 `vp_y`，也就是依赖静态俯仰角计算出的灭点位置。

4. ROI 裁剪和 resize 后，会重新计算 `fx / fy / cx / cy`，后续 3D 回投和深度恢复仍继续使用这套 ROI 坐标系下的标定。

5. 当真实车身姿态随时间变化、但运行时仍使用静态姿态来解释图像时，目标的上下漂移会被系统误解释为深度变化，最终表现为 `z3d` 周期性波动。

### 3.2 问题本质

问题本质可以概括为：

- 当前实现默认相机姿态在时序上稳定
- 实际车辆在颠簸场景下存在动态 `pitch / roll`
- 单帧视觉观测中，目标垂直位移与真实深度变化发生耦合

因此，该问题既是“相机姿态建模不足”的问题，也是“单帧深度估计对图像上下扰动敏感”的问题。

---

## 4. 解决方案分层

从工程与算法角度，可以将方案分为五层：逐帧姿态补偿、时序平滑、ROI 抗扰动、训练增强、几何一致性融合。

### 4.1 逐帧姿态补偿

这是最接近根因修复的方案。

核心思路：

- 获取逐帧 `pitch / roll`
- 按帧更新灭点位置、ROI 裁剪中心和相机姿态
- 必要时在进入模型前先完成图像稳定，再执行 ROI 裁剪与推理

可选实现路径：

- 接入 `IMU / CAN` 的实时姿态信号
- 无额外传感器时，基于地平线、车道线、路面结构、稳定背景点估计视觉姿态

建议改造点：

- 将静态 `camera4.json` 扩展为逐帧动态姿态输入
- 按帧更新 `vp_y`
- 按帧更新 ROI 的 `crop_center_y`
- 若结果需要映射到 ego 坐标系，则同步更新相机到 ego 的姿态变换

优点：

- 直接处理误差源头
- 同时改善 ROI 对位与 3D 回投

缺点：

- 依赖新增姿态源或新增视觉姿态估计模块
- 集成复杂度最高

### 4.2 Track 级时序平滑

这是最适合快速落地的工程方案。

核心思路：

- 不直接使用单帧 `z3d` 作为最终结果
- 先对目标建立 track
- 再对同一目标的连续帧 3D 结果做时序滤波

推荐方式：

- 基于 2D/3D 关联建立 tracking
- 对 `center_3d.z`、`center_3d.x`、`yaw` 等量做 `EMA`、`Kalman Filter` 或固定窗平滑
- 根据类别、置信度、框尺寸、edge 几何一致性等动态调整测量噪声

优点：

- 不需要修改训练
- 工程改造范围小
- 对周期性抖动通常能快速见效

缺点：

- 只能抑制表现，不能消除根因
- 会引入一定延迟

### 4.3 降低 ROI 对上下抖动的敏感性

当前 ROI 在 `y` 方向上缺少独立的稳定策略，因此可以先做轻量改造。

可选方案：

- 引入独立的 `crop_center_y_mode`
- 支持 `fixed_cy`
- 支持 `smoothed_vpy`
- 支持 `blend(cv, vp_y)` 形式的加权中心
- 对 `crop_center_y` 做低通滤波或逐帧最大步长限制
- 适当增大 ROI 高度，降低轻微颠簸引入的相对位置扰动

优点：

- 代码改动较小
- 便于快速验证问题是否主要由 ROI 跟随静态灭点触发

缺点：

- 只能缓解，不能完整表达真实动态姿态

### 4.4 训练侧抗颠簸增强

若该问题在量产场景中普遍存在，建议在训练侧显式纳入姿态扰动域。

建议方向：

- 增加 `pitch / roll` 扰动增强
- 增加垂直平移、轻微透视变化、动态模糊等增强
- 对连续帧加入时序一致性约束
- 条件允许时，将姿态信息、地平线位置或多帧特征作为额外输入

进一步方案：

- 训练轻量多帧模型
- 引入显式姿态辅助分支
- 增加地平线或路面几何中间量预测

优点：

- 可以从模型层面提升鲁棒性

缺点：

- 需要重新训练和完整回归验证

### 4.5 几何一致性融合

对于车辆类目标，可将网络输出与几何约束融合，以降低单一回归分支对上下抖动的敏感性。

可利用信息包括：

- ground plane 或接地点约束
- 目标底边缘与 edge 分支几何
- 类别尺寸先验
- 连续帧运动学先验

可选策略：

- 当 `z3d` 与 edge / ground 几何明显冲突时，对该帧深度降权
- 将网络回归深度与几何估计深度做加权融合
- 将异常跳变作为诊断信号输出

优点：

- 提高异常帧下的可解释性
- 有助于构建更稳健的诊断链路

缺点：

- 依赖额外几何假设，适用范围需要单独验证

---

## 5. 推荐推进顺序

若目标是“先快速抑制线上波动，再逐步修复根因”，建议按以下顺序推进：

1. 先增加 `track` 级时序平滑，快速压制测距抖动
2. 同时引入 ROI `y` 向稳定策略，验证 ROI 机制的敏感性
3. 若验证表明问题与车身俯仰强相关，再接入逐帧 `pitch / roll` 补偿
4. 在训练侧加入抗颠簸增强，降低模型对垂直扰动的敏感性
5. 视业务需要补充 edge / ground / 运动学等几何一致性融合

该顺序兼顾了：

- 短期可落地性
- 中期定位能力
- 长期根因修复效果

---

## 6. 推荐实施策略

从工程收益比看，建议优先采用“两阶段策略”。

### 6.1 第一阶段：快速止血

目标：

- 尽快降低线上测距周期波动
- 快速判断问题是否主要与姿态扰动相关

建议动作：

- 增加 track 级滤波
- 为 ROI 增加 `y` 向平滑或固定策略
- 输出更多诊断字段，例如平滑前后深度、ROI 中心变化量、疑似姿态扰动标记

### 6.2 第二阶段：根因修复

目标：

- 将静态姿态假设升级为动态姿态建模

建议动作：

- 接入逐帧姿态输入
- 按帧更新灭点、裁剪、回投与 ego 变换
- 联合训练增强与几何融合进一步提升鲁棒性

---

## 7. 验证建议

为了判断方案是否有效，建议重点关注以下指标：

- 同一目标连续帧 `center_3d.z` 的标准差
- 目标静稳跟车场景下的深度峰峰值
- 颠簸场景中深度频谱的主频能量
- 引入平滑后的延迟和响应速度
- ego 坐标系下 `xyzlhwyaw` 的稳定性

建议单独构建以下评测子集：

- 路面平稳场景
- 明显颠簸场景
- 远距离车辆场景
- 近距离跟车场景
- 高速桥头或减速带场景

---

## 8. 结论

当前测距周期性波动问题，很大概率与“真实动态俯仰变化”和“运行时静态姿态假设”之间的不一致有关。

从方案优先级上看：

- 短期最有效的是 `track` 级时序平滑与 ROI `y` 向稳定
- 中长期最关键的是逐帧姿态补偿
- 若要进一步提升模型鲁棒性，应结合训练增强与几何一致性融合

其中，逐帧姿态补偿是最接近根因修复的方案；其余方案更适合作为快速缓解、问题定位和整体稳健性增强手段。
