Skip to content

Register Point Clouds Using Rotation Sampler ICP

SUMMARY

Register Point Clouds Using Rotation Sampler ICP aligns two point clouds by trying multiple initial orientations sampled uniformly on a sphere and running ICP from each orientation to find the best alignment.

This Skill is useful in industrial, mobile, and humanoid robotics pipelines for 6D pose estimation when the object’s initial rotation is unknown. For instance, it can align parts in manufacturing when their orientation on a conveyor is arbitrary, register LIDAR scans with uncertain initial rotation for mobile robots, or orient objects correctly for humanoid robot manipulation. Sampling multiple rotations increases robustness to poor initial guesses.

Use this Skill when you want to perform ICP registration robust to unknown initial rotations for precise alignment.

The Skill

python
from telekinesis import vitreous
import numpy as np

registered_point_cloud = vitreous.register_point_clouds_using_rotation_sampler_icp(
    source_point_cloud=source_point_cloud,
    target_point_cloud=target_point_cloud,
    initial_transformation_matrix=np.eye(4),
    x_step_size_deg=20,
    y_step_size_deg=20,
    z_step_size_deg=20,
    x_min_deg=0,
    x_max_deg=180,
    y_min_deg=0,
    y_max_deg=180,
    z_min_deg=0,
    z_max_deg=180,
    early_stop_fitness_score=0.5,
    min_fitness_score=0.9,
    max_iterations=50,
    max_correspondence_distance=0.02,
    estimate_scaling=False,
)

API Reference

Performance Note

Current Data Limits: The system currently supports up to 1 million points per request (approximately 16MB of data). We're actively optimizing data transfer performance as part of our beta program, with improvements rolling out regularly to enhance processing speed.

Example

Source and Target Point Clouds

Raw sensor input i.e. target point cloud in green and object model in red

Registered Point Clouds

Registered source point cloud (red) aligned to target point cloud (green) using rotation sampler ICP with multiple orientation initializations

The Code

python
from telekinesis import vitreous
from datatypes import datatypes, io
import pathlib
import numpy as np

# Optional for logging
from loguru import logger

DATA_DIR = pathlib.Path("path/to/telekinesis-data")

# Load point clouds
source_filepath = str(DATA_DIR / "point_clouds" / "zivid_bottle_segmented.ply")
target_filepath = str(DATA_DIR / "point_clouds" / "zivid_bottle_cylinder_centered.ply")
source_point_cloud = io.load_point_cloud(filepath=source_filepath)
target_point_cloud = io.load_point_cloud(filepath=target_filepath)
logger.success(f"Loaded source point cloud with {len(source_point_cloud.positions)} points")
logger.success(f"Loaded target point cloud with {len(target_point_cloud.positions)} points")

# Execute operation
registered_point_cloud = vitreous.register_point_clouds_using_rotation_sampler_icp(
  source_point_cloud=source_point_cloud,
  target_point_cloud=target_point_cloud,
  initial_transformation_matrix=np.eye(4),
  x_step_size_deg=20,
  y_step_size_deg=20,
  z_step_size_deg=20,
  x_min_deg=0,
  x_max_deg=180,
  y_min_deg=0,
  y_max_deg=180,
  z_min_deg=0,
  z_max_deg=180,
  early_stop_fitness_score=0.5,
  min_fitness_score=0.9,
  max_iterations=50,
  max_correspondence_distance=0.02,
  estimate_scaling=False,
)
logger.success("Registered point clouds using rotation sampler ICP")

Running the Example

Runnable examples are available in the Telekinesis examples repository. Follow the README in that repository to set up the environment. Once set up, you can run this specific example with:

bash
cd telekinesis-examples
python examples/vitreous_examples.py --example register_point_clouds_using_rotation_sampler_icp

The Explanation of the Code

The script starts by importing the necessary modules for point cloud processing (vitreous), data management (datatypes, io), file handling (pathlib), numerical computations (numpy), and optional logging (loguru).

python
from telekinesis import vitreous
from datatypes import datatypes, io
import pathlib
import numpy as np

# Optional for logging
from loguru import logger

Next, the source and target point clouds are loaded from disk. Logging statements confirm successful loading and display the number of points in each cloud, providing insight into the data size and density before registration.

python

DATA_DIR = pathlib.Path("path/to/telekinesis-data")

# Load point clouds
source_filepath = str(DATA_DIR / "point_clouds" / "zivid_bottle_segmented.ply")
target_filepath = str(DATA_DIR / "point_clouds" / "zivid_bottle_cylinder_centered.ply")
source_point_cloud = io.load_point_cloud(filepath=source_filepath)
target_point_cloud = io.load_point_cloud(filepath=target_filepath)
logger.success(f"Loaded source point cloud with {len(source_point_cloud.positions)} points")
logger.success(f"Loaded target point cloud with {len(target_point_cloud.positions)} points")

The main operation applies the register_point_clouds_using_rotation_sampler_icp Skill. This method performs ICP registration with multiple initial orientations sampled on a rotation grid, iterating over various Euler angle rotations along the X, Y, and Z axes to find the best initial alignment. Key parameters include:

  • x_step_size_deg, y_step_size_deg, z_step_size_deg: define the angular increments for rotation sampling along each axis. Smaller values yield finer sampling but increase computation time.
  • x_min_deg, x_max_deg, y_min_deg, y_max_deg, z_min_deg, z_max_deg: define the rotation range along each axis, allowing control over the orientation search space.
  • early_stop_fitness_score and min_fitness_score: thresholds to determine when to stop sampling early or consider a registration successful.
  • max_iterations and max_correspondence_distance: control the ICP refinement process.
  • estimate_scaling: whether to allow scaling during alignment.
  • initial_transformation_matrix: starting transformation for ICP.
python

# Execute operation
registered_point_cloud = vitreous.register_point_clouds_using_rotation_sampler_icp(
  source_point_cloud=source_point_cloud,
  target_point_cloud=target_point_cloud,
  initial_transformation_matrix=np.eye(4),
  x_step_size_deg=20,
  y_step_size_deg=20,
  z_step_size_deg=20,
  x_min_deg=0,
  x_max_deg=180,
  y_min_deg=0,
  y_max_deg=180,
  z_min_deg=0,
  z_max_deg=180,
  early_stop_fitness_score=0.5,
  min_fitness_score=0.9,
  max_iterations=50,
  max_correspondence_distance=0.02,
  estimate_scaling=False,
)
logger.success("Registered point clouds using rotation sampler ICP")

This Skill is useful in industrial robotics and perception pipelines where objects may be arbitrarily oriented. By sampling multiple rotations, it increases the likelihood of finding the correct initial alignment, which can then be refined with standard ICP.

How to Tune the Parameters

The register_point_clouds_using_rotation_sampler_icp Skill has many parameters that control the rotation search and ICP refinement:

x_step_size_deg, y_step_size_deg, z_step_size_deg (default: 20):

  • Step size for rotation sampling along each axis in degrees
  • Increase (20-45) to create a coarser search (fewer samples, faster) but may miss optimal rotation
  • Decrease (5-10) to create finer search (more samples, slower)
  • Typical range: 5-45 degrees
  • Use 5-10 for fine search, 10-20 for balanced, 20-45 for coarse

x_min_deg, x_max_deg, y_min_deg, y_max_deg, z_min_deg, z_max_deg (defaults: 0 to 180):

  • Define the rotation range along each axis in degrees
  • Increase range (0-360) to search over full rotation space
  • Decrease range (0-180) to focus search in a smaller region (faster)
  • Typical range: 0-360 degrees
  • Use 0-180 for half-sphere, 0-360 for full rotation

early_stop_fitness_score (default: 0.5):

  • Fitness score threshold (0-1) for early stopping during search
  • Increase (0.5-0.7) to require better alignments before stopping (slower but potentially better results)
  • Decrease (0.3-0.5) to stop earlier (faster) but may accept suboptimal alignments
  • Should be set higher than min_fitness_score to ensure early-stopped results are acceptable
  • Typical range: 0.3-0.7

min_fitness_score (default: 0.9):

  • Minimum fitness score (0-1) required to accept the final result
  • Increase (0.95-0.99) to require better alignment quality
  • Decrease (0.7-0.85) to accept lower quality alignments
  • Typical range: 0.7-0.99

max_iterations (default: 50):

  • The maximum number of ICP iterations per rotation sample
  • Increase (50-200) to allow more refinement but is slower
  • Decrease (10-30) for faster computation
  • Typical range: 10-200

max_correspondence_distance (default: 0.02):

  • The maximum distance to consider points as correspondences
  • Units: Uses the same units as your point cloud
  • Increase to allow matching more distant points but may include incorrect matches
  • Decrease to require closer matches
  • Should be 2-5x point spacing
  • Typical range: 0.01-0.1 in point cloud units

estimate_scaling (default: False):

  • Whether to estimate and apply uniform scaling between point clouds
  • True: Allows the algorithm to find scale differences
  • False: Assumes same scale
  • Set to True if point clouds may have different scales, False for same-scale alignment

TIP

Best practice: Start with default values and adjust the rotation ranges based on your expected rotation uncertainty. Adjust step sizes based on the precision you need. Use register_point_clouds_using_centroid_translation first for coarse translation alignment, then use this for rotation search.

Where to Use the Skill in a Pipeline

Rotation sampler ICP is commonly used in the following pipelines:

  • 6D pose estimation with uncertain rotation
  • Object alignment with unknown orientation
  • Part inspection and quality control
  • Multi-view registration

A typical pipeline for pose estimation with unknown rotation looks as follows:

python
# Example pipeline using rotation sampler ICP (parameters omitted).

from telekinesis import vitreous
import numpy as np

# 1. Load point clouds
source_point_cloud = vitreous.load_point_cloud(...)  # Object model
target_point_cloud = vitreous.load_point_cloud(...)  # Scene scan

# 2. Preprocess both point clouds
filtered_source = vitreous.filter_point_cloud_using_statistical_outlier_removal(...)
filtered_target = vitreous.filter_point_cloud_using_statistical_outlier_removal(...)
downsampled_source = vitreous.filter_point_cloud_using_voxel_downsampling(...)
downsampled_target = vitreous.filter_point_cloud_using_voxel_downsampling(...)

# 3. Optional: Coarse alignment using centroid translation
coarse_aligned = vitreous.register_point_clouds_using_centroid_translation(
    source_point_cloud=downsampled_source,
    target_point_cloud=downsampled_target,
)

# 4. Fine alignment using rotation sampler ICP
registered_cloud = vitreous.register_point_clouds_using_rotation_sampler_icp(
    source_point_cloud=downsampled_source,
    target_point_cloud=downsampled_target,
    initial_transformation_matrix=np.eye(4),
    x_step_size_deg=20,
    y_step_size_deg=20,
    z_step_size_deg=20,
    x_min_deg=0,
    x_max_deg=180,
    y_min_deg=0,
    y_max_deg=180,
    z_min_deg=0,
    z_max_deg=180,
    early_stop_fitness_score=0.5,
    min_fitness_score=0.9,
    max_iterations=50,
    max_correspondence_distance=0.02,
    estimate_scaling=False,
)

# 5. Use registered point cloud for pose estimation or analysis

Related skills to build such a pipeline:

  • register_point_clouds_using_centroid_translation: coarse translation alignment before rotation search
  • register_point_clouds_using_cuboid_translation_sampler_icp: alternative for translation uncertainty
  • register_point_clouds_using_point_to_point_icp: simpler ICP without rotation sampling
  • filter_point_cloud_using_statistical_outlier_removal: clean input before registration
  • filter_point_cloud_using_voxel_downsampling: reduce point cloud density for faster processing

Alternative Skills

Skillvs. Rotation Sampler ICP
register_point_clouds_using_point_to_point_icpUse point-to-point ICP when initial rotation is known. Use rotation sampler ICP when rotation is uncertain.
register_point_clouds_using_cuboid_translation_sampler_icpUse cuboid translation sampler when translation is uncertain. Use rotation sampler when rotation is uncertain.
register_point_clouds_using_fast_global_registrationUse FGR for feature-based initial alignment. Use rotation sampler ICP for rotation search with ICP refinement.

When Not to Use the Skill

Do not use rotation sampler ICP when:

  • Initial rotation is already known (use register_point_clouds_using_point_to_point_icp instead)
  • Only translation is uncertain (use register_point_clouds_using_cuboid_translation_sampler_icp instead)
  • You need fast registration (this method is slower due to multiple ICP runs)
  • Rotation uncertainty is very large (the search space may be too large to sample effectively)
  • Point clouds are very different in scale (set estimate_scaling=True or pre-scale the clouds)