三维点云与立方体
用带朝向的三维立方体、点、折线与逐点分割来标注 PCD、PLY、LAS 与 KITTI 点云。八叉树细节层次、正交切片面板,以及能在往返转换中保真的四元数旋转。
Potato 可以在浏览器中,用带朝向的三维立方体、点、折线与逐点分割来标注激光雷达与摄影测量点云。 八叉树细节层次让数百万点的扫描件在笔记本上依然可交互,而相机标定会把每一个框投影到图像上,使你可以在三维中编辑、在二维中核验。
annotation_schemes:
- annotation_type: spatial_annotation
name: objects
description: "Put a 3D box around every vehicle and pedestrian."
source_field: point_cloud
tools: [cuboid_3d, point_3d]
labels:
- {name: car, color: "#FF6B6B", key_value: "1"}
- {name: pedestrian, color: "#FFD93D", key_value: "2"}
color_mode: height
point_size: 2.0
max_points: 400000可运行示例:examples/spatial/kitti-cuboids/。
格式
点云在服务端读取,并转换为浏览器可理解的一种紧凑二进制格式。若在 JavaScript 中逐一解析各种格式,就意味着四套解析器、四套字节序与记录布局的缺陷,而且每次页面加载都要重新解析一份两百万点的扫描件。
| 格式 | 说明 |
|---|---|
KITTI velodyne .bin | 裸 float32 的 x、y、z、强度,无文件头 |
| PCD | ascii、binary 与 binary_compressed(LZF) |
| PLY | ascii、binary_little_endian、binary_big_endian |
| LAS | 1.0 至 1.4,点记录格式 0 至 3 与 6 至 8 |
.xyz / .pts | 每行 x y z [r g b] |
| LAZ | 不直接读取。请先转换:laszip -i scan.laz -o scan.las |
格式中若带有颜色则会读取颜色;KITTI、PCD 与 LAS 会读取强度。若对一个没有颜色的文件请求 color_mode: rgb,系统会回退到按高度着色,并在状态栏中说明,而不是悄悄渲染出一个看起来像你所请求模式的结果。
工具
| 工具 | 绘制内容 |
|---|---|
cuboid_3d | 一个带朝向的三维框 |
point_3d | 单个三维点 |
polyline_3d | 穿过点云的一条路径 |
segment_3d | 对选中点集的逐点标签 |
旋转用四元数存储,而非偏航角
Potato 把立方体的旋转存为完整的四元数。多数格式只存单个偏航角,因此这看起来像是过度设计——直到某次往返转换丢了东西为止。
正是它让 KITTI 导入做到无损,包括那约 0.85° 的相机相对激光雷达的安装倾角,而只有偏航角的字段会把它丢掉且不作声明。导出回 KITTI 时确实必须舍弃俯仰与滚转——但系统会报告舍弃了多少朝向信息,而不是悄悄把框压平。
Potato 能表达的内容与某种格式能存储的内容之间的落差,是在格式相关的代码中、明确地跨越的,而不是在存储层中、悄无声息地跨越的。
一致性使用精确的带旋转三维 IoU
两位标注者给同一辆车画框,不会得到相同的框。Potato 用精确的带旋转三维 IoU 计算一致性,它在任意旋转下都成立,而不只适用于轴对齐的框。
只要数据不是水平的,这一点就变得重要:无人机、手持与室内扫描都会产生具有真实俯仰与滚转的框,而轴对齐的近似所报告的分歧,是度量方式的产物,而非标注者的分歧。参见几何形状上的一致性。
大规模场景下的工作方式
- 八叉树细节层次默认开启(
lod: true)。点按区域与距离加载,因此大型扫描件仍可交互。 max_points用于限制抽稀程度。它是查看器设置,不是数据设置。- 正交切片面板(
mpr: true)提供三个轴对齐视图,便于精确、完全键盘驱动的编辑。拖动其中一个面时,对面保持固定。
有一个值得知道的缺陷,因为它影响的是已存储的数据而非显示:segment_3d 的点索引过去假定了固定的抽稀比例,因此调低 max_points 会悄悄让已有的逐点标签指向不同的点。现在索引指向的是源文件,所以查看器设置不可能挪动一份标注。