Skip to content

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

python
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),
)
API Reference
Full parameter and return type documentation for register_point_clouds_using_centroid_translation.
View Reference →

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

python
"""
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:

bash
cd telekinesis-examples
python examples/point_cloud/register_point_clouds_using_centroid_translation.py

Parameter Configuration

KeyTypeDefaultDescription
source_point_clouddatatypes.PointCloudrequiredThe point cloud to align; its centroid is moved to match target_point_cloud's.
target_point_clouddatatypes.PointCloudrequiredThe point cloud to align to.
initial_transformation_matrixdatatypes.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

TypeDescription
datatypes.Mat4x4The 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

ExceptionCondition
TypeErrorA parameter's value does not match its expected type (see the Parameter Configuration table above)
ValueErrorinitial_transformation_matrix is not shape (4, 4), or (for a list input) contains a non-numeric element
ConfigurationErrorThe TELEKINESIS_API_KEY environment variable is not set
SerializationErrorThe request input failed to serialize, or the response failed to deserialize
RequestTimeoutErrorThe request to the Vitreous service timed out
TransportErrorA network failure occurred before a response was received
ClientErrorThe Vitreous service rejected the request due to invalid input, invalid data, or another unexpected 4xx response
AuthenticationErrorThe API key was rejected as invalid or expired
AuthenticationServiceErrorThe authentication service was unavailable
ServerErrorThe 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_cloud before 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

Skillvs. Register Point Clouds Using Centroid Translation
register_point_clouds_using_cuboid_translation_sampler_icpAlso 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_icpSolves 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_centroidComputes 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_icp rather 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.