Skip to content

Estimate Principal Axes

SUMMARY

Estimate Principal Axes computes the three principal axes (dominant orientations) of an entire 3D point cloud.

It analyzes every point in the cloud at once, using either the oriented bounding box ("obb") or principal component analysis ("pca") method, and returns the three mutually orthogonal axes of maximum variance, ordered by how much of the point cloud's spread each one explains. Compare with estimate_principal_axis_within_radius, which estimates a single local direction near one reference point instead of the whole cloud's global orientation.

Use this Skill when you want to determine an object's overall 3D orientation for tasks like grasp planning, pose estimation, or gripper alignment.

The Skill

python
from telekinesis import vitreous

principal_axes = vitreous.estimate_principal_axes(
    point_cloud=point_cloud,
    method="obb",
)
API Reference
Full parameter and return type documentation for estimate_principal_axes.
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.

Example

Raw Sensor Input

Unprocessed point cloud captured directly from the sensor. Shows full resolution, natural noise, and uneven sampling density.

Calculated Highest Principal Axis

Point cloud with calculated highest principal axis shown in red

The Code

python
"""
Demonstrates computing the principal axes of a point cloud using PCA.
"""

from loguru import logger
import rerun as rr

from telekinesis import vitreous, datatypes


def estimate_principal_axes_example():
    """
    Computes the principal axes of a point cloud using PCA.

    Finds the orthogonal axes along which the point cloud has maximum variance.
    """
    # ===================== Load Data ==========================================
    point_cloud_url = "https://assets.telekinesis.ai/examples/v1/point_clouds/zivid_large_pcb_inspection_cropped_preprocessed.ply"
    point_cloud = datatypes.PointCloud.from_url(url=point_cloud_url, use_cache=True)

    # ===================== Run Skill ==========================================
    principal_axes = vitreous.estimate_principal_axes(
        point_cloud=point_cloud,
        method="obb",
    )

    # ===================== Log ================================================
    logger.success(f"Estimated principal axes for {point_cloud}")
    logger.success(f"Results: {principal_axes}")
    logger.info(
        f"Principal axes data (columns are the principal axis vectors): {principal_axes.data}"
    )
    logger.info(f"Principal axes shape: {principal_axes.shape}")
    logger.info(f"Principal axes dtype: {principal_axes.dtype}")
    logger.info(
        f"Principal axes columns are orthonormal: {principal_axes.is_orthonormal()}"
    )

    # ===================== Visualization  (Optional) ===========================
    rr.init("estimate_principal_axes_example", spawn=True)
    datatypes.visualize(point_cloud, entity_path="/1-point_cloud")
    datatypes.visualize(principal_axes, entity_path="/2-principal_axes")


if __name__ == "__main__":
    estimate_principal_axes_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/estimate_principal_axes.py

Parameter Configuration

KeyTypeDefaultDescription
point_clouddatatypes.PointCloudrequiredThe point cloud to analyze; all points contribute to the estimate
methoddatatypes.String | str"obb"Estimation method: "obb" (oriented bounding box, more robust to outliers) or "pca" (principal component analysis, faster but more sensitive to outliers)

Returns

TypeDescription
datatypes.EigenVectorsA (3, 3) array whose columns are the three principal axes, ordered by how much variance each explains. .data[:, 0] is the dominant axis, .data[:, 1] the second, .data[:, 2] the third — each already a unit vector, and mutually orthogonal. Use .data for the raw array and .is_orthonormal() to confirm that orthogonality.

Raises

ExceptionCondition
TypeErrorA parameter's value does not match its expected type (see the Parameter Configuration table above)
ValueErrormethod is not "obb" or "pca"
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

The estimate_principal_axes Skill exposes a single tunable parameter, which selects the estimation method.

method

  • Controls: Which algorithm derives the three principal axes from the point cloud.
  • Units: N/A — must be exactly one of two literal strings
  • Default: "obb"
  • Options:
    • "obb" — derives the axes from the point cloud's oriented bounding box; tends to be more robust to outliers. Use for noisy, real-world captures.
    • "pca" — derives the axes directly via principal component analysis of the point positions; faster, but more sensitive to outliers than "obb". Use for speed on already-clean data.
  • Any value other than "obb" or "pca" raises a ValueError.

TIP

Use "obb" for most real-world scenes where the point cloud may contain noise or outliers. Reach for "pca" only once the data is already clean and you need the extra speed.

Where to Use the Skill

Common pipelines include:

  • Grasp planning – align a gripper with an object's dominant axis before a pick
  • Pose estimation – recover an object's 3D orientation from a segmented cluster
  • Bin picking – orient a tool consistently across differently-rotated instances of the same part
  • Packaging and placement – align an object to a target orientation before placing it

Alternative Skills

Skillvs. Estimate Principal Axes
estimate_principal_axis_within_radiusEstimates the dominant direction of a local neighborhood around one reference point instead of the whole cloud. Use it when only part of the object — an edge, rod, or other local feature — matters.
calculate_oriented_bounding_boxAlso returns orientation, but bundled with size/extent information. Use it when you need the box's dimensions as well as its axes.

When Not to Use the Skill

Do not use Estimate Principal Axes when:

  • You only care about one local feature — this Skill analyzes the whole cloud; use estimate_principal_axis_within_radius for a neighborhood around a single reference point instead
  • You also need size or extent, not just orientation — use calculate_oriented_bounding_box instead
  • The point cloud has no clear dominant direction (e.g. a roughly spherical or uniformly-distributed cluster) — the returned axes are still orthonormal, but not meaningful for alignment
  • method isn't exactly "obb" or "pca" — any other string raises a ValueError

TIP

If results look unstable between runs on similar objects, the point cloud may be too symmetric or noisy for a well-defined dominant axis — try method="obb" first, or remove outliers before estimating.