Skip to content

Segmentation Datasets

Open in Colab ยท Download notebook

Segmentation datasets hold one scene per sample: a room or a LiDAR scan, with a label on every point. A sample holds hundreds of thousands of points, so a training pipeline crops, voxelizes or tiles it before batching.

A committed ScanNet room: color, semantic labels, instance ids

An indoor sample carries color, a semantic label and an instance id on every point. Outdoor scans carry intensity in place of color.

Indoor

Dataset Scenes Classes Download
S3DIS 272 rooms in 6 areas 13 automatic
S3DISHdf5 23 585 tiles of 4 096 points 13 automatic
ScanNet20 1 201 train / 312 val 20 automatic
ScanNet200 same scenes 200 automatic

Outdoor

Dataset Frames or scenes Classes Download
SemanticKITTI 19 130 train / 4 071 val 19 manual
Semantic3D 15 train scenes 9 manual
Toronto3D 4 tiles 9 manual
ParisLille3D 3 scenes 10 manual

Load a dataset

from torch_pointcloud.datasets import S3DIS
from torch_pointcloud.config import DATA_DIR

dataset = S3DIS(root=DATA_DIR, areas=["Area_5"], download=True)
print(f"Rooms: {len(dataset)}")
print({k: tuple(v.shape) for k, v in dataset[0].items()})

ScanNet is loaded the same way, and adds estimated normals and the scene name:

from torch_pointcloud.datasets import ScanNet20
from torch_pointcloud.config import DATA_DIR

dataset = ScanNet20(root=DATA_DIR, split="val", download=True)
print(f"Scenes: {len(dataset)}")
print(sorted(dataset[0]))

A committed SemanticKITTI scan: intensity, and its semantic labels

Outdoor scans carry intensity \((N, 1)\) instead of color (reflectance on ParisLille3D), plus the sequence and frame identifiers on SemanticKITTI. Their labels are the raw SemanticKITTI ids, which the checkpoints remap themselves.

Tile a large room

S3DIS and ScanNet can split their scenes into ground-plane blocks at construction time, which reproduces the block-based training protocols:

from torch_pointcloud.config import DATA_DIR

dataset = S3DIS(
    root=DATA_DIR,
    areas=["Area_1"],
    block_size=1.0,
    block_stride=0.5,
    num_nodes=4096,
)

S3DISHdf5 is the same data, released already cut into 4096-point tiles. Use it for benchmarking to reproduce block-based results.

Conventions

Color range differs per loader

color is uint8 in \([0, 255]\) for S3DIS, ScanNet, Toronto3D and Semantic3D, and float32 in \([0, 1]\) for S3DISHdf5. Checkpoint transforms divide by 255 where needed, so mixing the two silently halves or doubles the input scale.

Ignore index differs per dataset

Unlabeled points are 0 in ScanNet (<unk>) and the outdoor sets, and \(-1\) after the class-subset remaps. A checkpoint's Relabel transform sends everything outside its class list to its own default, and the matching loss and metric take ignore_index=-1.

Batch the samples

Batching uses the packed format. PointCloudDataLoader is a DataLoader whose collate_fn defaults to the packed collate: per-point tensors are concatenated into one tensor, and a batch index is built alongside them.

from torch_pointcloud.utils.data import PointCloudDataLoader
from torch_pointcloud.config import DATA_DIR

dataset = S3DIS(
    root=DATA_DIR, 
    areas=["Area_5"],
    block_size=1.0,
    block_stride=0.5,
    num_nodes=4096,
)

dataloader = PointCloudDataLoader(
    dataset, 
    batch_size=32, 
    shuffle=True, 
    num_workers=6,
)

data = next(iter(dataloader))

print(f"Batch keys: {data.keys()}")
print(f"  pos.shape: {tuple(data['pos'].shape)}")
print(f"  batch.shape: {tuple(data['batch'].shape)}")
print(f"  segment.shape: {tuple(data['segment'].shape)}")

# Loading: 100%|โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ| 1/1 [00:07<00:00,  7.84s/it]
# Batch keys: dict_keys(['pos', 'color', 'segment', 'instance', 'room_max', 'batch'])
#   pos.shape: (131072, 3)
#   batch.shape: (131072,)
#   segment.shape: (131072,)

Class names

from torch_pointcloud.datasets.semantickitti import SEMANTIC_KITTI_CLASSES
from torch_pointcloud.datasets.parislille3d import PARISLILLE3D_CLASSES

print(len(SEMANTIC_KITTI_CLASSES), len(PARISLILLE3D_CLASSES))

S3DIS and ScanNet20 expose theirs the same way, and a pretrained checkpoint carries its own head order in info["weights"]["classes"].