Files
2026-06-24 09:35:46 +08:00
..
2026-06-24 09:35:46 +08:00
2026-06-24 09:35:46 +08:00
2026-06-24 09:35:46 +08:00
2026-06-24 09:35:46 +08:00
2026-06-24 09:35:46 +08:00
2026-06-24 09:35:46 +08:00
2026-06-24 09:35:46 +08:00
2026-06-24 09:35:46 +08:00
2026-06-24 09:35:46 +08:00
2026-06-24 09:35:46 +08:00
2026-06-24 09:35:46 +08:00
2026-06-24 09:35:46 +08:00
2026-06-24 09:35:46 +08:00

真值可视化脚本说明

概述

本目录包含用于单帧图像真值可视化的脚本可以实现2D和3D边界框的可视化。

真值读取到可视化的完整流程

1. 数据加载流程utils/dataloaders3d.py

1.1 标签读取 (load_label())

# 标签文件格式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: xc, yc (3D框中心投影到2D的归一化坐标)
# - 列15: alpha (观测角)
# - 列16-23: 前面信息 [x3d, y3d, z3d, alpha, xc, yc, score, visible]
# - 列24-31: 后面信息
# - 列32-39: 左面信息
# - 列40-47: 右面信息

支持三种标签格式:

  • 2D only (6列): 仅包含2D边界框
  • 2D+3D simple (18列): 针对行人、自行车、骑手包含基本3D信息
  • 2D+3D+faces (50列): 针对车辆、三轮车包含完整的4个面信息

1.2 图像读取 (load_image())

# 使用cv2.imread读取BGR格式图像
img = cv2.imread(image_path)  # (H, W, 3) BGR

1.3 标定参数读取

# 从 camera4.json 读取相机内参
{
    "focal_u": fx,      # x方向焦距
    "focal_v": fy,      # y方向焦距  
    "cu": cx,           # x方向主点
    "cv": cy,           # y方向主点
    "pitch": pitch,     # 相机俯仰角
    "distort_coeffs": []  # 畸变系数
}

2. 数据预处理流程

2.1 ROI变换可选

# 计算消失点和裁剪中心
vanish_y = cy - fy * tan(pitch * π/180)
crop_center = (oriW/2, vanish_y)

# 计算ROI边界
roi_x1 = crop_center_x - roi_width/2
roi_y1 = crop_center_y - roi_height/2
roi_x2 = roi_x1 + roi_width
roi_y2 = roi_y1 + roi_height

# 裁剪图像
img_roi = img[roi_y1:roi_y2, roi_x1:roi_x2]

2.2 标签坐标转换

# 将2D边界框从原始图像坐标转换到ROI坐标
# 1. 归一化xywh -> 绝对xyxy
# 2. 平移到ROI相对坐标
# 3. 裁剪到ROI边界内
# 4. 重新归一化

# UV坐标面中心投影也需要相应转换

2.3 深度归一化(可选)

# 当使用虚拟焦距时需要缩放z3d深度值
# 只缩放Z坐标X和Y从UV和Z恢复
scale = virtual_fx / fx_original
z3d_normalized = z3d_original * scale

# 包括:
# - 列7: 整体中心z3d
# - 列17: 前面中心z3d
# - 列25: 后面中心z3d
# - 列33: 左面中心z3d
# - 列41: 右面中心z3d

3. 可视化流程test_val_visualize.py

3.1 2D可视化

# 使用 plot_2d_boxes_to_image() 或类似逻辑
# 1. 放大图像scale_factor=2获得更清晰的可视化
# 2. 将归一化坐标转换为像素坐标
# 3. 使用Annotator绘制边界框和类别标签
# 4. 添加标签文字(如"2D GT"

3.2 3D可视化

步骤1解码3D框 (decode_and_reconstruct_3d_box_from_target())

# 针对不同类别采用不同策略:

# 车辆类class 0, 13基于最佳可见面重建
# 1. 遍历4个面前、后、左、右
# 2. 选择可见且得分最高的面
# 3. 从面中心(u,v,z)反投影得到3D中心
# 4. 使用dimensions和rot_y计算8个3D角点

# 行人类class 1, 2, 3基于完整3D框
# 1. 直接使用(x3d, y3d, z3d)作为3D中心
# 2. 使用dimensions和rot_y计算8个3D角点
# 3. 注意:需要将归一化深度转换回原始尺度
#    z3d_original = z3d_normalized * depth_scale

步骤2投影和绘制 (plot_3d_boxes_from_decoded_targets())

# 1. 将3D角点投影到2D图像平面
#    u = fx * X/Z + cx
#    v = fy * Y/Z + cy
# 2. 绘制3D框的12条边
# 3. 使用不同颜色区分前后面
# 4. 对于车辆类,标记最佳可见面的中心点

3.3 BEV可视化

# 1. 创建空白BEV图像 (draw_bev_blank)
# 2. 对每个3D框调用 drawbev() 绘制俯视图
# 3. 使用不同颜色区分真值(绿色)和预测(红色)

4. 关键坐标系统

4.1 图像坐标系

  • 原点:图像左上角
  • x轴向右
  • y轴向下
  • 单位:像素或归一化[0,1]

4.2 相机坐标系

  • 原点:相机光心
  • x轴向右
  • y轴向下
  • z轴向前深度方向
  • 单位:米

4.3 投影关系

u = fx * X/Z + cx
v = fy * Y/Z + cy

# 反投影已知u,v,Z求X,Y
X = (u - cx) * Z / fx
Y = (v - cy) * Z / fy

使用方法

基本用法不应用ROI

python scripts_for_gt/visualize_single_frame.py \
    --image /path/to/images/frame_001.jpg \
    --label /path/to/labels/frame_001.txt \
    --output ./gt_visualization

带ROI变换与训练一致

python scripts_for_gt/visualize_single_frame.py \
    --image /path/to/images/frame_001.jpg \
    --label /path/to/labels/frame_001.txt \
    --output ./gt_visualization \
    --roi 704 352 \
    --virtual-fx 500 \
    --ori-img-size 1920 1080

参数说明

  • --image: 图像文件路径(必需)
  • --label: 标签文件路径(必需)
  • --output: 输出目录(默认:./gt_visualization
  • --calib: 相机标定文件路径camera4.json如不提供会自动从图像路径推断
  • --roi: ROI尺寸宽 高),如:--roi 704 352
  • --virtual-fx: 虚拟焦距,用于深度归一化
  • --ori-img-size: 原始图像尺寸(宽 高),如不提供则从图像自动获取

输出文件

脚本会在输出目录生成以下文件:

  • {filename}_2d_gt.jpg: 2D边界框可视化
  • {filename}_3d_gt.jpg: 3D边界框投影可视化
  • {filename}_bev_gt.jpg: 鸟瞰图BEV可视化
  • {filename}_combined.jpg: 组合可视化2D + 3D + BEV

示例

假设数据结构如下:

/data/
├── images/
│   └── frame_001.jpg
├── labels/
│   └── frame_001.txt
└── calib/
    └── L2_calib/
        └── camera4.json

运行命令:

python scripts_for_gt/visualize_single_frame.py \
    --image /data/images/frame_001.jpg \
    --label /data/labels/frame_001.txt \
    --output ./output \
    --roi 704 352 \
    --virtual-fx 500

注意事项

  1. 标定文件自动推断:如果不指定--calib,脚本会自动查找与图像路径对应的标定文件(../calib/L2_calib/camera4.json

  2. 深度归一化:当使用--virtual-fxz3d坐标会被缩放以匹配虚拟焦距这与训练时的处理一致

  3. 坐标系统

    • 输入标签使用归一化坐标[0,1]
    • 3D坐标使用相机坐标系
    • 深度归一化后需要在可视化时转换回原始尺度
  4. 支持的类别

    • 0: vehicle车辆- 使用面策略
    • 1: pedestrian行人- 使用完整框
    • 2: bicycle自行车- 使用完整框
    • 3: rider骑手- 使用完整框
    • 13: tricycle三轮车- 使用面策略

快速测试

提供了一个自动测试脚本,可以自动从验证集中找到第一个有效样本并进行可视化:

# 使用默认数据集配置
python scripts_for_gt/test_visualization.py

# 指定数据集配置
python scripts_for_gt/test_visualization.py --data data/mono3d.yaml --output ./test_output

测试脚本会:

  1. 从数据集配置中读取验证集路径
  2. 自动查找第一个有标签的样本
  3. 分别测试原始图像可视化和ROI变换可视化
  4. 生成所有可视化结果到指定目录

批量处理

如果需要批量处理多帧图像,可以使用批量脚本:

python scripts_for_gt/visualize_batch.py \
    --image-dir /path/to/images \
    --label-dir /path/to/labels \
    --output ./batch_output \
    --roi 704 352 \
    --virtual-fx 500 \
    --max-samples 10

参数说明:

  • --image-dir: 图像目录
  • --label-dir: 标签目录
  • --output: 输出目录
  • --calib-dir: 标定文件目录(可选)
  • --roi: ROI尺寸
  • --virtual-fx: 虚拟焦距
  • --max-samples: 最大处理样本数(可选)

条件过滤可视化

如果需要从训练集或验证集中筛选特定条件的样本进行可视化,可以使用过滤脚本:

示例1: 可视化包含两轮车的样本(空间范围过滤)

# 只可视化两轮车在左右各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 \
    --output ./bicycle_samples

示例2: 可视化包含行人的样本

# 可视化前50个包含行人的训练样本
python scripts_for_gt/visualize_filtered_train.py \
    --data data/mono3d.yaml \
    --target-class pedestrian \
    --max-samples 50 \
    --output ./pedestrian_samples

示例3: 可视化特定空间范围内的车辆

# 可视化车辆在左右5米、纵向10-30米范围内的样本
python scripts_for_gt/visualize_filtered_train.py \
    --data data/mono3d.yaml \
    --target-class vehicle \
    --x-range -5 5 \
    --z-range 10 30 \
    --max-samples 30 \
    --output ./vehicle_samples

过滤参数说明

  • --target-class: 目标类别vehicle, pedestrian, bicycle, rider, motorcycle, tricycle
  • --x-range MIN MAX: X坐标范围左右方向单位
  • --y-range MIN MAX: Y坐标范围上下方向单位
  • --z-range MIN MAX: Z坐标范围前后方向/深度),单位:米
  • --min-targets: 最少目标数量默认1
  • --max-samples: 最大可视化样本数
  • --split: 数据集划分train或val默认train
  • --use-roi: 使用ROI变换

坐标系说明

相机坐标系:

  • X轴: 向右为正(单位:米)
  • Y轴: 向下为正(单位:米)
  • Z轴: 向前为正(深度方向,单位:米)

示例:

  • --x-range -10 10: 左右各10米范围
  • --z-range 0 50: 前方0到50米范围
  • --y-range -2 1: 相机水平面上下2米到下方1米范围

脚本说明

本目录包含以下脚本:

  1. visualize_single_frame.py - 单帧可视化脚本

    • 核心功能读取单帧图像和标签生成2D、3D和BEV可视化
    • 支持ROI变换和深度归一化
  2. visualize_batch.py - 批量可视化脚本

    • 批量处理多帧图像
    • 自动匹配图像和标签文件
  3. test_visualization.py - 快速测试脚本

    • 自动查找验证集样本
    • 测试不同配置的可视化效果

扩展功能

可以基于此脚本进行扩展:

  • 添加不同的可视化风格
  • 输出3D框参数到文件
  • 与预测结果对比
  • 统计分析(深度分布、尺寸分布等)