Filter Point Cloud Using Plane Splitting
SUMMARY
Filter Point Cloud Using Plane Splitting keeps only the points on one side of a defined plane, based on the plane’s normal direction.
This Skill is useful in industrial, mobile, and humanoid robotics pipelines for segregating objects or regions in 3D space. For example, it can isolate items on one side of a conveyor belt in industrial settings, remove floor points for mobile robot perception, or separate reachable objects for humanoid manipulation. By splitting the point cloud along a plane, robots can focus on relevant regions and simplify downstream tasks like clustering, segmentation, and pose estimation.
Use this Skill when you want to retain only points on a specific side of a plane to support perception, alignment, or manipulation operations.
The Skill
from telekinesis import vitreous
filtered_point_cloud = vitreous.filter_point_cloud_using_plane_splitting(
point_cloud=point_cloud,
plane_coefficients=[0.0, 0.0, 1.0, -0.5],
keep_positive_side=True,
)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 Sensor Input
Unprocessed point cloud captured directly from the sensor. Shows full resolution, natural noise, and uneven sampling density.
Splitted Points
Filtered points on the negative side of the red plane.
Raw Sensor Input with Splitting Plane
Splitting Plane shown in red.
The Code
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" / "mounts_3_raw.ply")
point_cloud = io.load_point_cloud(filepath=filepath)
logger.success(f"Loaded point cloud with {len(point_cloud.positions)} points")
# Execute operation
filtered_point_cloud = vitreous.filter_point_cloud_using_plane_splitting(
point_cloud=point_cloud,
plane_coefficients=[0, 0, 1, -547],
keep_positive_side=True,
)
logger.success("Filtered points using plane splitting")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:
cd telekinesis-examples
python examples/vitreous_examples.py --example filter_point_cloud_using_plane_splittingThe Explanation of the Code
The code begins by importing necessary modules for point cloud processing, data handling, and optional logging. Key modules here include vitreous, datatypes, io, pathlib, and loguru.
from telekinesis import vitreous
from datatypes import datatypes, io
import pathlib
# Optional for logging
from loguru import loggerA point cloud is then loaded from a .ply file, and logging is used to verify the number of points, ensuring the dataset is ready for processing.
DATA_DIR = pathlib.Path("path/to/telekinesis-data")
# Load point cloud
filepath = str(DATA_DIR / "point_clouds" / "mounts_3_raw.ply")
point_cloud = io.load_point_cloud(filepath=filepath)
logger.success(f"Loaded point cloud with {len(point_cloud.positions)} points")The main operation uses the filter_point_cloud_using_plane_splitting Skill. A plane is defined using general plane coefficients, and the Skill retains only the points on the specified side of the plane. This is particularly useful in robotics pipelines for segmenting a workspace, isolating parts of interest, or removing background points from sensor data before downstream perception or manipulation tasks.
# Execute operation
filtered_point_cloud = vitreous.filter_point_cloud_using_plane_splitting(
point_cloud=point_cloud,
plane_coefficients=[0, 0, 1, -547],
keep_positive_side=True,
)
logger.success("Filtered points using plane splitting")How to Tune the Parameters
The filter_point_cloud_using_plane_splitting Skill has two parameters that control the splitting:
plane_coefficients (required):
- The plane equation coefficients as
[a, b, c, d]whereax + by + cz + d = 0 - The vector
[a, b, c]is the plane normal (should be normalized) dis the distance from origin- The sign of
(ax + by + cz + d)determines which side a point is on - Can be obtained from plane fitting algorithms (e.g.,
segment_point_cloud_using_plane) - Examples:
- For a horizontal plane at z=0.5:
[0, 0, 1, -0.5] - For a plane through origin with normal [1,0,0]:
[1, 0, 0, 0]
- For a horizontal plane at z=0.5:
keep_positive_side (required):
- Whether to keep points on the positive side of the plane
True: Keeps points where(ax + by + cz + d) > 0(points in the direction of the normal vector)False: Keeps points where(ax + by + cz + d) < 0(points opposite to the normal)- The choice depends on which half-space you want to retain
TIP
Best practice: Use segment_point_cloud_using_plane to detect planes and get plane coefficients. The sign of the normal vector determines which side is "positive", so test both True and False if unsure which side you want.
Where to Use the Skill in a Pipeline
Plane splitting is commonly used in the following pipelines:
- Half-space extraction
- Ground plane removal
- Workspace segmentation
- Object separation
A typical pipeline for ground plane removal looks as follows:
# Example pipeline using plane splitting (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 ground plane to get plane coefficients
ground_plane = vitreous.segment_point_cloud_using_plane(
point_cloud=downsampled_cloud,
distance_threshold=0.01,
keep_outliers=False,
)
# 4. Get plane coefficients (from plane segmentation result)
# plane_coefficients = [a, b, c, d] # Extract from plane segmentation
# 5. Remove ground plane (keep points above the plane)
objects_above_ground = vitreous.filter_point_cloud_using_plane_splitting(
point_cloud=downsampled_cloud,
plane_coefficients=[0.0, 0.0, 1.0, -0.5],
keep_positive_side=True, # Keep points above the plane
)
# 6. Process the filtered point cloud
clusters = vitreous.cluster_point_cloud_using_dbscan(...)Related skills to build such a pipeline:
segment_point_cloud_using_plane: detect planes and get plane coefficientscalculate_plane_normal: extract normal vector from plane coefficientsfilter_point_cloud_using_statistical_outlier_removal: clean input before filteringfilter_point_cloud_using_plane_proximity: alternative for keeping points within a distance thresholdcluster_point_cloud_using_dbscan: process filtered point clouds
Alternative Skills
| Skill | vs. Filter Point Cloud Using Plane Splitting |
|---|---|
| filter_point_cloud_using_plane_proximity | Use plane proximity when you want to keep points within a distance threshold on both sides. Use plane splitting when you want to keep only one side of the plane. |
| filter_point_cloud_using_plane_defined_by_point_normal_proximity | Use plane proximity (point+normal) when you have a point and normal. Use plane splitting when you have plane coefficients and want to split by side. |
When Not to Use the Skill
Do not use filter point cloud using plane splitting when:
- You want to keep points within a distance threshold on both sides (use
filter_point_cloud_using_plane_proximityinstead) - The plane coefficients are invalid (ensure the normal vector [a, b, c] is normalized)
- You need to detect planes (use
segment_point_cloud_using_planefirst to find planes) - You have a point and normal vector (use
filter_point_cloud_using_plane_defined_by_point_normal_proximityinstead, though it doesn't split by side) - You need to filter based on 3D box regions (use bounding box or passthrough filter instead)

