S3DIS(Stanford Large-Scale 3D Indoor Spaces Dataset)是斯坦福大学发布的室内场景点云数据集,包含6个区域共271个房间的RGB点云数据,标注了13个语义类别。这个数据集在三维语义分割研究中被广泛使用,但原始数据处理起来比较麻烦,需要经过特定转换才能用于MMdet3d框架。
我建议直接从百度网盘下载预处理好的数据集(链接:https://pan.baidu.com/s/13_MtdvoYWj1a358QoLecNg 提取码:AJZY)。下载后解压到mmdetection3d/data/s3dis目录下,结构应该是这样的:
code复制mmdetection3d
├── data
│ ├── s3dis
│ │ ├── Stanford3dDataset_v1.2_Aligned_Version
│ │ │ ├── Area_1
│ │ │ ├── Area_2
│ │ │ ├── ...
│ │ ├── indoor3d_util.py
│ │ ├── collect_indoor3d_data.py
关键的一步是修改indoor3d_util.py中的export函数。这个函数负责将原始标注文件转换为模型可读的格式。原始数据中每个物体实例都是单独的txt文件,我们需要把它们合并成完整的房间点云,同时生成语义标签和实例标签。修改后的函数核心逻辑是:
实际使用时,先运行collect_indoor3d_data.py脚本处理原始数据,这会为每个房间生成三个.npy文件:
有了.npy文件后,还需要转换成MMdet3d专用的.bin格式。这个步骤会用到create_data.py脚本:
bash复制python tools/create_data.py s3dis --root-path ./data/s3dis \
--out-dir ./data/s3dis --extra-tag s3dis
这个命令会做以下几件事:
转换后的目录结构如下:
code复制s3dis
├── points # 点云数据(.bin)
├── instance_mask # 实例标签(.bin)
├── semantic_mask # 语义标签(.bin)
├── seg_info # 训练辅助信息
│ ├── Area_1_label_weight.npy # 类别权重
│ ├── Area_1_resampled_scene_idxs.npy # 重采样索引
├── s3dis_infos_Area_1.pkl # 区域元数据
...
特别要注意的是label_weight.npy文件。由于S3DIS中不同类别的点数差异很大(比如墙面的点远多于椅子),这个文件存储了每个类别的权重系数,用于在损失函数中进行类别平衡。在训练配置文件中会引用这个权重。
MMdet3d已经内置了PointNet++的实现,配置文件通常位于configs/pointnet2/目录下。对于S3DIS语义分割任务,我们使用pointnet2_ssg_2xb16-cosine-50e_s3dis-seg.py这个配置。主要参数解析:
python复制model = dict(
type='PointNet2Seg', # 模型类型
backbone=dict(
type='PointNet2SSG', # 单尺度分组(SSG)版本
in_channels=6, # 输入维度(xyz+rgb)
num_points=(4096, 1024, 256, 64), # 各层采样点数
radius=(0.1, 0.2, 0.4, 0.8)), # 分组半径
decode_head=dict(
num_classes=13, # S3DIS有13类
ignore_index=0)) # 忽略未标注点
train_dataloader = dict(
batch_size=16, # 批大小
dataset=dict(
data_root='data/s3dis',
ann_file='s3dis_infos_Area_1.pkl', # 默认用Area_1训练
seg_label_mapping=label_mapping)) # 类别映射
启动训练的命令很简单:
bash复制python tools/train.py configs/pointnet2/pointnet2_ssg_2xb16-cosine-50e_s3dis-seg.py
训练过程中有几个实用技巧:
bash复制--cfg-options optimizer.lr=0.001
训练完成后,可以用test.py评估模型在测试集上的表现:
bash复制python tools/test.py \
configs/pointnet2/pointnet2_ssg_2xb16-cosine-50e_s3dis-seg.py \
work_dirs/pointnet2_ssg_2xb16-cosine-50e_s3dis-seg/epoch_50.pth
测试脚本会输出各类别的IoU(交并比)和平均mIoU。S3DIS上PointNet++的典型性能:
如果效果不理想,可以尝试:
MMdet3d提供了便捷的可视化工具。选择一个.bin文件运行:
bash复制python demo/pcd_seg_demo.py \
data/s3dis/points/Area_1_conferenceRoom_1.bin \
configs/pointnet2/pointnet2_ssg_2xb16-cosine-50e_s3dis-seg.py \
work_dirs/pointnet2_ssg_2xb16-cosine-50e_s3dis-seg/epoch_50.pth \
--show
可视化效果会显示原始点云和预测的语义标签。不同类别用不同颜色标注,可以在config文件中调整颜色映射。如果显示效果不理想,可能是以下原因:
我在实际项目中发现,对于大型场景,可以先进行区域分割再分别处理,最后合并结果,这样能提升细节分割效果。另外,适当增加num_points参数(如从4096改为8192)也能改善小物体的识别率,但会显著增加显存消耗。