Skip to content

Segment Point Cloud Using Plane

SUMMARY

Segment Point Cloud Using Plane extracts planar surfaces from a point cloud using the RANSAC algorithm to fit plane models.

This Skill is useful in industrial, mobile, and humanoid robotics pipelines for identifying flat surfaces such as floors, walls, tables, or tabletops. For instance, it can detect conveyor belts or workbenches in manufacturing, segment ground planes for mobile robot navigation, or identify tables and platforms for humanoid robot manipulation. Plane segmentation simplifies downstream tasks by separating dominant surfaces from clutter.

Use this Skill when you want to detect and isolate planar regions within a 3D point cloud for further analysis or processing.

The Skill

python
from telekinesis import vitreous

segmented_point_cloud = vitreous.segment_point_cloud_using_plane(
    point_cloud=point_cloud,
    distance_threshold=0.01,
    num_initial_points=3,
    max_iterations=100,
    keep_outliers=False,
)

API Reference

Performance Note

Current Data Limits: The system currently supports up to 1 million points per request (approximately 16MB of data). We're actively optimizing data transfer performance as part of our beta program, with improvements rolling out regularly to enhance processing speed.

Example

Raw Pointcloud

Unprocessed point cloud.

Segmented Pointcloud

Segmented pointcloud.

The Code

python
from telekinesis import vitreous
from datatypes import datatypes, io
import pathlib

# Optional for logging
from loguru import logger

DATA_DIR = pathlib.Path("path/to/telekinesis-data")

# Load point cloud
filepath = str(DATA_DIR / "point_clouds" / "can_vertical_3_downsampled.ply")
point_cloud = io.load_point_cloud(filepath=filepath)
logger.success(f"Loaded point cloud with {len(point_cloud.positions)} points")

# Execute operation
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=100,
  keep_outliers=False,
)
logger.success(f"Segmented {len(segmented_point_cloud.positions)} points using plane")

Running the Example

Runnable examples are available in the Telekinesis examples repository. Follow the README in that repository to set up the environment. Once set up, you can run this specific example with:

bash
cd telekinesis-examples
python examples/vitreous_examples.py --example segment_point_cloud_using_plane

The Explanation of the Code

The script begins by importing essential modules for point cloud processing (vitreous), data handling (datatypes, io), file management (pathlib), and optional logging (loguru).

python
from telekinesis import vitreous
from datatypes import datatypes, io
import pathlib

# Optional for logging
from loguru import logger

Next, a point cloud is loaded from disk. Logging statements confirm successful loading and indicate the number of points, which is useful for understanding the dataset scale before segmentation.

python

DATA_DIR = pathlib.Path("path/to/telekinesis-data")

# Load point cloud
filepath = str(DATA_DIR / "point_clouds" / "can_vertical_3_downsampled.ply")
point_cloud = io.load_point_cloud(filepath=filepath)
logger.success(f"Loaded point cloud with {len(point_cloud.positions)} points")

The main operation applies the segment_point_cloud_using_plane Skill. This Skill extracts planar surfaces from a point cloud using the RANSAC algorithm. Key parameters include:

  • distance_threshold: the maximum distance a point can be from the plane to be considered an inlier.
  • num_initial_points: number of points used to initialize each RANSAC iteration.
  • max_iterations: maximum number of RANSAC iterations to attempt for plane fitting.
  • keep_outliers: whether to retain points that do not belong to the detected plane.
  • point_cloud: the input point cloud to be segmented.
python
# Execute operation
segmented_point_cloud, plane_cloud = vitreous.segment_point_cloud_using_plane(
  point_cloud=point_cloud,
  distance_threshold=1.0,
  num_initial_points=3,
  max_iterations=100,
  keep_outliers=False,
)
logger.success(f"Segmented {len(segmented_point_cloud.positions)} points using plane")

This operation is particularly useful in industrial robotics and perception pipelines for isolating flat surfaces such as floors, tabletops, or planar faces of objects, which can serve as references for object pose estimation, collision checking, or scene understanding.

How to Tune the Parameters

The segment_point_cloud_using_plane Skill has four parameters that control the RANSAC plane fitting:

distance_threshold (required):

  • The maximum perpendicular distance from the plane to include a point
  • Units: Uses the same units as your point cloud (e.g., if point cloud is in meters, threshold is in meters; if in millimeters, threshold is in millimeters)
  • Increase to include points farther from the plane, capturing a thicker plane region
  • Decrease to keep only points very close to the plane
  • Should be set based on point cloud density and noise level:
    • Millimeter-scale point clouds (e.g., Zivid where 1 unit = 1 mm): Typical values 1-100 (representing 1-100 mm distance)
    • Centimeter-scale point clouds (e.g., 1 unit = 1 cm): Typical values 0.1-10 (representing 0.1-10 cm distance)
    • Meter-scale point clouds (e.g., 1 unit = 1 m): Typical values 0.001-0.1 (representing 0.001-0.1 m distance)
  • Use smaller values for precise plane extraction, larger values for thick planes

num_initial_points (default: 3):

  • The number of points used to initialize each RANSAC plane hypothesis
  • For a plane, 3 points are needed (minimum)
  • Increase (4-10) to use more points per hypothesis, which may be more stable but is slower
  • Decrease (3) for standard RANSAC (fastest)
  • Typical range: 3-10
  • Use 3 for standard RANSAC, 4-6 for more stable fits, 7-10 for very robust (slower)

max_iterations (default: 100):

  • The maximum number of RANSAC iterations
  • Increase (2000-10000) to try more random samples, improving the chance of finding the best plane but taking longer
  • Decrease (100-500) for faster computation but may miss the optimal plane
  • Typical range: 100-10000
  • Use 100-500 for fast, 500-2000 for balanced, 2000-10000 for high robustness

keep_outliers (default: False):

  • Whether to return points that are NOT on the plane (outliers) instead of points ON the plane (inliers)
  • True: Returns points that don't belong to the plane (removes the plane)
  • False: Returns points that belong to the plane (extracts the plane)
  • Default: False

TIP

Best practice: Start with default values and adjust distance_threshold based on your point cloud scale and noise level. Increase max_iterations if the detected plane seems incorrect or if you have a complex scene with multiple planes.

Where to Use the Skill in a Pipeline

Plane segmentation is commonly used in the following pipelines:

  • Surface detection and removal
  • Ground plane extraction
  • Tabletop and work surface identification
  • Scene understanding and preprocessing

A typical pipeline for surface removal looks as follows:

python
# Example pipeline using plane segmentation (parameters omitted).

from telekinesis import vitreous

# 1. Load point cloud
point_cloud = vitreous.load_point_cloud(...)

# 2. Preprocess: remove outliers and downsample
filtered_cloud = vitreous.filter_point_cloud_using_statistical_outlier_removal(...)
downsampled_cloud = vitreous.filter_point_cloud_using_voxel_downsampling(...)

# 3. Segment plane (e.g., table surface)
segemented_point_cloud, plane_model = vitreous.segment_point_cloud_using_plane(
    point_cloud=downsampled_cloud,
    distance_threshold=0.01,
    num_initial_points=3,
    max_iterations=100,
    keep_outliers=False,  # Extract plane
)

# 4. Remove plane to isolate objects
objects_only, plane_model = vitreous.segment_point_cloud_using_plane(
    point_cloud=downsampled_cloud,
    distance_threshold=0.01,
    num_initial_points=3,
    max_iterations=100,
    keep_outliers=True,  # Remove plane, keep objects
)

# 5. Cluster remaining objects
clusters = vitreous.cluster_point_cloud_using_dbscan(
    point_cloud=objects_only,
    max_distance=0.5,
    min_points=10,
)

Related skills to build such a pipeline:

  • filter_point_cloud_using_statistical_outlier_removal: clean input before plane segmentation
  • filter_point_cloud_using_voxel_downsampling: reduce point cloud density for faster processing
  • calculate_plane_normal: extract normal vector from segmented plane
  • cluster_point_cloud_using_dbscan: cluster objects after plane removal
  • segment_point_cloud_using_color: alternative segmentation method based on color

Alternative Skills

Skillvs. Segment Using Plane
segment_point_cloud_using_colorUse color segmentation when objects are distinguished by color. Use plane segmentation when you need to detect flat surfaces.
cluster_point_cloud_using_dbscanUse DBSCAN when objects are spatially separated. Use plane segmentation when you need to detect planar surfaces.

When Not to Use the Skill

Do not use segment using plane when:

  • The point cloud has no dominant plane (the algorithm may not find a meaningful plane)
  • You need to segment curved surfaces (plane segmentation only detects flat surfaces)
  • You need to segment multiple planes simultaneously (this Skill finds only the largest plane; you may need to iterate)
  • The point cloud is very sparse (RANSAC may not work reliably with too few points)
  • You need color-based segmentation (use segment_point_cloud_using_color instead)

WARNING

This Skill finds the largest plane in the point cloud. If you need to segment multiple planes, you may need to iterate: segment the largest plane, remove it, then segment the next largest plane from the remaining points.