Register Point Clouds Using Centroid Translation
SUMMARY
Register Point Clouds Using Centroid Translation computes a coarse alignment that matches two point clouds' centroids.
It finds the translation that moves source_point_cloud's centroid onto target_point_cloud's centroid — the simplest possible registration, with no rotation or scaling. It returns the transform itself, not an already-transformed point cloud; apply it separately with apply_transform_to_point_cloud. Commonly used as a fast first step before a more precise registration Skill such as register_point_clouds_using_point_to_point_icp.
Use this Skill when you want a fast, translation-only initial alignment between two point clouds before running a finer registration step.
The Skill
from telekinesis import vitreous
import numpy as np
transformation_matrix = vitreous.register_point_clouds_using_centroid_translation(
source_point_cloud=source_point_cloud,
target_point_cloud=target_point_cloud,
initial_transformation_matrix=np.eye(4),
)Data Transfer Notice
There is no longer a fixed limit of 1 million points per request. However, very large datasets may result in slower data transfer and processing times. We are continuously optimizing performance as part of our beta program, with ongoing improvements to enhance speed and reliability.
The Code
"""
Demonstrates aligning point clouds by matching their centroids (coarse alignment).
"""
import numpy as np
from loguru import logger
import rerun as rr
from telekinesis import vitreous, datatypes
def register_point_clouds_using_centroid_translation_example():
"""
Aligns point clouds by matching their centroids (coarse alignment).
Computes a translation that moves the source cloud's center to the target cloud's
center. Fast initial alignment step before fine registration.
"""
# ===================== Load Data ==========================================
source_point_cloud_url = "https://assets.telekinesis.ai/examples/v1/point_clouds/zivid_manufacturing_workpieces.ply"
target_point_cloud_url = "https://assets.telekinesis.ai/examples/v1/point_clouds/zivid_manufacturing_workpieces_centered.ply"
source_point_cloud = datatypes.PointCloud.from_url(
url=source_point_cloud_url, use_cache=True
)
target_point_cloud = datatypes.PointCloud.from_url(
url=target_point_cloud_url, use_cache=True
)
# ===================== Run Skill ==========================================
transformation_matrix = vitreous.register_point_clouds_using_centroid_translation(
source_point_cloud=source_point_cloud,
target_point_cloud=target_point_cloud,
initial_transformation_matrix=np.eye(4),
)
# ===================== Log ================================================
logger.success(
f"Registered {source_point_cloud} to {target_point_cloud} using centroid translation"
)
logger.success(f"Results: {transformation_matrix}")
logger.info(f"Transformation matrix data: {transformation_matrix.data}")
logger.info(f"Transformation matrix shape: {transformation_matrix.shape}")
logger.info(f"Transformation matrix ndim: {transformation_matrix.ndim}")
logger.info(f"Transformation matrix dtype: {transformation_matrix.dtype}")
# ===================== Visualization (Optional) ===========================
aligned_source_point_cloud = vitreous.apply_transform_to_point_cloud(
point_cloud=source_point_cloud,
transformation_matrix=transformation_matrix,
)
rr.init("register_point_clouds_using_centroid_translation_example", spawn=True)
datatypes.visualize(source_point_cloud, entity_path="/1-before_registration_source")
datatypes.visualize(target_point_cloud, entity_path="/2-before_registration_target")
datatypes.visualize(
aligned_source_point_cloud, entity_path="/3-after_registration_source_aligned"
)
if __name__ == "__main__":
register_point_clouds_using_centroid_translation_example()Runnable examples are available in the Telekinesis examples repository.
Follow the README in that repository to set up the environment, run this specific example with:
cd telekinesis-examples
python examples/point_cloud/register_point_clouds_using_centroid_translation.pyParameter Configuration
| Key | Type | Default | Description |
|---|---|---|---|
source_point_cloud | datatypes.PointCloud | required | The point cloud to align; its centroid is moved to match target_point_cloud's. |
target_point_cloud | datatypes.PointCloud | required | The point cloud to align to. |
initial_transformation_matrix | datatypes.Mat4x4 | np.ndarray | list[list[float]] | np.eye(4) | A 4x4 transform applied to source_point_cloud before computing centroids, e.g. if you already have a rough alignment. |
Returns
| Type | Description |
|---|---|
datatypes.Mat4x4 | The 4x4 transform that translates source_point_cloud onto target_point_cloud's centroid. Not an already-transformed point cloud — apply it with apply_transform_to_point_cloud. |
Raises
| Exception | Condition |
|---|---|
TypeError | A parameter's value does not match its expected type (see the Parameter Configuration table above) |
ValueError | initial_transformation_matrix is not shape (4, 4), or (for a list input) contains a non-numeric element |
ConfigurationError | The TELEKINESIS_API_KEY environment variable is not set |
SerializationError | The request input failed to serialize, or the response failed to deserialize |
RequestTimeoutError | The request to the Vitreous service timed out |
TransportError | A network failure occurred before a response was received |
ClientError | The Vitreous service rejected the request due to invalid input, invalid data, or another unexpected 4xx response |
AuthenticationError | The API key was rejected as invalid or expired |
AuthenticationServiceError | The authentication service was unavailable |
ServerError | The Vitreous service returned a 5xx or otherwise unexpected error response |
How to Tune the Parameters
register_point_clouds_using_centroid_translation has a single real input to consider — there's no fitness score, iteration budget, or search range to sweep; the centroid difference is computed directly and deterministically.
initial_transformation_matrix
- Controls: A pre-transform applied to
source_point_cloudbefore its centroid is computed, e.g. to fold in an already-known rough rotation. - Default:
np.eye(4)(identity — no pre-transform) - Leave at the identity for a standard, from-scratch centroid alignment; supply a prior estimate here if you already have one and want the centroid step to build on it rather than start over
TIP
This Skill only aligns positions — it has no concept of rotation. If your point clouds are also rotated relative to each other, follow this with a rotation-aware Skill such as register_point_clouds_using_rotation_sampler_icp or register_point_clouds_using_point_to_point_icp.
Where to Use the Skill
Common pipelines include:
- Fast coarse initialization – getting two point clouds roughly aligned in position before running a slower, more precise ICP-based registration Skill
- Multi-scan stitching – roughly centering successive scans of the same object before fine alignment
- Sanity-checking alignment – quickly checking how far apart two point clouds' centers are before investing in a full registration pipeline
Alternative Skills
| Skill | vs. Register Point Clouds Using Centroid Translation |
|---|---|
| register_point_clouds_using_cuboid_translation_sampler_icp | Also translation-only, but searches a range of candidate translations and scores each with ICP fitness instead of a single deterministic centroid computation — slower, but more robust when centroids alone aren't a good proxy for alignment (e.g. partial overlap). |
| register_point_clouds_using_point_to_point_icp | Solves for a full rotation + translation (and needs a reasonable initial alignment to converge) — a natural next step after this Skill's coarse translation estimate. |
| calculate_point_cloud_centroid | Computes a single point cloud's centroid directly, without registering it against another cloud. |
When Not to Use the Skill
Do not use Register Point Clouds Using Centroid Translation when:
- The point clouds are also rotated relative to each other – this Skill only computes a translation; follow it with a rotation-aware registration Skill
- The point clouds only partially overlap – centroids of non-overlapping regions can differ substantially even when the shared region is well-aligned, making the centroid a poor alignment proxy
- You need a final, precise alignment – this is a coarse initialization step; use it to seed a Skill like
register_point_clouds_using_point_to_point_icprather than as a final result
TIP
Because this Skill has no fitness score or convergence check, it always returns a result — even a poor one. Visually inspect the aligned point cloud (or compute a fitness metric yourself) before trusting the output, especially for partially-overlapping scans.

