
从3D框到2D图像bdd100k Box3D标注体系与边缘可见性算法实战指南【免费下载链接】bdd100kThis repo has been moved to https://github.com/bdd100k/bdd100k permanently.项目地址: https://gitcode.com/gh_mirrors/bd/bdd100kbdd100k是一个面向自动驾驶的大规模真实驾驶视频数据集项目提供了 10 万级街景视频的 2D/3D 标注与配套工具。本文将从 bdd100k 数据集的Box3D 标注体系讲起带你快速搞懂 3D 框如何表示、又如何通过边缘可见性算法正确投影绘制到 2D 图像上并给出可上手的可视化实战步骤。一、认识 bdd100k 数据集上图bdd100k 的标注可视化效果包含 2D 检测框、3D 包围框Box3D、可行驶区域与车道线标注覆盖白天/夜晚、城市街道/住宅区等多种场景bdd100kBerkeley DeepDrive收录了 700 万 张真实城市街景图像标注维度非常丰富Box2D10 类道路物体car、bus、person、traffic light 等的 2D 边界框Box3D部分物体的 3D 包围框位置、尺寸、朝向️可行驶区域 / 车道线以 2D 多边形poly2d表示️场景属性天气、时段、道路场景等完整标注格式定义可参考 doc/format.md 文档它是与 Scalabel 标注工具兼容的 JSON 结构。二、快速上手获取仓库并运行️ 只需三步即可体验 bdd100k 的可视化工具1️⃣ 克隆仓库Python 环境为主git clone https://gitcode.com/gh_mirrors/bd/bdd100k cd bdd100k2️⃣ 安装依赖见requirements.txt主要是 numpy 与 matplotlibpip install -r requirements.txt3️⃣ 运行标注可视化工具bdd100k/show_labels.py传入一张街景图和对应的 JSON 标签文件即可在图上叠加 Box2D / Box3D / 车道线python -m bdd100k.show_labels -i 图片路径 -l 标签json路径 -o 输出目录如果想把整个视频的 GPS 轨迹绘制到地图上可以运行bdd100k/show_gps_trajectory.py上图bdd100k 视频对应的 GPS 轨迹在地图上的展示效果三、Box3D 标注体系一个 3D 框由哪些字段构成在 bdd100k 的标签 JSON 中每个带 3D 信息的物体label都包含一个box3d字段核心有 4 个要素字段含义location3D 中心点坐标 (x, y, z)dimension尺寸高 (h)、宽 (w)、长 (d)orientation3D 朝向角用于点云标注alpha观测角存在 2D 视图时使用有了这 4 个要素就能推导出 3D 框的8 个顶点。在源码 bdd100k/geometry.py 中Label3d.from_box3d()方法正是这样做的以location为中心按dimension在 8 个方向各偏移一半尺寸得到v000~v111八个顶点再调用rotate_vector()围绕中心做旋转支持绕 Y 轴的orientation或完整的欧拉角orientation3D# geometry.py 中的核心思路伪代码级示意 center box3d[location] height, width, depth box3d[dimension] # 8 个顶点 中心 ± 半个尺寸再按 orientation 旋转 v000 rotate(center [-width/2, -height/2, -depth/2]) ...四、边缘可见性算法为什么 3D 框有的棱是实线、有的是虚线 把一个 3D 框画到 2D 图像上时离相机近的前脸应该画实线被遮挡的背棱应该画虚线。bdd100k 的Label3d.get_edges_with_visibility()方法位于bdd100k/geometry.py用了一个非常巧妙的几何判断步骤如下1. 定义 12 条棱与 6 个面长方体共有 12 条棱前上 FU、前右 FR…… 后下 BD和 6 个面前 F、后 B、左 L、右 R、上 U、下 D。初始时所有 12 条棱都被标记为虚线候选。2. 利用 3 组相对面配对判断朝向3 组相对面分别是FB前后、LR左右、UD上下。对每一组把两个面各自的 4 个顶点投影到 2D 平面用check_clockwise()通过叉积符号判断投影四边形是顺时针还是逆时针若两个面的旋转方向不一致说明它们中恰有一个正对相机3. 距离相机更近的面 → 实线在旋转方向相反的一对相对面中计算各自顶点中点到相机原点的距离距离更近的那个面就是可见面把它的 4 条棱标记为实线dashed_edges[edge] False。# geometry.py 判断逻辑核心简化示意 if cw1 ! cw2: # 两个相对面朝向相反 dist1 norm(median(vertices1)) # 面1到相机的距离 dist2 norm(median(vertices2)) # 面2到相机的距离 solid_face face1 if dist1 dist2 else face2 # 可见面的 4 条棱 → 实线最终算法输出两组 2D 线段solid实线棱与dashed虚线棱这就是边缘可见性的核心。新手提示check_side_of_line()函数通过行列式叉积判断点在线段哪一侧是判断顺时针/逆时针的数学基础只有十几行代码建议配合源码阅读。五、3D 投影到 2D一行矩阵乘法完成透视变换拿到 8 个 3D 顶点后还需要把它们变成像素坐标。bdd100k/geometry.py中的vector_3d_to_2d()完成了这一步把 3D 点补齐为齐次坐标[x, y, z, 1]与相机标定矩阵intrinsics 中的cali4×4相乘用前两个分量除以第三个分量透视除法得到像素坐标# 透视投影核心geometry.py vec_3d [x, y, z, 1] vec_2d calibration vec_3d return vec_2d[0] / vec_2d[2], vec_2d[1] / vec_2d[2]在bdd100k/show_labels.py的box3d_to_lines()方法中这两步被串成完整流程Label3d.from_box3d(box3d)→ 生成 8 个 3D 顶点label.get_edges_with_visibility(calibration)→ 得到实线/虚线两组 2D 线段用 matplotlib 分别以实线和虚线样式绘制到图像上遮挡物体occluded: true还会降低透明度六、相关文件导航文件作用bdd100k/geometry.pyBox3D 顶点计算、透视投影、边缘可见性算法本文核心bdd100k/show_labels.py标注可视化工具支持 Box2D / Box3D / 车道线绘制bdd100k/show_gps_trajectory.py在地图上绘制视频的 GPS 行驶轨迹bdd100k/label2det.py把 JSON 标注转换为检测任务格式bbox categorybdd100k/bdd2coco.pyBDD 标注格式与 COCO 格式互转doc/format.md完整标注 JSON 格式说明doc/evaluation.md检测/分割任务的评测指标与提交格式七、小结 回顾一下 bdd100k Box3D 标注体系的完整链路标注层location dimension orientation三要素定义一个 3D 框几何层geometry.py推导 8 顶点 → 旋转 → 透视投影到像素坐标可见性层相对面顺时针判断 距离比较自动区分实线棱与虚线棱展示层show_labels.py一键渲染直观验证标注质量这套从 3D 框到 2D 图像的算法并不复杂却覆盖了 3D 检测任务中最常用的投影与遮挡处理思路。读懂它你就具备了自行绘制任意数据集 3D 标注的基础能力。【免费下载链接】bdd100kThis repo has been moved to https://github.com/bdd100k/bdd100k permanently.项目地址: https://gitcode.com/gh_mirrors/bd/bdd100k创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考