Skip to content

S3DIS

S3DIS indoor scene segmentation datasets with room loading, alignment, and tiling helpers.

First page of 3D Semantic Parsing of Large-Scale Indoor Spaces

Computer Vision Foundation CVPR · June 2016

Classes:

  • S3DISRoomData –

    Per-point arrays of one S3DIS room, as returned by load_s3dis_room.

  • S3DIS –

    The Stanford 3D Indoor Spaces Dataset (S3DIS) dataset, as described in the original paper

  • S3DISHdf5 –

    Pre-processed HDF5 version of the S3DIS dataset used by multiple SOTA reference implementations.

Functions:

  • load_s3dis_room –

    Load the full S3DIS room from a given directory and (optionally) apply an alignment angle.

  • load_s3dis_alignment_angles –

    Load the alignment angles for a given area from a text file.

  • tile_s3dis_room –

    Split a single room dict into fixed-size spatial blocks.

S3DISRoomData

Bases: TypedDict

Per-point arrays of one S3DIS room, as returned by load_s3dis_room.

S3DIS

S3DIS(
    root: PathLike,
    *,
    areas: Union[
        ValueCollection[S3DISArea], Literal["all"]
    ] = "all",
    classes: Union[
        ValueCollection[S3DISClass], Literal["all"]
    ] = "all",
    aligned: bool = True,
    block_size: Optional[float] = None,
    block_stride: float = 1.0,
    num_nodes: int = 4096,
    min_num_nodes: int = 100,
    transform: Optional[Callable] = None,
    download: bool = False,
    force_download: bool = False,
    force_process: bool = False,
    show_progress: bool = True,
    num_workers: Optional[int] = None,
)

Bases: PointCloudDataset

The Stanford 3D Indoor Spaces Dataset (S3DIS) dataset, as described in the original paper 3D Indoor Spaces Dataset: Collection, Annotations, and Methods.

You can download the raw dataset from https://cvg-data.inf.ethz.ch/s3dis/ official website.

The S3DIS dataset contains 6 diverse areas (one used for testing) covering a total of 6020 square meters. Each area contains multiple rooms (e.g. office, conference room, etc.), and each room contains multiple segment regions (e.g. wall, floor, ceiling, etc.) with instance-level annotations.

The dataset will be processed automatically and saved in the S3DIS/processed directory. Each room is stored as its own folder: <processed_dir>/<Area_i>/<room_name>/{coord,color,segment,instance}.npy. If the processed data already exists, it will be loaded from the S3DIS/processed directory and processing will be skipped.

Tip

If you change the preprocessing parameters, you can delete the processed data to reprocess the dataset or use the force_process argument to force the processing of the raw data.

Parameters:

  • root (PathLike) –

    The root directory of the dataset, where the raw and processed data will be stored.

  • areas (Union[ValueCollection[S3DISArea], Literal['all']], default: 'all' ) –

    The areas to load, either a list of area names or "all".

  • classes (Union[ValueCollection[S3DISClass], Literal['all']], default: 'all' ) –

    The classes to load, either a list of class names or "all".

  • aligned (bool, default: True ) –

    Whether to apply each room's global alignment rotation during processing. The raw Stanford3dDataset_v1.2_Aligned_Version download ships the same (non-aligned) coordinates as V1.2 plus per-room Area_{i}_alignmentAngle.txt files. When aligned=True (default) the rotation is applied so the stored coordinates are globally aligned. When False the original V1.2 coordinate frame is kept: this is required when benchmarking pretrained weights that were trained on non-aligned data (e.g. the DGCNN reference weights whose HDF5 blocks use non-aligned coordinates). Aligned and unaligned data are stored in separate processed directories so they can coexist.

  • block_size (Optional[float], default: None ) –

    If set, each room is split into ground-plane blocks of this size (meters) at load time. Changing this only affects loading, not on-disk processed data.

  • block_stride (float, default: 1.0 ) –

    Stride between blocks when block_size is set.

  • num_nodes (int, default: 4096 ) –

    Target number of points per block (or per room when not tiling).

  • min_num_nodes (int, default: 100 ) –

    Skip blocks with fewer than this many points.

  • transform (Optional[Callable], default: None ) –

    A callable that transforms the data when retrieved from the dataset.

  • download (bool, default: False ) –

    Whether to download the raw data.

  • force_download (bool, default: False ) –

    Whether to force the download of the raw data.

  • force_process (bool, default: False ) –

    Whether to force the processing of the raw data.

  • show_progress (bool, default: True ) –

    Whether to show a progress bar during processing.

  • num_workers (Optional[int], default: None ) –

    Number of worker processes for parallel room processing. If None, rooms are processed sequentially.

Example

Assuming you have downloaded the raw dataset from https://cvg-data.inf.ethz.ch/s3dis/, and extracted it under data/S3DIS/raw, you can load the dataset as follows:

from torch_pointcloud.datasets import S3DIS

dataset = S3DIS(
    root="data",
    areas=["Area_1", "Area_2", "Area_3", "Area_4", "Area_6"],
)

To split rooms into 1m x 1m blocks (matching the DGCNN evaluation protocol):

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

Methods:

  • is_area_processed –

    Check whether an area is fully packed in the processed cache.

  • process –

    Process the raw dataset for easier loading.

  • load –

    Load the processed dataset into memory.

Attributes:

  • processed_dir (str) –

    Path to the processed cache directory, suffixed _aligned when the rooms are axis-aligned.

  • class_to_idx (dict[str, int]) –

    Mapping from class name to label index.

  • name (str) –

    Name of the dataset directory.

  • data_dir (str) –

    Path to the dataset directory <root>/<name>.

  • raw_dir (str) –

    Path to the raw download directory.

processed_dir property

processed_dir: str

Path to the processed cache directory, suffixed _aligned when the rooms are axis-aligned.

class_to_idx cached property

class_to_idx: dict[str, int]

Mapping from class name to label index.

name property

name: str

Name of the dataset directory.

data_dir property

data_dir: str

Path to the dataset directory <root>/<name>.

raw_dir property

raw_dir: str

Path to the raw download directory.

is_area_processed

is_area_processed(area: str) -> bool

Check whether an area is fully packed in the processed cache.

Parameters:

  • area (str) –

    Name of the area (e.g. Area_1).

Returns:

  • bool –

    True if every packed file of the area exists, False otherwise.

process

process(
    force: bool = False,
    num_workers: Optional[int] = None,
    show_progress: bool = True,
) -> None

Process the raw dataset for easier loading.

When aligned=True, applies the per-room alignment rotation so that the stored coordinates are in the globally-aligned frame (the s3disfull convention). When aligned=False, coordinates are kept in the raw scan frame.

load

load(
    block_size: Optional[float] = None,
    block_stride: float = 1.0,
    num_nodes: int = 4096,
    min_num_nodes: int = 100,
    show_progress: bool = True,
) -> None

Load the processed dataset into memory. If the provided block_size is not None and greater than 0, the rooms will be split into fixed-size spatial blocks.

Parameters:

  • block_size (Optional[float], default: None ) –

    Side length of each square block in meters.

  • block_stride (float, default: 1.0 ) –

    Step size for the sliding window in meters. Must be \(\leq\) block_size.

  • num_nodes (int, default: 4096 ) –

    Fixed number of nodes per block. Nodes are randomly subsampled (or duplicated if the block has fewer nodes).

  • min_num_nodes (int, default: 100 ) –

    Minimum number of raw nodes for a block to be kept.

  • show_progress (bool, default: True ) –

    Whether to show a progress bar during loading.

S3DISHdf5

S3DISHdf5(
    root: PathLike,
    *,
    areas: Union[
        Sequence[S3DISArea], Literal["all"]
    ] = "all",
    classes: Union[
        ValueCollection[S3DISClass], Literal["all"]
    ] = "all",
    transform: Optional[Callable] = None,
    download: bool = False,
    force_download: bool = False,
    force_process: bool = False,
    show_progress: bool = True,
)

Bases: PointCloudDataset

Pre-processed HDF5 version of the S3DIS dataset used by multiple SOTA reference implementations.

Unlike S3DIS, which loads from the raw annotated rooms, this class loads the pre-tiled 4096-point blocks distributed as HDF5 files. The blocks are already spatially tiled and fixed-size, so no additional tiling step is needed.

Each sample is a dict with the following keys:

Key Shape Dtype Description
pos \((4096, 3)\) float32 XYZ coordinates
color \((4096, 3)\) float32 RGB values
norm_pos \((4096, 3)\) float32 Room-normalized XYZ coordinates (range \([0,1]\))
segment \((4096,)\) int64 Per-point semantic label (13 classes)

Labels are emitted in S3DIS_CLASSES order (the archive itself stores them in S3DIS_HDF5_CLASSES order, which swaps table / chair and sofa / bookcase).

Important

This dataset is already processed and the HDF5 files are used directly. They are stored in the S3DIS/indoor3d_sem_seg_hdf5_data directory, meaning that they are co-located with the S3DIS dataset.

Parameters:

  • root (PathLike) –

    Root directory where S3DIS/indoor3d_sem_seg_hdf5_data/ is stored.

  • areas (Union[Sequence[S3DISArea], Literal['all']], default: 'all' ) –

    Areas to load, either a sequence of area names or "all".

  • classes (Union[ValueCollection[S3DISClass], Literal['all']], default: 'all' ) –

    Classes to load, either a sequence of class names or "all". When a subset is selected, labels are remapped to contiguous indices in the given order; unselected classes fall back to the new index of clutter when it is selected, else to the ignore index -1 (matching S3DIS).

  • transform (Optional[Callable], default: None ) –

    Optional callable applied to each sample dict at __getitem__ time.

  • download (bool, default: False ) –

    Whether to download the HDF5 archive if not already present.

  • force_download (bool, default: False ) –

    Whether to re-download even if the archive already exists.

  • force_process (bool, default: False ) –

    Whether to force re-processing (no-op for this variant since the HDF5 files are used directly).

  • show_progress (bool, default: True ) –

    Whether to show progress bars during download and loading.

Example

Assuming you have downloaded the HDF5 files from https://shapenet.cs.stanford.edu/media/, and extracted it under data/S3DIS/indoor3d_sem_seg_hdf5_data, you can load the dataset as follows:

from torch_pointcloud.datasets import S3DISHdf5

dataset = S3DISHdf5(root="data", areas=["Area_1"])
sample = dataset[0]
sample["pos"].shape   # torch.Size([4096, 3])
sample["segment"].shape  # torch.Size([4096])

Attributes:

  • name (str) –

    Name of the dataset directory (shared with S3DIS).

  • class_to_idx (dict[str, int]) –

    Mapping from class name to label index.

  • raw_dir (str) –

    Path to the raw download directory.

  • processed_dir (str) –

    Path to the processed cache directory, which aliases raw_dir since the HDF5 blocks are read as-is.

  • data_dir (str) –

    Path to the dataset directory <root>/<name>.

name property

name: str

Name of the dataset directory (shared with S3DIS).

class_to_idx cached property

class_to_idx: dict[str, int]

Mapping from class name to label index.

raw_dir property

raw_dir: str

Path to the raw download directory.

processed_dir property

processed_dir: str

Path to the processed cache directory, which aliases raw_dir since the HDF5 blocks are read as-is.

data_dir property

data_dir: str

Path to the dataset directory <root>/<name>.

load_s3dis_room

load_s3dis_room(
    room_dir: PathLike, alignment_angle: float | None = None
) -> S3DISRoomData

Load the full S3DIS room from a given directory and (optionally) apply an alignment angle.

Parameters:

  • room_dir (PathLike) –

    Path to the room directory.

  • alignment_angle (float | None, default: None ) –

    Alignment angle to apply to the room. Defaults to None.

Returns:

Example

Assuming you have downloaded the raw dataset and extracted it under data/S3DIS/raw, you can load the alignment angles for the Area_1 as follows:

from torch_pointcloud.datasets.s3dis import load_s3dis_room

room_dir = "data/S3DIS/raw/Area_1/conferenceRoom_1"
data = load_s3dis_room(room_dir)

load_s3dis_alignment_angles

load_s3dis_alignment_angles(
    file_path: PathLike,
) -> dict[str, float]

Load the alignment angles for a given area from a text file. In S3DIS dataset, one file is provided for each area, containing the alignment angles for each room in the area. The file is a text file with the following format:

## Global alignment angle per disjoint space in Area_1 ##
## Disjoint Space Name Global Alignment Angle ##
conferenceRoom_1 0
conferenceRoom_2 180
Example

Assuming you have downloaded the raw dataset and extracted it under data/S3DIS/raw, you can load the alignment angles for the Area_1 as follows:

from torch_pointcloud.datasets.s3dis import load_s3dis_alignment_angles

file_path = "data/S3DIS/raw/Area_1/Area_1_alignmentAngle.txt"
angles = load_s3dis_alignment_angles(file_path)

tile_s3dis_room

tile_s3dis_room(
    room: dict[str, Any],
    block_size: float = 1.0,
    block_stride: float = 1.0,
    num_nodes: int = 4096,
    min_num_nodes: int = 100,
) -> list[dict[str, Any]]

Split a single room dict into fixed-size spatial blocks.

The algorithm shifts the room so that the minimum point is at the origin, then sweeps a \(\text{block\_size} \times \text{block\_size}\) window (full Z extent) over the room with the given stride. This matches the procedure in multiple SOTA reference implementations (KPFCNN, ...).

Parameters:

  • room (dict[str, Any]) –

    Dict with at least DataKeys.POS (float32, \((N, 3)\)). All other tensors with a leading dimension of \(N\) are sliced in parallel.

  • block_size (float, default: 1.0 ) –

    Side length of each square block in meters.

  • block_stride (float, default: 1.0 ) –

    Step size for the sliding window in meters. Must be \(\leq\) block_size.

  • num_nodes (int, default: 4096 ) –

    Fixed number of nodes per block. Nodes are randomly subsampled (or duplicated if the block has fewer nodes).

  • min_num_nodes (int, default: 100 ) –

    Minimum number of raw nodes for a block to be kept.

Returns:

  • list[dict[str, Any]] –

    List of dicts, one per retained block. Each block has exactly

  • list[dict[str, Any]] –

    num_nodes nodes (randomly subsampled or oversampled).

  • list[dict[str, Any]] –

    Positions are origin-shifted (room minimum at origin).

Example

Assuming you have downloaded the raw dataset and extracted it under data/S3DIS/raw, you can tile the room into 1m x 1m blocks as follows:

from torch_pointcloud.datasets.s3dis import load_s3dis_room, tile_s3dis_room

room_dir = "data/S3DIS/raw/Area_1/conferenceRoom_1"
data = load_s3dis_room(room_dir)
blocks = tile_s3dis_room(data)