# 真值可视化工具集

## 📚 文档索引

本目录提供了完整的真值可视化工具和详细文档，帮助理解从数据加载到可视化的完整流程。

### 核心脚本

1. **[visualize_single_frame.py](visualize_single_frame.py)** - 单帧可视化脚本 ⭐
   - 读取单帧图像和标签
   - 支持2D、3D、BEV可视化
   - 支持ROI变换和深度归一化
   - 推荐用于详细分析单个样本

2. **[visualize_batch.py](visualize_batch.py)** - 批量可视化脚本
   - 批量处理多帧图像
   - 自动匹配图像和标签
   - 支持限制处理数量
   - 推荐用于快速浏览数据集

3. **[visualize_filtered_train.py](visualize_filtered_train.py)** - 条件过滤可视化脚本 🔥
   - 从训练集/验证集筛选特定条件的样本
   - 支持类别过滤（如：只看两轮车）
   - 支持3D空间范围过滤（如：左右10米、纵向50米）
   - 自动生成摘要文件
   - 推荐用于数据分析和质量检查

4. **[test_visualization.py](test_visualization.py)** - 快速测试脚本
   - 自动从验证集查找样本
   - 测试不同配置的可视化效果
   - 推荐用于首次使用或调试

### 文档说明

1. **[README.md](README.md)** - 总体说明 📖
   - 真值读取到可视化的完整流程概述
   - 标签格式说明（47维数组结构）
   - ROI变换和深度归一化原理
   - 不同类别的处理策略
   - 使用方法和参数说明

2. **[FLOW_ANALYSIS.md](FLOW_ANALYSIS.md)** - 详细流程分析 🔍
   - 数据加载流程（标签、图像、标定）
   - ROI变换的详细步骤
   - 深度归一化的数学原理
   - 2D/3D可视化的实现细节
   - 坐标系统和变换关系
   - 调试技巧和优化建议

3. **[EXAMPLES.md](EXAMPLES.md)** - 使用示例 💡
   - 基础使用示例（原始图像）
   - ROI模式示例（与训练一致）
   - 批量处理示例
   - 自动测试示例
   - 常见场景和故障排查
   - 参数速查表

4. **[FILTER_GUIDE.md](FILTER_GUIDE.md)** - 条件过滤指南 🎯
   - 条件过滤可视化的详细使用方法
   - 类别过滤和空间范围过滤
   - 多种使用场景（数据质量检查、类别分布分析等）
   - 参数详解和坐标系说明
   - 高级用法和性能优化
   - 常见问题和实用技巧

## 🚀 快速开始

### 方式1: 最简单（自动测试）

```bash
# 自动查找样本并可视化
python scripts_for_gt/test_visualization.py --data data/mono3d.yaml --output ./test_viz
```

### 方式2: 单帧可视化（原始图像）

```bash
# 基础使用：不使用ROI，直接可视化原始图像
python scripts_for_gt/visualize_single_frame.py \
    --image /path/to/image.jpg \
    --label /path/to/label.txt \
    --output ./viz_output
```

### 方式3: 单帧可视化（ROI模式，与训练一致）

```bash
# 使用ROI变换和深度归一化（与训练时一致）
python scripts_for_gt/visualize_single_frame.py \
    --image /path/to/image.jpg \
    --label /path/to/label.txt \
    --output ./viz_output_roi \
    --roi 704 352 \
    --virtual-fx 500 \
    --ori-img-size 1920 1080
```

### 方式4: 批量处理

```bash
# 批量可视化多帧
python scripts_for_gt/visualize_batch.py \
    --image-dir /path/to/images \
    --label-dir /path/to/labels \
    --output ./batch_viz \
    --roi 704 352 \
    --virtual-fx 500 \
    --max-samples 20
```

## 📊 输出结果

每个样本会生成4个可视化文件：

| 文件 | 内容 | 用途 |
|------|------|------|
| `*_2d_gt.jpg` | 2D边界框 | 查看目标检测标注 |
| `*_3d_gt.jpg` | 3D框投影 | 查看3D标注质量 |
| `*_bev_gt.jpg` | 鸟瞰图 | 查看空间位置关系 |
| `*_combined.jpg` | 组合视图 | 一眼看到所有信息 |

## 🔑 关键概念

### 标签格式（47维数组）

```
[0]:     class                    # 类别ID
[1-4]:   x, y, w, h              # 2D边界框（归一化）
[5]:     score                   # 置信度
[6-8]:   x3d, y3d, z3d          # 3D中心（相机坐标系）
[9-11]:  length, height, width   # 3D尺寸
[12]:    rot_y                   # 偏航角
[13-14]: center_u, center_v      # 3D中心投影（归一化）
[15]:    alpha                   # 观测角
[16-23]: front_face              # 前面信息
[24-31]: rear_face               # 后面信息
[32-39]: left_face               # 左面信息
[40-47]: right_face              # 右面信息
```

### ROI变换

1. 计算ROI区域（以消失点为中心）
2. 裁剪图像到ROI区域
3. 调整2D边界框和UV坐标到ROI空间
4. 根据`virtual_fx`缩放深度值

### 深度归一化

```python
# 训练时
z_normalized = z_original * (virtual_fx / fx_original)

# 可视化时（恢复）
z_original = z_normalized * depth_scale
# 其中 depth_scale = fx_original / virtual_fx
```

**为什么只缩放Z？**
- 投影公式: `u = fx * X/Z + cx`
- 同时缩放`fx`和`Z`可以保持投影不变
- `X`和`Y`从`UV`和`Z`恢复，无需单独缩放

### 不同类别的处理策略

| 类别 | 策略 | 原因 |
|------|------|------|
| 车辆(0, 13) | 基于最佳可见面 | 可能被部分遮挡 |
| 行人(1, 2, 3) | 基于完整3D框 | 尺寸小，完整框更准确 |

## 🔧 常见问题

### Q1: 为什么需要ROI变换？

**A**: ROI变换有两个目的：
1. **聚焦感兴趣区域**: 去除天空等无关区域
2. **统一焦距**: 通过`virtual_fx`统一不同相机的焦距，提高泛化能力

### Q2: 什么时候使用ROI模式？

**A**: 
- **查看原始数据**: 不使用ROI（了解数据本身）
- **与训练一致**: 使用ROI（验证训练数据处理）
- **调试模型**: 使用ROI（与模型输入一致）

### Q3: 标定文件必需吗？

**A**: 
- **2D可视化**: 不需要
- **3D可视化**: 需要（用于3D到2D的投影）

### Q4: 如何验证可视化是否正确？

**A**: 检查以下几点：
1. 2D框是否对齐目标
2. 3D框投影是否合理（不应该明显错位）
3. BEV中的位置是否符合直觉（距离、朝向）
4. 不同面的颜色是否正确（前红后绿）

## 📖 推荐阅读顺序

1. **新手**: README.md → EXAMPLES.md → 运行test_visualization.py
2. **数据分析**: FILTER_GUIDE.md → 运行visualize_filtered_train.py
3. **开发**: FLOW_ANALYSIS.md → 阅读脚本代码 → 自定义功能
4. **调试**: EXAMPLES.md故障排查 → FLOW_ANALYSIS.md调试技巧

## 🎯 常用命令速查

```bash
# 快速测试
python scripts_for_gt/test_visualization.py

# 原始图像可视化
python scripts_for_gt/visualize_single_frame.py --image img.jpg --label label.txt --output out

# ROI模式（与训练一致）
python scripts_for_gt/visualize_single_frame.py --image img.jpg --label label.txt \
    --roi 704 352 --virtual-fx 500 --output out

# 批量处理（前10个样本）
python scripts_for_gt/visualize_batch.py --image-dir imgs/ --label-dir labels/ \
    --output batch_out --max-samples 10

# 批量+ROI
python scripts_for_gt/visualize_batch.py --image-dir imgs/ --label-dir labels/ \
    --roi 704 352 --virtual-fx 500 --output batch_out

# 条件过滤：可视化包含两轮车的样本（左右10米、纵向50米范围）
python scripts_for_gt/visualize_filtered_train.py --data data/mono3d.yaml \
    --target-class bicycle --x-range -10 10 --z-range 0 50 --max-samples 20

# 条件过滤：可视化包含行人的样本
python scripts_for_gt/visualize_filtered_train.py --data data/mono3d.yaml \
    --target-class pedestrian --max-samples 50

# 条件过滤：从验证集筛选
python scripts_for_gt/visualize_filtered_train.py --data data/mono3d.yaml \
    --split val --target-class vehicle --z-range 10 30 --max-samples 20
```

## 📞 需要帮助？

1. 查看 [EXAMPLES.md](EXAMPLES.md) 的故障排查章节
2. 查看 [FLOW_ANALYSIS.md](FLOW_ANALYSIS.md) 的调试技巧章节
3. 检查标签文件格式是否正确
4. 检查标定文件是否存在且格式正确

## 🔄 与模型代码的对应关系

| 功能 | 脚本位置 | 模型代码位置 |
|------|---------|------------|
| 标签加载 | `load_label_file()` | `utils/dataloaders3d.py:load_label()` |
| ROI变换 | `apply_roi_transform()` | `utils/dataloaders3d.py:post_process_labels_to_roi()` |
| 深度归一化 | `scale_z3d()` | `utils/dataloaders3d.py:_scale_z3d()` |
| 3D解码（GT） | - | `utils/plots.py:decode_and_reconstruct_3d_box_from_target()` |
| 3D解码（预测） | - | `utils/plots.py:decode_and_reconstruct_3d_box()` |
| 2D可视化 | `plot_2d_boxes()` | `test_val_visualize.py:plot_2d_boxes_to_image()` |
| 3D可视化 | - | `utils/plots.py:plot_3d_boxes_from_decoded_targets()` |

## 📝 版本历史

- **v1.0** (2026-02-07): 初始版本
  - 单帧可视化脚本
  - 批量可视化脚本
  - 自动测试脚本
  - 完整文档（README, FLOW_ANALYSIS, EXAMPLES）

## 🎓 相关资源

- 主项目文档: [CLAUDE.md](../CLAUDE.md)
- 数据集配置: [data/mono3d.yaml](../data/mono3d.yaml)
- 3D可视化指南: [3D_VISUALIZATION_GUIDE.md](../3D_VISUALIZATION_GUIDE.md)
- 验证脚本: [test_val_visualize.py](../test_val_visualize.py)
