3. 数据基础

Occupancy网络训练的第一步不是搭模型,而是把“三维空间被占据的情况”变成网络能读、能学、能评估的数据。与检测框、语义分割掩码不同,Occupancy标签描述的是体素级或查询点级的空间占据状态,它同时携带几何、语义与可见性信息。理解数据格式、标注规范和主流数据集,是后续训练与部署工程能否复现、能否迁移的前提。

一、Occupancy数据的核心表示

当前工业界与学术界常见的Occupancy表示可归为三类:稠密体素栅格、稀疏体素/点查询以及隐式场查询。稠密体素把空间切成规则网格,每个体素存占据概率或语义类别,结构规整、便于3D卷积,但显存随分辨率立方增长;稀疏体素只保留被占据或靠近表面的体素,配合稀疏卷积可显著降低计算量;隐式场则把Occupancy建模为连续函数,训练时在空间采样查询点,输出该点的占据与语义,适合高分辨率与任意查询位置。

无论哪种表示,一条Occupancy样本通常包含以下字段:自车坐标系下的空间范围(如x∈[-40,40]m、y∈[-40,40]m、z∈[-5,3]m)、体素分辨率(如0.4m或0.2m)、每个体素的占据状态(free/occupied/unknown)、语义类别(如车辆、行人、可行驶区域、路沿、植被、建筑等),以及可见性掩码。可见性掩码用于区分“真实为空”和“未被观测到”,这是Occupancy标注与普通3D检测标签最大的差异之一。

关键点:Occupancy标签不是“看到什么标什么”,而是“在给定传感器视野与遮挡关系下,推断每个空间单元是否被占据”。因此unknown区域必须显式建模,否则网络会把未观测区域误学成free。

二、标注规范与生成流程

Occupancy标注成本极高,纯人工逐体素标注几乎不可行。主流方案是“多传感器融合自动生成 + 人工校验/补标”。典型流程如下:

  1. 多帧点云聚合:将激光雷达多帧点云配准到同一自车坐标系,形成稠密点云,作为几何证据。
  2. 图像语义投影:用2D语义分割结果反投影到3D空间,为点云或体素提供语义先验。
  3. 表面重建与体素化:对点云做泊松重建或TSDF融合,得到表面,再按分辨率体素化,标记occupied/free。
  4. 可见性计算:从传感器原点做射线投射,标记被遮挡或超出量程的体素为unknown。
  5. 人工校验:在可视化工具中检查漏标、错标,重点修正动态物体、细长结构(如杆、行人)和地面边界。

标注规范中需要特别约定:动态物体是否按当前帧位置标注;地面与可行驶区域是否单独成类;远处稀疏区域是否降级为unknown;以及类别体系是否与下游规划控制对齐。这些约定直接决定网络输出能否被部署端消费。

工程建议:在项目早期就固定一套“类别ID + 颜色映射 + 分辨率 + 空间范围”的元数据文件(如JSON/YAML),训练、可视化、评估、部署共用同一份,避免格式漂移。

三、常见数据集:nuScenes与Waymo

目前公开的Occupancy相关数据主要来自两大自动驾驶数据集及其衍生标注。

数据集传感器配置Occupancy相关标注典型用途
nuScenes6相机 + 1激光雷达 + 5毫米波雷达官方提供3D检测与分割;社区衍生Occ3D-nuScenes提供体素级占据与语义标签多模态Occupancy预训练、时序融合
Waymo Open Dataset5相机 + 多激光雷达3D检测与跟踪;Waymo Occupancy Flow提供体素占据与运动流高精度几何、占据流预测
SemanticKITTI单激光雷达逐点语义标注,可体素化生成Occupancy激光雷达语义分割基线
Occ3D / OpenOccupancy基于nuScenes/Waymo衍生统一体素级占据+语义+可见性Occupancy预测基准评测

nuScenes的优势在于多模态同步与场景多样性,适合验证相机为主的Occupancy方案;Waymo的激光雷达点云更密,几何精度更高,适合研究高分辨率占据与占据流。实际工程中,常先用nuScenes做快速迭代,再用自采数据做域适配。

四、数据读取与格式示例

以体素级Occupancy为例,常见存储为压缩的numpy数组或稀疏索引。下面是一个简化的读取与解析示例:

import numpy as np

# occ: [X, Y, Z] uint8, 0=free, 1=occupied, 255=unknown
# sem: [X, Y, Z] uint8, 语义类别ID
occ = np.load("sample_occ.npz")["occupancy"]
sem = np.load("sample_occ.npz")["semantics"]

# 空间范围与分辨率
pc_range = [-40, -40, -5, 40, 40, 3]   # [x_min,y_min,z_min,x_max,y_max,z_max]
voxel_size = 0.4                        # 米

# 将体素索引转换为自车坐标
def voxel_to_point(ix, iy, iz):
    x = pc_range[0] + (ix + 0.5) * voxel_size
    y = pc_range[1] + (iy + 0.5) * voxel_size
    z = pc_range[2] + (iz + 0.5) * voxel_size
    return x, y, z

occupied_idx = np.argwhere(occ == 1)
print("occupied voxels:", occupied_idx.shape[0])

训练时通常还会构造可见性掩码,只对可见区域计算损失,unknown区域忽略。评估指标常用IoU、mIoU以及针对occupied类的精度/召回。

五、常见误区与复盘

  • 把unknown当free:导致网络在遮挡区域“幻觉”出可行驶空间,部署时风险极高。
  • 分辨率与感受野不匹配:0.2m分辨率下,40m×40m×8m需要约1.28亿体素,必须用稀疏表示或分块训练。
  • 类别体系与下游不一致:训练时细分“卡车/挂车”,部署端只关心“是否可通行”,会造成标签浪费与映射错误。
  • 忽略时序一致性:Occupancy是连续空间状态,单帧标注抖动会让网络学到噪声,建议多帧聚合与平滑。
  • 直接跨数据集混训:nuScenes与Waymo的坐标系、类别、分辨率不同,需先统一到同一元数据规范。

复盘结论:Occupancy数据工程的核心是“元数据统一 + 可见性建模 + 类别对齐”。数据格式一旦确定,训练、评估、部署都应围绕同一份规范展开,任何环节私自修改分辨率或类别ID,都会导致模型无法复现或部署失败。

Occupancy数据基础:格式 · 标注 · 数据集 数据格式三要素 空间范围 + 分辨率 占据状态:free/occ/unknown 语义类别 + 可见性掩码 标注生成流程 多帧点云聚合 2D语义反投影 + 表面重建 体素化 + 可见性射线投射 人工校验与补标 常见数据集 nuScenes / Occ3D-nuScenes Waymo / Occupancy Flow SemanticKITTI / OpenOccupancy 训练消费:统一元数据规范 类别ID + 颜色映射 分辨率 + 空间范围 可见性掩码策略 常见误区 unknown当free · 分辨率与感受野不匹配 · 类别体系与下游不一致 · 忽略时序一致性 跨数据集混训前必须先统一元数据规范

综上,Occupancy数据基础可以概括为:用统一的元数据规范描述空间范围、分辨率、占据状态、语义与可见性;用多传感器融合加人工校验生成标签;用nuScenes、Waymo等公开数据集快速起步,再通过自采数据完成域适配。只有把数据格式与标注规范固定下来,后续的网络训练与部署工程才有稳定的输入基础。