Skip to content

Calculate Oriented Bounding Box

SUMMARY

Calculate Oriented Bounding Box computes the bounding box of a point cloud while letting the box itself rotate to fit the points more tightly than an axis-aligned box would.

It searches for a box whose orientation better matches the object's own shape than the world's X/Y/Z axes, optionally minimizing the box's volume for the tightest possible fit and optionally using a fitting method that is less sensitive to outlier points.

Use this Skill when you need a compact, orientation-aware description of a point cloud's shape, for example ahead of grasp planning or pose estimation.

The Skill

python
from telekinesis import vitreous

bounding_box = vitreous.calculate_oriented_bounding_box(
    point_cloud=point_cloud,
    minimize_bbox_volume=True,
    use_robust_fitting=True,
)
API Reference
Full parameter and return type documentation for calculate_oriented_bounding_box.
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

Note: For Bounding Box comparison look at Calculate Axis Aligned Oriented Bounding Box .

Raw Sensor Input

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

Calculated Oriented Bounding Box

Point cloud with oriented bounding box

The Code

python
"""
Demonstrates computing the oriented bounding box (OBB) of a point cloud.
"""

from loguru import logger
import rerun as rr

from telekinesis import vitreous, datatypes


def calculate_oriented_bounding_box_example():
    """
    Computes the oriented bounding box (OBB) of a point cloud.

    Finds the smallest box (in any orientation) that contains all points.
    """
    # ===================== Load Data ==========================================
    point_cloud_url = "https://assets.telekinesis.ai/examples/v1/point_clouds/can_vertical_1_raw_obb_preprocessed.ply"
    point_cloud = datatypes.PointCloud.from_url(url=point_cloud_url, use_cache=True)

    # ===================== Run Skill ==========================================
    oriented_bounding_box = vitreous.calculate_oriented_bounding_box(
        point_cloud=point_cloud,
        minimize_bbox_volume=True,
        use_robust_fitting=True,
    )

    # ===================== Log =================================================
    logger.success(f"Calculated oriented bounding box for {point_cloud}")
    logger.success(f"Results: {oriented_bounding_box}")
    logger.info(f"Oriented bounding box data: {oriented_bounding_box.data}")
    logger.info(f"Oriented bounding box shape: {oriented_bounding_box.shape}")
    logger.info(f"Oriented bounding box center: {oriented_bounding_box.center}")
    logger.info(
        f"Oriented bounding box size (height, width, depth): "
        f"{oriented_bounding_box.height}, "
        f"{oriented_bounding_box.width}, "
        f"{oriented_bounding_box.depth}"
    )
    logger.info(f"Oriented bounding box volume: {oriented_bounding_box.volume}")

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


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

Parameter Configuration

KeyTypeDefaultDescription
point_clouddatatypes.PointCloudrequiredThe point cloud to bound. Only positions are used; normals/colors are ignored.
minimize_bbox_volumedatatypes.Bool | boolTrueWhether to search for the box with the smallest possible volume that still contains every point. True gives the tightest fit but costs more compute; False uses a faster, less exhaustive method that may return a looser box.
use_robust_fittingdatatypes.Bool | boolTrueWhether to fit the box in a way that's less sensitive to outlier points. True lets a few stray points (e.g. sensor noise) have less influence on the box; False weighs every point equally, so a handful of outliers can skew/enlarge the box.

Returns

TypeDescription
datatypes.Box3DThe bounding box [min_x, min_y, min_z, width, height, depth] (the box's minimum corner plus its size along each axis, in meters), oriented to fit the point cloud. Use .data for the raw (6,) array, .center for the box center [cx, cy, cz], .width/.height/.depth for its per-axis size, and .volume for width * height * depth (cubic meters).

Raises

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

calculate_oriented_bounding_box exposes two boolean parameters that trade fit quality and robustness against compute cost.

minimize_bbox_volume

  • Controls: Whether the search looks for the box with the smallest possible volume that still contains every point, versus a faster, less exhaustive fit.
  • Units: Boolean (no units)
  • Default: True
  • True tightest fit; use for accurate measurements (e.g. grasp planning, dimensional checks)
  • False faster, less exhaustive fit; use when speed matters more than the absolute tightest box

use_robust_fitting

  • Controls: Whether the fit is less sensitive to outlier points. True lets a few stray points (e.g. sensor noise) have less influence on the box; False weighs every point equally.
  • Units: Boolean (no units)
  • Default: True
  • True more stable box on noisy real-world scans, since a handful of outliers won't skew or enlarge it
  • False use only on already-clean data, where every point should count equally toward the fit

TIP

For most use cases, keep both parameters at their defaults (True). Only set minimize_bbox_volume=False if you need faster computation and can accept a slightly looser fit; only set use_robust_fitting=False if you're confident the input point cloud has no outliers.

Where to Use the Skill

Common pipelines include:

  • Grasp planning – using the box's tight fit and orientation to plan an approach to an elongated or rotated object
  • Pose estimation – using the box's .center and orientation as an approximate object pose when a full 6-DoF estimate isn't needed
  • Per-cluster tight-fit sizing – computing a tight box for each object after cluster_point_cloud_using_dbscan separates a scene into individual objects
  • Region filtering with orientation – passing the box to filter_point_cloud_using_oriented_bounding_box to keep or remove points inside a rotated region

Alternative Skills

Skillvs. Calculate Oriented Bounding Box
calculate_axis_aligned_bounding_boxFaster and always well-defined, but not tight-fitting for a rotated object. Use it when you don't care about the object's orientation and want the cheaper computation.
calculate_point_cloud_centroidReturns only the mean position, not size or orientation. Use it when you don't need extent/orientation information at all.

When Not to Use the Skill

Do not use Calculate Oriented Bounding Box when:

  • Speed is critical and orientation doesn't mattercalculate_axis_aligned_bounding_box is faster and always well-defined.
  • The object is already roughly axis-aligned — an AABB gives essentially the same box for less compute.
  • You only need a position, not size or orientationcalculate_point_cloud_centroid is simpler and cheaper.

TIP

Keep use_robust_fitting=True on real sensor data — a few outlier points can otherwise skew both the box's size and its orientation, which is exactly the information an OBB is meant to provide.