Skip to content

Transforms

Transforms adopt a dict-based API heavily inspired by MONAI's API.

A transform takes one sample dict and returns a new one. Compose chains them, and a dataset applies the chain to every sample it loads. The API follows MONAI's dict transforms and PyTorch Geometric's Data conventions.

Why a dict-based API?

The dict-based API allows for flexible composition of transforms and what the inputs/outputs.

PyTorch Geometric transforms, in contrast, require a Data object as input. This can be limiting if we want to forward more keys (intensity, color, etc.) and make it easier to compose when we don't want to forward all these values (using a Data object will required each transform to take care of all the attributes it carries, and defaults to None if we don't have them).

Transforms are designed to manipulate specific keys of the input data, which makes the operations explicit and easier to compose.

import torch
import torch_pointcloud.transforms as T

pos = torch.randn(2048, 3)
color = torch.rand(2048, 3)

pipeline = T.Compose([
    T.Rescale(keys="pos", method="centroid"),
    T.Shift(keys="pos", method="bbox", axes=[0, 1]),
    T.RandomSample(keys=("pos", "color"), num_samples=1024),
])

scene = pipeline({"pos": pos, "color": color})

Atomic operations

Each transform is designed as an atomic operation to make it easier to compose and reuse.

Pretrained checkpoints

A pretrained checkpoint carries its own preprocessing in info["transform"] used for inference on the specified dataset.

Sampling and downsampling

Transform Description
RandomSample Uniform random subsample with shared indices across keys
FarthestPointSample FPS subsample (well-distributed)
RandomSampleFaceVertices Sample points on a mesh's faces
Voxelize Voxel-grid downsample with per-voxel reduction

Sampling keys

Any transform that changes the number of points keeps pos, x, segment and batch aligned at the new resolution and records how to get back:

Key Shape Written by Meaning
origin_pos \((N_\text{origin}, 3)\) a CopyItems step in every registered pipeline the source cloud, in the same frame as pos
origin_segment \((N_\text{origin},)\) the same step, when the pipeline carries labels the source labels, in the model's label space
inverse \((N_\text{origin},)\) Voxelize, DivisiblePad through dst_inverse_key source row to predictor row: preds[inverse] scores at full resolution
index \((N,)\) the selection samplers (FarthestPointSample, RandomSample, SphereCrop, ...) through dst_index_key predictor row to source row: origin_pos[index] is pos

Chained steps compose these maps, so they always address the outermost source. Registered pipelines set the keys; set them on your own samplers to get the maps.

Geometry / shifting

Transform Description
Shift Subtract a computed offset (bbox, centroid, or min)
AlignAxis Shift one axis so its min is zero
AxisMinOffset Per-point offset from axis minimum (height feature)

Scaling / normalization

Transform Description
Rescale Center and rescale to unit extent (centroid / bbox / centroid_extent / min_sphere)
Normalize Per-channel \((x - \mu) / \sigma\) standardization
Scale Multiply by a scalar
Divide Divide by a scalar

Masking and filtering

Transform Geometry
BoxMask Axis-aligned bounding box (AABB)
CubeMask Lāˆž / Chebyshev ball (hypercube)
SphereMask L2 / Euclidean ball
ApplyMask Apply any precomputed mask to one or more keys
RemoveNearOrigin One-shot L2 filter around origin

Key / dict manipulation

Transform Description
Cat Concatenate multiple keys' tensors along a dim
CopyItems Clone a key's value under a new name
RenameItems Move a key to a new name
KeepItems Drop everything not in a whitelist
SetValue Set keys to literal values
SubtractKey data[k] - data[sub_k] element-wise
DivideKey data[k] / data[div_k] element-wise
Reduce Reduce a tensor along a dim (min/max/mean/sum)
OneHot One-hot encode integer labels
Relabel Remap integer labels via a lookup table
Abs Element-wise absolute value

Type / device

Transform Description
ToFloat Cast tensors to float32
ToTensor Convert lists / arrays to tensors
ToDevice Move to a device
OnesLike Add a key whose tensor is torch.ones_like(...)

Octree (optional, requires ocnn)

Transform Description
BuildOctree Build an octree from positions
OctreeFeatures Extract per-node features from an octree