functional
Functional API of the transforms: the tensor functions of every themed module.
Functions:
-
color_auto_contrastβStretch per-cloud color range to the full
[0, max]interval, then blend. -
color_dropβReplace colors with a constant gray value (drops chromatic information).
-
color_grayscaleβConvert RGB colors to grayscale using the BT.601 luminance weights.
-
color_jitterβApply brightness, contrast, and saturation factors to colors, in that order.
-
color_shiftβAdd a per-channel offset to colors, clamped to the valid color range.
-
flip_boxesβFlip oriented 3D boxes along a spatial axis.
-
flip_vectorsβFlip a packed field of 3D vectors along a spatial axis.
-
random_color_jitterβJitter colors by brightness, contrast, and saturation, in that order.
-
random_elastic_distortionβApply a smooth random displacement field to
pos. -
random_jitterβAdd Gaussian noise to
x, optionally clipped. -
rotate_boxesβRotate oriented 3D boxes about the up axis.
-
scale_boxesβScale oriented 3D boxes by an isotropic factor.
-
translate_boxesβTranslate oriented 3D boxes by a fixed offset.
-
cut_boxesβCut the annotated objects of a scene out by their boxes, one dict per object.
-
points_in_oriented_boxβTest which points lie inside a single oriented 3D box.
-
axis_min_offsetβPer-point offset from a floor reference along a chosen coordinate axis.
-
estimate_normalsβEstimate per-point unit surface normals by local PCA.
-
quantizeβInteger voxel-grid coordinates of every point, without reducing the cloud.
-
rotate_vectorsβRotate a packed field of 3D vectors by a rotation matrix.
-
rotation_matrixβ\(3 \times 3\) rotation matrix for
angleradians around an axis-aligned axis. -
shiftβSubtract a data-driven offset from
x. -
apply_maskβApply a mask to a tensor.
-
bounding_boxβReturns the min and max values along a given dimension.
-
box_maskβCreate a boolean mask for points inside an axis-aligned bounding box (AABB).
-
cube_maskβCreate a boolean mask for points inside an axis-aligned cube (Lβ / Chebyshev ball).
-
remove_near_originβRemove points that are within a given radius (L2) of the origin.
-
sphere_maskβCreate a boolean mask for points inside an L2 (Euclidean) ball.
-
laser_mix_masksβReturn keep-masks that swap alternating inclination (pitch) bands between two LiDAR scans.
-
polar_mix_masksβReturn keep-masks that swap a random azimuth half-sector between two LiDAR scans.
-
farthest_point_sampleβFarthest-point sampling (FPS) from a tensor of positions.
-
random_dropout_maskβReturn a boolean keep-mask of length
nwhere each entry is kept with probability1 - drop_ratio. -
random_sampleβRandomly sample a fixed number of values from a tensor.
-
random_sample_face_verticesβRandomly sample a fixed number of vertices from a 3D mesh (vertices, face),
-
shuffle_indicesβReturn a random permutation of
[0, n). -
maxabs_scaleβScale a tensor by its largest absolute value, per channel: \(x' = x / \max(\max_i |x_i|, \epsilon)\).
-
minimal_enclosing_ballβCompute the smallest ball enclosing a point set (Welzl's move-to-front algorithm).
-
normalizeβPer-channel standardization: \(x' = (x - \mu) / \max(\sigma, \epsilon)\).
-
rescaleβCenter a point set and rescale it to a unit extent.
-
absoluteβMake the input tensor absolute.
-
relabelβRemap integer labels via a lookup table.
-
divisible_padβPad the batch indices of a tensor to make them divisible by a given integer.
color_auto_contrast [source] ΒΆ
Stretch per-cloud color range to the full [0, max] interval, then blend.
For each channel, the min becomes 0 and the max becomes max_val. The output is then linearly blended with the original by blend (blend=1.0 is the fully stretched version, blend=0.0 is the input).
Parameters:
-
color(Tensor) βColor tensor of shape \((N, 3)\).
-
blend(float, default:0.5) βBlend weight in
[0, 1]. -
int_color(bool, default:False) βIf
True, treat float colors as[0, 255]values; otherwise[0, 1].uint8colors are always treated as[0, 255]regardless of the flag.
Returns:
-
TensorβAuto-contrast tensor with the same shape and dtype as
color.
Raises:
-
ValueErrorβIf
coloris a float tensor with values above 1 whileint_color=False.
color_drop [source] ΒΆ
Replace colors with a constant gray value (drops chromatic information).
Parameters:
-
color(Tensor) βColor tensor of shape \((N, 3)\).
-
fill(float, default:0.5) βReplacement value, expressed in the range implied by
int_color([0, 1]whenFalse,[0, 255]whenTrue). It is rescaled to the input's actual range when that differs, so the default0.5fills127onuint8colors. -
int_color(bool, default:False) βIf
True, treat float colors as[0, 255]values; otherwise[0, 1].uint8colors are always treated as[0, 255]regardless of the flag.
Returns:
-
TensorβTensor of the same shape and dtype as
color, filled with the rescaledfill.
Raises:
-
ValueErrorβIf
coloris a float tensor with values above 1 whileint_color=False.
color_grayscale [source] ΒΆ
Convert RGB colors to grayscale using the BT.601 luminance weights.
Parameters:
-
color(Tensor) βColor tensor of shape \((N, 3)\).
-
int_color(bool, default:False) βIf
True, treat colors as[0, 255]ints; otherwise[0, 1]floats.
Returns:
-
TensorβTensor with the same shape and dtype as
color, with R=G=B = luminance.
color_jitter [source] ΒΆ
color_jitter(
color: Tensor,
brightness: Optional[float] = None,
contrast: Optional[float] = None,
saturation: Optional[float] = None,
int_color: bool = False,
) -> Tensor
Apply brightness, contrast, and saturation factors to colors, in that order.
Each factor multiplies its component directly (1.0 is identity); None skips the component entirely.
Parameters:
-
color(Tensor) βColor tensor of shape \((N, 3)\).
-
brightness(Optional[float], default:None) βMultiplicative brightness factor (e.g.
1.2brightens by 20%). -
contrast(Optional[float], default:None) βContrast factor, scaling the deviation from the per-channel mean.
-
saturation(Optional[float], default:None) βSaturation factor, scaling the deviation from the per-point grayscale luminance.
-
int_color(bool, default:False) βIf
True, treat float colors as[0, 255]values; otherwise[0, 1].uint8colors are always treated as[0, 255]regardless of the flag.
Returns:
-
TensorβJittered colors with the same shape and dtype as
color.
Raises:
-
ValueErrorβIf
coloris a float tensor with values above 1 whileint_color=False.
color_shift [source] ΒΆ
Add a per-channel offset to colors, clamped to the valid color range.
Parameters:
-
color(Tensor) βColor tensor of shape \((N, 3)\).
-
shift(Tensor) βPer-channel offset of shape \((3,)\), in the same range as the colors.
-
int_color(bool, default:False) βIf
True, treat float colors as[0, 255]values; otherwise[0, 1].uint8colors are always treated as[0, 255]regardless of the flag.
Returns:
-
TensorβShifted colors with the same shape and dtype as
color.
Raises:
-
ValueErrorβIf
coloris a float tensor with values above 1 whileint_color=False.
flip_boxes [source] ΒΆ
Flip oriented 3D boxes along a spatial axis.
Boxes are stored as \((K, 7)\) rows \([c_x, c_y, c_z, d_x, d_y, d_z, \theta]\) with full extents and heading in radians counterclockwise about \(+z\) from \(+x\). A flip negates the center component along axis. A flip along axis \(0\) (the \(yz\) plane) maps the heading to \(\pi - \theta\); a flip along axis \(1\) (the \(xz\) plane) maps the heading to \(-\theta\). Sizes are unchanged. Boxes with a planar velocity \((v_x, v_y)\) in columns \(7{:}9\) have its axis component negated too; further columns are kept as they are.
Parameters:
-
boxes(Tensor) βBox tensor of shape \((K, 7)\) or \((K, 7 + C)\).
-
axis(int) βCenter axis index to negate (0=X, 1=Y).
Returns:
-
TensorβThe flipped box tensor, same shape as
boxes.
flip_vectors [source] ΒΆ
Flip a packed field of 3D vectors along a spatial axis.
Negates component axis of every contiguous triple of the last dimension, so it handles both a plain \((N, 3)\) field (e.g. coordinates or normals) and a \((N, 3 G)\) field of \(G\) tiled offsets (e.g. vote offsets \((\text{center} - \text{point})\)) alike.
Parameters:
-
x(Tensor) βVector field of shape \((N, 3)\) or \((N, 3 G)\).
-
axis(int) βAxis index within each triple to negate.
Returns:
-
TensorβThe flipped tensor with the same shape as
x.
random_color_jitter [source] ΒΆ
random_color_jitter(
color: Tensor,
brightness: float = 0.0,
contrast: float = 0.0,
saturation: float = 0.0,
int_color: bool = False,
generator: Optional[Generator] = None,
) -> Tensor
Jitter colors by brightness, contrast, and saturation, in that order.
Each strength is a relative delta sampled uniformly from [-x, x] and applied multiplicatively (out = x * factor) via color_jitter.
Parameters:
-
color(Tensor) βColor tensor of shape \((N, 3)\).
-
brightness(float, default:0.0) βMax relative brightness change.
0.2means Β±20%. -
contrast(float, default:0.0) βMax relative contrast change.
-
saturation(float, default:0.0) βMax relative saturation change. Saturation moves toward (or away from) the per-channel grayscale luminance.
-
int_color(bool, default:False) βIf
True, treat float colors as[0, 255]values; otherwise[0, 1].uint8colors are always treated as[0, 255]regardless of the flag. -
generator(Optional[Generator], default:None) βRandom generator for reproducibility.
Returns:
-
TensorβJittered colors with the same shape and dtype as
color.
Raises:
-
ValueErrorβIf
coloris a float tensor with values above 1 whileint_color=False.
random_elastic_distortion [source] ΒΆ
random_elastic_distortion(
pos: Tensor,
granularity: float = 0.2,
magnitude: float = 0.4,
generator: Optional[Generator] = None,
) -> Tensor
Apply a smooth random displacement field to pos.
Implements the elastic distortion recipe common in sparse-voxel indoor segmentation pipelines: sample Gaussian noise on a coarse 3D grid (cells of side granularity), smooth it with two passes of a \(3 \times 3 \times 3\) mean filter, trilinear-interpolate the smoothed displacement at each point, and add it to the position. Net effect is a locally-coherent, low-frequency deformation that preserves nearby-point relationships.
Parameters:
-
pos(Tensor) βInput positions of shape \((N, 3)\).
-
granularity(float, default:0.2) βSize of the noise grid cells (in the same units as
pos). Smaller values give higher-frequency distortion. -
magnitude(float, default:0.4) βStandard deviation of the per-cell Gaussian noise (in the same units as
pos). Larger values give stronger deformation. -
generator(Optional[Generator], default:None) βRandom generator for reproducibility.
Returns:
-
TensorβDistorted positions of shape \((N, 3)\).
random_jitter [source] ΒΆ
random_jitter(
x: Tensor,
sigma: float = 0.01,
clip: Optional[float] = 0.05,
generator: Optional[Generator] = None,
) -> Tensor
Add Gaussian noise to x, optionally clipped.
Parameters:
-
x(Tensor) βInput tensor.
-
sigma(float, default:0.01) βStandard deviation of the Gaussian noise.
-
clip(Optional[float], default:0.05) βIf not
None, clip the noise to[-clip, clip]. -
generator(Optional[Generator], default:None) βRandom generator for reproducibility.
Returns:
-
TensorβJittered tensor with the same shape as
x.
rotate_boxes [source] ΒΆ
Rotate oriented 3D boxes about the up axis.
Box centers are rotated by rotation (centers @ rotation.transpose(-1, -2)) and the heading is incremented by angle, so a counterclockwise rotation about \(+z\) keeps the counterclockwise heading aligned with the jointly rotated points. Sizes are unchanged. Boxes with a planar velocity \((v_x, v_y)\) in columns \(7{:}9\) have it rotated in the plane; further columns are kept as they are.
Parameters:
-
boxes(Tensor) βBox tensor of shape \((K, 7)\) as \([c_x, c_y, c_z, d_x, d_y, d_z, \theta]\), or \((K, 7 + C)\).
-
rotation(Tensor) βA \(3 \times 3\) rotation matrix rotating by
anglecounterclockwise about the \(z\) axis. -
angle(float) βRotation angle in radians, added to the heading.
Returns:
-
TensorβThe rotated box tensor, same shape as
boxes.
scale_boxes [source] ΒΆ
Scale oriented 3D boxes by an isotropic factor.
Both centers and extents (columns \(0\) to \(6\)) are multiplied by scale, and so is a planar velocity \((v_x, v_y)\) in columns \(7{:}9\). Heading and further columns are unchanged.
Parameters:
-
boxes(Tensor) βBox tensor of shape \((K, 7)\) or \((K, 7 + C)\).
-
scale(Union[float, Tensor]) βIsotropic scalar factor applied to centers, sizes and velocity.
Returns:
-
TensorβThe scaled box tensor, same shape as
boxes.
translate_boxes [source] ΒΆ
Translate oriented 3D boxes by a fixed offset.
Centers (columns \(0\) to \(3\)) are offset by translation. Sizes, heading and any further column (such as a velocity) are unchanged.
Parameters:
-
boxes(Tensor) βBox tensor of shape \((K, 7)\) as \([c_x, c_y, c_z, d_x, d_y, d_z, \theta]\), or \((K, 7 + C)\).
-
translation(Tensor) βTranslation vector of shape \((3,)\).
Returns:
-
TensorβThe shifted box tensor, same shape as
boxes.
cut_boxes [source] ΒΆ
cut_boxes(
data: Mapping[str, Any],
keys: KeyCollection = POS,
box_key: str = BOX,
label_key: str = LABEL,
attribute_keys: Optional[KeyCollection] = None,
) -> List[Dict[str, Tensor]]
Cut the annotated objects of a scene out by their boxes, one dict per object.
An object holds the points inside its box under keys, the coordinates relative to the box center under the first key, its box under box_key, its label under label_key and its value of every attribute_keys. A point inside several boxes belongs to each of them. The keys are plain strings, so a list of objects saves with torch.save and loads back with weights_only=True. PasteBoxes pastes such objects into other scenes.
Parameters:
-
data(Mapping[str, Any]) βScene holding the packed points under
keys, the boxes \((K, 7)\) or wider underbox_key, the labels \((K,)\) underlabel_keyand one row per box under each ofattribute_keys. -
keys(KeyCollection, default:POS) βPoint keys cut out with the objects, the coordinates first.
-
box_key(str, default:BOX) βKey of the boxes, whose first seven columns are read.
-
label_key(str, default:LABEL) βKey of the labels.
-
attribute_keys(Optional[KeyCollection], default:None) βPer-box keys cut out with the objects (e.g. a velocity).
Returns:
-
List[Dict[str, Tensor]]βThe objects of the scene, in the order of its boxes.
Example
import torch
import torch_pointcloud.transforms.functional as F
from torch_pointcloud.datasets import KITTI
objects = []
for data in KITTI(root="data"):
objects.extend(F.cut_boxes(data, keys=["pos", "intensity"]))
objects = [obj for obj in objects if len(obj["pos"]) >= 5]
torch.save(objects, "objects.pt")
points_in_oriented_box [source] ΒΆ
Test which points lie inside a single oriented 3D box.
The point offsets relative to the box center are rotated into the box frame by \(-\theta\) about \(+z\), then compared against the half-extents with an axis-aligned bounding-box test. The heading \(\theta\) is in radians counterclockwise about \(+z\). For a box with zero heading this reduces to a plain axis-aligned test.
Parameters:
-
pos(Tensor) βCoordinate tensor of shape \((N, 3)\).
-
box(Tensor) βA single box of shape \((7,)\) as \([c_x, c_y, c_z, h_x, h_y, h_z, \theta]\) with half-extents.
Returns:
-
TensorβA boolean mask of shape \((N,)\) that is
Truefor points inside the box.
axis_min_offset [source] ΒΆ
Per-point offset from a floor reference along a chosen coordinate axis.
For positions of shape \((N, D)\) and an axis \(a \in [0, D)\), returns a tensor of shape \((N, 1)\) whose entries are \(x_{i, a} - r\) where the floor reference \(r\) is either the strict minimum \(\min_j x_{j, a}\) (default) or, when quantile is given, the empirical quantile \(Q_{q}(x_{\cdot, a})\). A small positive quantile (e.g. \(q = 0.0099\)) yields an outlier-robust floor estimate. Useful for extracting "height above the local floor" as a per-point feature.
Parameters:
-
x(Tensor) βInput tensor of shape \((N, D)\).
-
axis(int) βAxis index in the last dimension.
-
quantile(Optional[float], default:None) βOptional quantile \(q \in [0, 1]\) for the floor reference. When
None, the strict per-axis minimum is used (equivalent to \(q = 0\)).
Returns:
-
TensorβTensor of shape \((N, 1)\) with the same dtype as
x. Returns an empty -
Tensorβ\((0, 1)\) tensor when
xis empty.
estimate_normals [source] ΒΆ
estimate_normals(
pos: Tensor,
k: int = 16,
batch: Optional[Tensor] = None,
orient_to_centroid: bool = False,
) -> Tensor
Estimate per-point unit surface normals by local PCA.
For each point the normal is the eigenvector of the smallest eigenvalue of the covariance of its \(k\) nearest neighbors, i.e. the direction of least variance (the local tangent-plane normal).
PCA gives no canonical orientation. By default the sign is the arbitrary-but-deterministic sign returned by torch.linalg.eigh. With orient_to_centroid, each normal is flipped to point towards its cloud's centroid, which approximates the inward-facing orientation of meshes scanned from inside a room (S3DIS, ScanNet) and matters when the consuming model was trained on oriented normals.
Parameters:
-
pos(Tensor) βPoint coordinates of shape \((N, 3)\).
-
k(int, default:16) βNumber of nearest neighbors (the point itself included) used per local PCA. Must not exceed the number of points in the smallest cloud.
-
batch(Optional[Tensor], default:None) βOptional \((N,)\) batch index so neighbors never cross cloud boundaries.
-
orient_to_centroid(bool, default:False) βIf
True, flip each normal to point towards its cloud's centroid.
Returns:
-
TensorβUnit normals of shape \((N, 3)\).
Raises:
-
ValueErrorβIf
poshas fewer thankpoints.
Shape
- Input: \((N, 3)\)
- Output: \((N, 3)\)
quantize [source] ΒΆ
Integer voxel-grid coordinates of every point, without reducing the cloud.
Each point maps to \(\lfloor p / s \rfloor\) shifted so the per-axis minimum is \(0\); points sharing a voxel get equal coordinates and every input row is kept. This is the coordinate a voxel-partition protocol feeds to a sparse model for each raw point (Voxelize(pos_reduce="grid") produces the same coordinates for the one representative it keeps per voxel).
Parameters:
-
pos(Tensor) βPoint positions of shape \((N, D)\).
-
size(float) βVoxel side length in the units of
pos.
Returns:
-
TensorβLong tensor of shape \((N, D)\) (empty input returns an empty \((0, D)\) tensor).
rotate_vectors [source] ΒΆ
Rotate a packed field of 3D vectors by a rotation matrix.
Each contiguous triple of the last dimension rotates as a vector, so it handles both a plain \((N, 3)\) field (e.g. coordinates or normals) and a \((N, 3 G)\) field of \(G\) tiled offsets (e.g. vote offsets) alike.
Parameters:
-
x(Tensor) βVector field of shape \((N, 3)\) or \((N, 3 G)\).
-
rotation(Tensor) βA \(3 \times 3\) rotation matrix.
Returns:
-
TensorβThe rotated tensor with the same shape as
x.
rotation_matrix [source] ΒΆ
\(3 \times 3\) rotation matrix for angle radians around an axis-aligned axis.
Parameters:
-
angle(float) βRotation angle in radians.
-
axis(int, default:2) βAxis index to rotate around (0=X, 1=Y, 2=Z).
-
device(Optional[device], default:None) βOutput device. Defaults to CPU.
Returns:
-
TensorβRotation matrix of shape \((3, 3)\).
Raises:
-
ValueErrorβIf
axisis not in{0, 1, 2}.
shift [source] ΒΆ
shift(
x: Tensor,
method: ShiftMethod,
dim: int = 0,
axes: Optional[Sequence[int]] = None,
) -> Tensor
Subtract a data-driven offset from x.
The offset is computed from x itself along the reduction dimension dim:
method | Offset |
|---|---|
"bbox" | Midrange: (min + max) / 2 |
"centroid" | Mean across the reduced dimension |
"min" | Per-axis minimum (shifts to the positive octant) |
When axes is given, only those axis-indices of the offset are non-zero, so axes not listed are left untouched. This is the composable knob for mixed-method shifts:
import torch
import torch_pointcloud.transforms.functional as F
x = torch.rand(100, 3)
# Center XY at the bbox midpoint and Z at the minimum
x = F.shift(x, method="bbox", axes=[0, 1])
x = F.shift(x, method="min", axes=[2])
The two calls touch disjoint axes, so they commute.
Parameters:
-
x(Tensor) βInput tensor.
-
method(ShiftMethod) βHow the offset is computed. See the table.
-
dim(int, default:0) βThe dimension to reduce over when computing the offset.
-
axes(Optional[Sequence[int]], default:None) βLast-dim axis indices to shift.
None(default) shifts every axis.
Returns:
-
TensorβThe shifted tensor, same shape as
x. Returnsxunchanged when -
Tensorβx.size(dim) == 0.
Raises:
-
ValueErrorβIf
methodis not one of"bbox","centroid","min".
apply_mask [source] ΒΆ
Apply a mask to a tensor.
Parameters:
-
x(Tensor) βThe input tensor.
-
mask(Tensor) βThe mask.
Returns:
-
TensorβThe tensor with the mask applied.
Examples:
bounding_box [source] ΒΆ
Returns the min and max values along a given dimension.
Parameters:
-
x(Tensor) βThe input tensor of shape (..., D, ...).
-
dim(int, default:0) βThe dimension to compute bounds over.
Returns:
-
tuple[float, ...]βA tuple of (*min, *max) values.
box_mask [source] ΒΆ
Create a boolean mask for points inside an axis-aligned bounding box (AABB).
Membership condition along dim (default, boundary points included):
With strict=True the inequalities are strict, so boundary points are excluded.
Parameters:
-
x(Tensor) βThe input tensor of shape \((\ldots, D)\) along
dim. -
bbox(tuple[float, ...]) βAABB as a flat tuple
(*bbmin, *bbmax)of length \(2 \cdot D\); a row longer than \(D\) is tested by its first \(D\) coordinates, so a box row \((c_x, c_y, c_z, \ldots)\) is tested by its center. -
dim(int, default:-1) βThe dimension to compute the mask over.
-
strict(bool, default:False) βIf
True, use strict inequalities (points exactly on the boundary are excluded).
Returns:
-
TensorβThe boolean mask, with
dimreduced.
Raises:
-
ValueErrorβIf
len(bbox)is odd or larger than2 * x.shape[dim].
cube_mask [source] ΒΆ
cube_mask(
x: Tensor,
center: Union[Tensor, Sequence[float], float],
radius: float,
dim: int = -1,
) -> Tensor
Create a boolean mask for points inside an axis-aligned cube (Lβ / Chebyshev ball).
Membership condition along dim:
Geometrically, the Lβ ball of radius \(r\) centered at \(c\) is a hypercube with edge \(2r\) aligned to the axes. Pair with sphere_mask (L2) and box_mask (explicit AABB).
Parameters:
-
x(Tensor) βThe input tensor of shape \((\ldots, D)\) along
dim. -
center(Union[Tensor, Sequence[float], float]) βThe center of the cube, shape \((D,)\) or broadcastable.
-
radius(float) βThe half-edge (radius) of the cube.
-
dim(int, default:-1) βThe dimension to reduce the per-axis comparison over.
Returns:
-
TensorβThe boolean mask, with
dimreduced.
remove_near_origin [source] ΒΆ
Remove points that are within a given radius (L2) of the origin.
Equivalent to inverting sphere_mask(pos, center=0, radius=r) and indexing.
Parameters:
-
pos(Tensor) βThe input tensor of shape \((N, D)\).
-
radius(float, default:0.001) βThe L2 radius (Euclidean distance) below which points are removed.
-
return_mask(bool, default:False) βIf
True, also return the keep-mask.
Returns:
-
AnyβThe filtered tensor; or
(filtered, mask)ifreturn_mask=True.
sphere_mask [source] ΒΆ
sphere_mask(
x: Tensor,
center: Union[Tensor, Sequence[float], float],
radius: float,
dim: int = -1,
) -> Tensor
Create a boolean mask for points inside an L2 (Euclidean) ball.
Membership condition along dim:
Pair with cube_mask (Lβ) and box_mask (explicit AABB).
Parameters:
-
x(Tensor) βThe input tensor of shape \((\ldots, D)\) along
dim. -
center(Union[Tensor, Sequence[float], float]) βThe center of the sphere, shape \((D,)\) or broadcastable.
-
radius(float) βThe radius of the sphere.
-
dim(int, default:-1) βThe dimension to compute the Euclidean norm over.
Returns:
-
TensorβThe boolean mask, with
dimreduced.
laser_mix_masks [source] ΒΆ
laser_mix_masks(
pos: Tensor,
other_pos: Tensor,
num_areas: int,
pitch_range: Tuple[float, float],
generator: Optional[Generator] = None,
) -> Tuple[Tensor, Tensor]
Return keep-masks that swap alternating inclination (pitch) bands between two LiDAR scans.
Each point's inclination is \(\phi = \arctan2(z, \sqrt{x^2 + y^2})\) in degrees. The range pitch_range is split into num_areas equal bands; a random parity picks whether the even or odd bands are kept from the first scan, with the complementary bands kept from the second. The mixed scene is torch.cat([pos[mask], other_pos[other_mask]]), so the two masks tile the sky.
Parameters:
-
pos(Tensor) βCoordinates of the first scan of shape \((N, 3)\).
-
other_pos(Tensor) βCoordinates of the second scan of shape \((M, 3)\).
-
num_areas(int) βNumber of inclination bands to split
pitch_rangeinto. -
pitch_range(Tuple[float, float]) βInclination range
(min, max)in degrees. -
generator(Optional[Generator], default:None) βRandom generator for reproducibility.
Returns:
-
TensorβA tuple
(mask, other_mask)of boolean tensors of shape \((N,)\) and \((M,)\) that select the -
Tensorβpoints kept from
posand fromother_posrespectively.
Shape
pos: \((N, 3)\)other_pos: \((M, 3)\)- output: \((N,)\) and \((M,)\)
Raises:
-
ValueErrorβIf
num_areasis not positive.
Example
import torch
from torch_pointcloud.transforms.functional import laser_mix_masks
pos = torch.randn(100, 3)
other = torch.randn(120, 3)
g = torch.Generator().manual_seed(0)
mask, other_mask = laser_mix_masks(pos, other, num_areas=4, pitch_range=(-25.0, 3.0), generator=g)
mixed = torch.cat([pos[mask], other[other_mask]], dim=0)
polar_mix_masks [source] ΒΆ
polar_mix_masks(
pos: Tensor,
other_pos: Tensor,
generator: Optional[Generator] = None,
) -> Tuple[Tensor, Tensor]
Return keep-masks that swap a random azimuth half-sector between two LiDAR scans.
Each point's azimuth is \(\theta = \arctan2(y, x)\). A random start angle in \([-\pi, \pi)\) defines a half-circle sector \([\theta_0, \theta_0 + \pi)\) that wraps around the \(\pm\pi\) seam, so half of the azimuth range is swapped regardless of the start angle. Points of the first scan outside the sector are kept, and points of the second scan inside the sector are added, so the mixed scene is torch.cat([pos[mask], other_pos[other_mask]]).
Parameters:
-
pos(Tensor) βCoordinates of the first scan of shape \((N, 3)\).
-
other_pos(Tensor) βCoordinates of the second scan of shape \((M, 3)\).
-
generator(Optional[Generator], default:None) βRandom generator for reproducibility.
Returns:
-
TensorβA tuple
(mask, other_mask)of boolean tensors of shape \((N,)\) and \((M,)\) that select the -
Tensorβpoints kept from
posand pasted fromother_posrespectively.
Shape
pos: \((N, 3)\)other_pos: \((M, 3)\)- output: \((N,)\) and \((M,)\)
farthest_point_sample [source] ΒΆ
farthest_point_sample(
pos: Tensor,
num_samples: Optional[int] = None,
ratio: Optional[float] = None,
random_start: bool = False,
) -> Tensor
Farthest-point sampling (FPS) from a tensor of positions.
Thin wrapper around torch_pointcloud.ops.cluster.fps, provided for convenience and naming symmetry with random_sample.
See Also
torch_pointcloud.ops.cluster.fps for more details and advanced usage.
Parameters:
-
pos(Tensor) βThe input tensor of shape \((N, D)\).
-
num_samples(Optional[int], default:None) βThe number of points to sample.
-
ratio(Optional[float], default:None) βThe ratio of points to sample.
-
random_start(bool, default:False) βWhether to start the sampling from a random point.
Returns:
-
TensorβThe indices of the sampled points, always
num_samplesof them whennum_samplesis given. A cloud with at -
Tensorβmost
num_samplespoints keeps its original order instead of being reordered by farthest-point rank, and a -
Tensorβsmaller one is completed by cycling through its points, the repetition
fpsapplies too.ratio >= 1 -
Tensorβreturns
torch.arange(N).
Examples:
random_dropout_mask [source] ΒΆ
random_dropout_mask(
n: int,
drop_ratio: float,
device: Optional[device] = None,
generator: Optional[Generator] = None,
) -> Tensor
Return a boolean keep-mask of length n where each entry is kept with probability 1 - drop_ratio.
Parameters:
-
n(int) βNumber of points.
-
drop_ratio(float) βProbability of dropping a point. Must be in \([0, 1)\).
-
device(Optional[device], default:None) βOutput device.
-
generator(Optional[Generator], default:None) βRandom generator for reproducibility.
Returns:
-
TensorβBoolean tensor of shape \((n,)\).
Raises:
-
ValueErrorβIf
drop_ratiois not in[0, 1).
random_sample [source] ΒΆ
random_sample(
tensor: Tensor,
num_samples: int,
return_indices: bool = False,
replace: bool = False,
generator: Optional[Generator] = None,
) -> Union[Tensor, Tuple[Tensor, Tensor]]
Randomly sample a fixed number of values from a tensor.
Note
The data is sampled uniformly along dim=0.
Parameters:
-
tensor(Tensor) βThe input tensor of shape \((N, \ldots)\).
-
num_samples(int) βThe number of values to sample.
-
return_indices(bool, default:False) βWhether to return the indices of the sampled values.
-
replace(bool, default:False) βIf
True, sample with replacement (duplicates allowed). IfFalse, sample without replacement when \(N \geq \text{num\_samples}\); when \(\text{num\_samples} > N\) the draw falls back to replacement so the output always hasnum_samplesrows. -
generator(Optional[Generator], default:None) βThe generator for the random number generator.
Returns:
-
Union[Tensor, Tuple[Tensor, Tensor]]βIf
return_indicesisTrue, the function returns a tuple of the sampled values and their indices. -
Union[Tensor, Tuple[Tensor, Tensor]]βOtherwise, it returns the sampled values.
Raises:
-
ValueErrorβIf
num_samples > 0and the input is empty.
random_sample_face_vertices [source] ΒΆ
random_sample_face_vertices(
vertices: Tensor,
face: Tensor,
num_samples: int,
return_normals: Literal[True],
generator: Optional[Generator] = None,
) -> Tuple[Tensor, Tensor]
random_sample_face_vertices(
vertices: Tensor,
face: Tensor,
num_samples: int,
return_normals: bool = False,
generator: Optional[Generator] = None,
) -> Union[Tensor, Tuple[Tensor, Tensor]]
Randomly sample a fixed number of vertices from a 3D mesh (vertices, face), using:
Note
The data is sampled uniformly from the mesh.
Parameters:
-
vertices(Tensor) βThe input tensor.
-
face(Tensor) βThe input tensor.
-
num_samples(int) βThe number of vertices to sample.
-
return_normals(bool, default:False) βWhether to return the normal of the sampled vertices.
-
generator(Optional[Generator], default:None) βThe generator for the random number generator.
Returns:
-
Union[Tensor, Tuple[Tensor, Tensor]]βIf
return_normalsisTrue, the function returns a tuple of the sampled vertices and their normal. -
Union[Tensor, Tuple[Tensor, Tensor]]βOtherwise, it returns the sampled vertices.
shuffle_indices [source] ΒΆ
shuffle_indices(
n: int,
device: Optional[device] = None,
generator: Optional[Generator] = None,
) -> Tensor
Return a random permutation of [0, n).
Parameters:
-
n(int) βSequence length.
-
device(Optional[device], default:None) βOutput device.
-
generator(Optional[Generator], default:None) βRandom generator for reproducibility.
Returns:
-
TensorβLong tensor of shape \((n,)\).
maxabs_scale [source] ΒΆ
Scale a tensor by its largest absolute value, per channel: \(x' = x / \max(\max_i |x_i|, \epsilon)\).
The maximum is taken over every dimension but the last (the channel dimension), so the input is treated as one point cloud: scale packed batches per sample (pre-collate), never on concatenated clouds.
Parameters:
-
x(Tensor) βInput tensor. Integer tensors are cast to
float32. -
eps(float, default:1e-07) βLower bound on the divisor to prevent division by zero.
Returns:
-
TensorβThe scaled tensor, same shape as
x, with values in \([-1, 1]\).
minimal_enclosing_ball [source] ΒΆ
Compute the smallest ball enclosing a point set (Welzl's move-to-front algorithm).
The recursion only descends on the support set (at most \(C + 1\) points), so the depth is bounded by the dimension while the point loop stays iterative; points already known to be inside are moved to the front so that later checks succeed early.
Parameters:
-
points(Tensor) βTensor of shape \((N, C)\) with \(N \geq 1\).
Returns:
-
Tuple[Tensor, Tensor]βThe ball center \((C,)\) and its radius (a scalar), in the dtype and on the device of
points.
Shape
- Input: \((N, C)\)
- Output: \((C,)\) and \(()\)
normalize [source] ΒΆ
normalize(
x: Tensor,
mean: Union[Tensor, Sequence[float], float],
std: Union[Tensor, Sequence[float], float],
eps: float = 1e-07,
) -> Tensor
Per-channel standardization: \(x' = (x - \mu) / \max(\sigma, \epsilon)\).
Parameters:
-
x(Tensor) βInput tensor. The last dimension is treated as the channel dim.
-
mean(Union[Tensor, Sequence[float], float]) βPer-channel mean(s). Broadcast against the last dimension.
-
std(Union[Tensor, Sequence[float], float]) βPer-channel standard deviation(s).
-
eps(float, default:1e-07) βLower bound on \(\sigma\) to prevent division by zero.
Returns:
-
TensorβStandardized tensor, same shape as
x.
rescale [source] ΒΆ
Center a point set and rescale it to a unit extent.
Operates along the point dimension dim=-2. Pairs a centering step with a scale-by-extent step that share the same statistics. The scale denominator is a single statistic over all leading dimensions, so the input is treated as one point cloud: rescale packed batches per sample (pre-collate), never on concatenated clouds.
Parameters:
-
points(Tensor) βTensor of shape \((\ldots, N, C)\) with \(C \geq 1\); min/max and means are over \(N\).
-
eps(float, default:1e-06) βSmall constant added to the scale denominator for numerical stability.
-
method(RescaleMethod, default:'centroid') β"centroid": subtract the mean over points, then divide by the max Euclidean distance from the centroid plus \(\epsilon\):
$$ \mathbf{x} \leftarrow \frac{\mathbf{x} - \boldsymbol{\mu}}{\max_i |\mathbf{x}_i - \boldsymbol{\mu}|_2 + \epsilon} $$
"bbox": subtract the axis-aligned bounding-box midpoint (midrange center), then divide by half the longest edge of that box plus \(\epsilon\) (matches common ModelNet-style normalization):
$$ \mathbf{c} = \frac{\mathbf{x}{\min} + \mathbf{x}, \quad r = \frac{1}{2}\max_j (x_{\max,j} - x_{\min,j}) + \epsilon, \quad \mathbf{x} \leftarrow \frac{\mathbf{x} - \mathbf{c}}{r} $$}}{2
"centroid_extent": subtract the centroid then divide by the longest axis-aligned span (the convention used by the published RandLA-Net Toronto-3D / Semantic3D checkpoints):
$$ \mathbf{x} \leftarrow \frac{\mathbf{x} - \boldsymbol{\mu}}{\max_j (x_{\max,j} - x_{\min,j}) + \epsilon} $$
"min_sphere": subtract the center of the minimal enclosing sphere of all points and divide by its radius plus \(\epsilon\) (seeminimal_enclosing_ball; the OctFormer ModelNet40 normalization).
Returns:
-
TensorβNormalized tensor, same shape as
points.
Raises:
-
ValueErrorβIf
methodis not"centroid","bbox","centroid_extent", or"min_sphere".
relabel [source] ΒΆ
relabel(
labels: Tensor,
mapping: Union[Sequence[int], Dict[int, int]],
default: int = 0,
) -> Tensor
Remap integer labels via a lookup table.
mapping can be either:
- a sequence of source values (1:1): each value at index \(i\) is mapped to \(i\);
- a
dict[int, int](general source β target): supports N-to-1 merges (e.g. SemanticKITTI'smoving-carandcarboth β 0).
Source values not listed in mapping are set to default.
Parameters:
-
labels(Tensor) βInteger label tensor (any integer dtype). Output preserves dtype.
-
mapping(Union[Sequence[int], Dict[int, int]]) βSource-value listing (1:1) or explicit
{source: target}dict (N:1). -
default(int, default:0) βValue assigned to source values not listed in
mapping.
Returns:
-
TensorβRemapped tensor with the same shape and dtype as
labels.
Raises:
-
ValueErrorβIf
mappingis empty.
divisible_pad [source] ΒΆ
divisible_pad(
batch: Tensor,
k: int,
mode: PadMode = "all",
pad_fill: PadFill = "cycle",
return_inverse: bool = False,
generator: Optional[Generator] = None,
) -> Union[
Tuple[Tensor, Tensor], Tuple[Tensor, Tensor, Tensor]
]
Pad the batch indices of a tensor to make them divisible by a given integer.
Consider a batch with three samples of sizes 2, 7, and 4, and k=4:
Mode controls which batches get padded (Β· = padded slot):
mode="all" [0 0 Β· Β· | 1 1 1 1 1 1 1 Β· | 2 2 2 2]
2β4 7β8 4 (ok)
mode="below" [0 0 Β· Β· | 1 1 1 1 1 1 1 | 2 2 2 2]
2β4 β 7 (β₯k) 4 (ok)
only <k
mode="above" [0 0 | 1 1 1 1 1 1 1 Β· | 2 2 2 2]
2 7β8 β 4 (ok)
(<k) only β₯k
Pad fill controls how padded slots are filled. Given batch 1 with 7 elements (A B C D E F G) and k=4:
Original patches: [A B C D] [E F G Β·]
patchβ patchβ (incomplete)
pad_fill="cycle" β [A B C D] [E F G A]
Cycles from the start β wraps to A
pad_fill="replicate" β [A B C D] [E F G D]
Copies from previous patch β same position as D
at same offset
pad_fill="random" β [A B C D] [E F G ?]
Random sample from the batch β uniform over {A..G}
When batch_size < k there is no previous patch, so "replicate" falls back to "cycle":
batch 0 (size 2, k=4): [A B Β· Β·]
pad_fill="cycle" β [A B A B]
pad_fill="replicate" β [A B A B] (same, no prior patch)
pad_fill="random" β [A B ? ?]
Parameters:
-
batch(Tensor) βThe batch indices of the tensor. Rows of the same batch must be contiguous (grouped, as produced by packed-batch collation); the batch values themselves may be non-consecutive. Interleaved orderings (e.g.
[0, 1, 0, 1]) are not supported and silently mix samples. -
k(int) βThe integer to make the batch indices divisible by.
-
mode(PadMode, default:'all') βThe mode to use for padding. -
"below": Pad only batches with fewer thankelements. -"above": Pad only batches withkor more elements. -"all": Pad all batches to be divisible byk. -
pad_fill(PadFill, default:'cycle') βStrategy for filling padding slots. -
"cycle": Cycle through original indices from the start of the batch (indices[0], indices[1], ...). -"replicate": Copy indices from the previous patch at the same relative offset. When the last group ofkelements is incomplete, the missing positions are filled with the corresponding positions from the preceding full group. Falls back to"cycle"when there is no preceding group (i.e. the batch has fewer thankelements). -"random": Sample padded indices uniformly with replacement from within the batch's original indices. Consumesgeneratorif given. -
return_inverse(bool, default:False) βWhether to return the inverse of the padded indices.
-
generator(Optional[Generator], default:None) βOptional
torch.Generatorfor reproducibility (used only bypad_fill="random").
Returns:
-
Union[Tuple[Tensor, Tensor], Tuple[Tensor, Tensor, Tensor]]βReturns a tuple of
(indices, padded_batch). -
Union[Tuple[Tensor, Tensor], Tuple[Tensor, Tensor, Tensor]]βIf
return_inverseisTrue, returns(indices, inverse_indices, padded_batch).