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
from telekinesis import vitreous
bounding_box = vitreous.calculate_oriented_bounding_box(
point_cloud=point_cloud,
minimize_bbox_volume=True,
use_robust_fitting=True,
)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
"""
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:
cd telekinesis-examples
python examples/point_cloud/calculate_oriented_bounding_box.pyParameter Configuration
| Key | Type | Default | Description |
|---|---|---|---|
point_cloud | datatypes.PointCloud | required | The point cloud to bound. Only positions are used; normals/colors are ignored. |
minimize_bbox_volume | datatypes.Bool | bool | True | Whether 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_fitting | datatypes.Bool | bool | True | Whether 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
| Type | Description |
|---|---|
datatypes.Box3D | The 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
| Exception | Condition |
|---|---|
TypeError | A parameter's value does not match its expected type (see the Parameter Configuration table above) |
ConfigurationError | The TELEKINESIS_API_KEY environment variable is not set |
SerializationError | The request input failed to serialize, or the response failed to deserialize |
RequestTimeoutError | The request to the Vitreous service timed out |
TransportError | A network failure occurred before a response was received |
ClientError | The Vitreous service rejected the request due to invalid input, invalid data, or another unexpected 4xx response |
AuthenticationError | The API key was rejected as invalid or expired |
AuthenticationServiceError | The authentication service was unavailable |
ServerError | The 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.
Truelets a few stray points (e.g. sensor noise) have less influence on the box;Falseweighs 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 itFalse→ 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
.centerand 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_dbscanseparates a scene into individual objects - Region filtering with orientation – passing the box to
filter_point_cloud_using_oriented_bounding_boxto keep or remove points inside a rotated region
Alternative Skills
| Skill | vs. Calculate Oriented Bounding Box |
|---|---|
| calculate_axis_aligned_bounding_box | Faster 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_centroid | Returns 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 matter —
calculate_axis_aligned_bounding_boxis 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 orientation —
calculate_point_cloud_centroidis 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.

