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 dimensions (height, width, depth): "
        f"{oriented_bounding_box.dimensions}, "
    )
    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

ParameterTypeDefaultDescription
point_clouddatatypes.PointCloudrequiredThe point cloud to bound. Must contain at least one point (at least 4 when minimize_bbox_volume is True). Only positions are used; normals/colors are ignored.
minimize_bbox_volumedatatypes.Bool | boolFalseWhether to search for the box with the smallest possible volume that still contains every point, instead of using a faster default fit. True gives the tightest fit but costs more compute and requires point_cloud to contain at least 4 points; False uses a faster, less exhaustive method that may return a looser box.
use_robust_fittingdatatypes.Bool | boolFalseWhether 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, the response was not returned as an Arrow stream, 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 or malformed input (HTTP 400/422), an unrecognized endpoint (HTTP 404), or another unexpected 4xx response
AuthenticationErrorThe API key was rejected as invalid or expired (HTTP 401)
AuthenticationServiceErrorThe authentication service returned an invalid response, was temporarily unavailable, or timed out (HTTP 502/503/504)
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: False
  • True tightest fit; use for accurate measurements (e.g. grasp planning, dimensional checks). Requires point_cloud to contain at least 4 points
  • 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: False
  • 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

Both parameters default to False (the faster, non-robust fit). For accurate measurements on real sensor data, set both to True — the extra compute cost is usually worth the tighter, more stable box. Leave them at False when speed matters more than fit quality, or when the input is already clean and has fewer than 4 points.

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.