Segment Point Cloud Using Plane
SUMMARY
Segment Point Cloud Using Plane finds the largest plane in a point cloud using RANSAC and segments it out.
RANSAC repeatedly hypothesizes a plane from a few random points, then counts how many other points lie close to it, keeping the hypothesis with the most support. The result is a 2-tuple: both the points belonging to that plane and the plane's own [a, b, c, d] equation — useful for detecting and removing a table/floor/background plane, or for obtaining plane coefficients to feed into other geometry-based Skills.
Use this Skill when you want to detect and isolate the dominant planar surface in a point cloud, along with its equation, for further analysis or processing.
The Skill
from telekinesis import vitreous
segmented_point_cloud, plane_model = vitreous.segment_point_cloud_using_plane(
point_cloud=point_cloud,
distance_threshold=1.0,
num_initial_points=3,
max_iterations=1000,
keep_outliers=False,
)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 Pointcloud
Unprocessed point cloud.
Segmented Pointcloud
Segmented pointcloud.
The Code
"""
Demonstrates segmenting the dominant plane from a point cloud using RANSAC.
"""
from loguru import logger
import rerun as rr
from telekinesis import vitreous, datatypes
def segment_point_cloud_using_plane_example():
"""
Segments the dominant plane from a point cloud using RANSAC.
Finds the largest planar surface in the cloud using random sample consensus.
Returns inlier points and plane equation.
"""
# ===================== Load Data ==========================================
point_cloud_url = "https://assets.telekinesis.ai/examples/v1/point_clouds/can_vertical_3_downsampled.ply"
point_cloud = datatypes.PointCloud.from_url(url=point_cloud_url, use_cache=True)
# ===================== Run Skill ==========================================
segmented_point_cloud, plane_model = vitreous.segment_point_cloud_using_plane(
distance_threshold=1.0,
num_initial_points=3,
max_iterations=1000,
keep_outliers=False,
point_cloud=point_cloud,
)
# ===================== Log ================================================
logger.success(
f"Segmented {point_cloud} using plane, plane model: {plane_model.data}"
)
logger.success(f"Results: {segmented_point_cloud}, {plane_model}")
logger.info(
f"Segmented point cloud positions shape: {segmented_point_cloud.positions.shape}"
)
logger.info(
f"Segmented point cloud has normals shape: "
f"{segmented_point_cloud.normals.shape if segmented_point_cloud.has_normals else None}"
)
logger.info(
f"Segmented point cloud has colors shape: "
f"{segmented_point_cloud.colors.shape if segmented_point_cloud.has_colors else None}"
)
logger.info(f"Plane model coefficients [a, b, c, d]: {plane_model.data}")
logger.info(f"Plane model shape: {plane_model.shape}")
# ===================== Visualization (Optional) ===========================
rr.init("segment_point_cloud_using_plane_example", spawn=True)
datatypes.visualize(point_cloud, entity_path="/1-input_point_cloud")
datatypes.visualize(segmented_point_cloud, entity_path="/2-segmented_point_cloud")
if __name__ == "__main__":
segment_point_cloud_using_plane_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/segment_point_cloud_using_plane.pyParameter Configuration
These parameters control the RANSAC search used to fit the plane, and which points end up in the returned point cloud.
| Key | Type | Default | Description |
|---|---|---|---|
point_cloud | datatypes.PointCloud | required | The point cloud to segment. Should contain at least one clearly dominant plane for RANSAC to find |
distance_threshold | datatypes.Float | float | int | required | Maximum perpendicular distance, in meters, from the fitted plane for a point to count as an inlier |
num_initial_points | datatypes.Int | int | 3 | Number of points used to hypothesize each candidate plane |
max_iterations | datatypes.Int | int | 100 | Maximum number of RANSAC hypotheses to try |
keep_outliers | datatypes.Bool | bool | False | If True, returns the points that do NOT belong to the detected plane (outliers) instead of the plane's own points (inliers) |
Returns
| Type | Description |
|---|---|
tuple[datatypes.PointCloud, datatypes.Vector4D] | A 2-tuple (segmented_point_cloud, plane_model). segmented_point_cloud holds the plane's inlier points, or its outliers if keep_outliers=True — use .positions/.colors for its (N, 3) arrays and len(...) for its point count. plane_model is the fitted plane's equation coefficients [a, b, c, d] where ax + by + cz + d = 0; use .data for the raw (4,) array. |
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
The segment_point_cloud_using_plane Skill exposes four parameters that control the RANSAC search and what the output represents.
distance_threshold
- Controls: How far, perpendicular to the fitted plane, a point may be and still count as an inlier.
- Units: Meters (the same units as the point cloud's own coordinates).
- Default: required — no default
- Increase → includes points farther from the plane (a thicker plane region)
- Decrease → keeps only points very close to the plane
- Scale it to your point cloud's density and noise level
- Typical range: 0.001–0.1 meters — 0.001–0.01 for precise plane extraction, 0.01–0.05 for moderate, 0.05–0.1 for thick planes
num_initial_points
- Controls: How many points are used to hypothesize each candidate plane per RANSAC iteration.
- Units: Point count (integer)
- Default:
3— the geometric minimum needed to define a plane - Increase (4–10) → more stable hypotheses per iteration, but slower
- Keep at
3for the fastest, standard RANSAC - Typical range: 3–10 —
3for standard RANSAC, 4–6 for more stable fits, 7–10 for very robust (slower) fits
max_iterations
- Controls: The maximum number of RANSAC hypotheses tried before returning the best one found.
- Units: Iteration count (integer)
- Default:
100 - Increase → better chance of finding the true best plane, but slower
- Decrease → faster, but may settle for a suboptimal plane
- Typical range: 100–10000 — 100–500 for fast, 500–2000 for balanced, 2000–10000 for high robustness
keep_outliers
- Controls: Whether the returned
segmented_point_cloudis the plane's inliers or its outliers. - Units: Boolean
- Default:
False False→ returns the points that belong to the plane (extracts the plane itself)True→ returns the points that do not belong to the plane (effectively removes the plane, e.g. to discard a background/floor)
TIP
Start from the defaults for num_initial_points (3) and max_iterations (100), and spend your tuning effort on distance_threshold scaled to your point cloud's units and noise level. Only raise max_iterations into the thousands if the detected plane looks wrong in a complex, multi-plane scene.
Where to Use the Skill
Common pipelines include:
- Ground/floor plane removal – segmenting and discarding the floor before processing the objects on it, for mobile robot navigation or scene understanding
- Tabletop or work-surface extraction – isolating a table, conveyor, or workbench surface with
keep_outliers=False - Isolating objects on a surface – using
keep_outliers=Trueto strip out the dominant plane, then clustering what remains withcluster_point_cloud_using_dbscan - Downstream plane-geometry pipelines – feeding
plane_modelintofilter_point_cloud_using_plane_proximity,filter_point_cloud_using_plane_splitting,project_point_cloud_to_plane, orcalculate_plane_normal
Alternative Skills
| Skill | vs. Segment Point Cloud Using Plane |
|---|---|
| segment_point_cloud_using_color | Segments by color instead of geometry. Use color segmentation when objects are distinguished by color; use plane segmentation when you need to detect a flat surface. |
segment_point_cloud_using_vector_proximity | Segments points near a known 3D line/axis instead of a plane. Use it for a rod, cable, or edge; use plane segmentation for flat surfaces. |
| filter_point_cloud_using_plane_proximity | Not an alternative — a natural next step. Consumes plane_model directly to keep a thin band of points near the plane, on the same or a different point cloud. |
| filter_point_cloud_using_plane_splitting | Not an alternative — a natural next step. Consumes plane_model to split a cloud into two half-spaces and keep only one side, instead of a thin band around the plane. |
| project_point_cloud_to_plane | Not an alternative — a natural next step. Consumes plane_model to orthogonally flatten points onto the plane, rather than selecting a subset of points. |
| calculate_plane_normal | Not an alternative — a natural next step. Consumes plane_model to extract the plane's unit normal vector for orientation-based reasoning. |
When Not to Use the Skill
Do not use Segment Point Cloud Using Plane when:
- The point cloud has no clearly dominant plane – RANSAC assumes one geometrically dominant flat surface exists to find; without one, the "largest plane" it returns may not be meaningful
- You need to segment a curved or non-planar surface – the fitted model is a flat plane only
- You need every plane in a multi-plane scene at once – this Skill returns only the single largest plane; to get more, segment it, remove it from the cloud, and re-run on what remains
- Objects are distinguished by color rather than geometry – use
segment_point_cloud_using_colorinstead
TIP
This Skill finds only the largest plane. To extract multiple planes from one scene, iterate: segment the largest plane, remove its inliers from the cloud (or call again with keep_outliers=True to get everything else), then segment the next-largest plane from what remains.

