Filter Point Cloud Using Plane Defined by Point Normal Proximity
SUMMARY
Filter Point Cloud Using Plane Defined by Point Normal Proximity extracts points that lie within a specified distance from a plane defined by a reference point and a normal vector.
This Skill is particularly useful in industrial, mobile, and humanoid robotics pipelines for isolating planar surfaces or features. For example, it can extract a tabletop or work surface in industrial settings, detect floors or walls in mobile robot mapping, or identify flat regions for humanoid robot interactions. By focusing on points near a plane, robots can simplify perception and enable accurate pose estimation, segmentation, and manipulation.
Use this Skill when you want to filter a point cloud to points close to a specific plane for downstream perception, alignment, or manipulation tasks.
The Skill
from telekinesis import vitreous
import numpy as np
filtered_point_cloud = vitreous.filter_point_cloud_using_plane_defined_by_point_normal_proximity(
point_cloud=point_cloud,
plane_point=np.array([0.0, 0.0, 0.5]),
plane_normal=np.array([0.0, 0.0, 1.0]),
distance_threshold=0.01,
)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 Sensor Input
Unprocessed point cloud captured directly from the sensor.
Plane for Extraction
Input point cloud overlayed with the plane for extraction.
Extracted Points with a Small Distance
Only points within the specified distance of the plane are retained and points beyond this threshold are removed on either side. This filters out both the cans and the outliers below the plane.
Parameters: distance_threshold = 4 (scene units).
Extracted Points with a Moderate Distance
Raising the distance threshold filters out fewer points. Outliers below the plane are removed, but the cans’ lower-half points remain.
Parameters: distance_threshold = 50 (scene units).
The Code
from telekinesis import vitreous
from datatypes import datatypes, io
import pathlib
import numpy as np
# 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
# Define plane using point and normal from coefficients
plane_coefficients = [0.028344755192329624, -0.5747207168510667, -0.8178585895344518, 555.4890362620131]
a, b, c, d = plane_coefficients
plane_point = -d / (a**2 + b**2 + c**2) * np.array([a, b, c])
# Filter point cloud using plane defined by point and normal
filtered_point_cloud = vitreous.filter_point_cloud_using_plane_defined_by_point_normal_proximity(
point_cloud=point_cloud,
plane_point=plane_point,
plane_normal=[a, b, c],
distance_threshold=50.0,
)
logger.success("Filtered points using plane defined by point and normal")The Explanation of the Code
This example begins by importing the necessary modules for point cloud processing, numerical operations, data handling, and optional logging. The key modules include vitreous, datatypes, io, numpy, pathlib, and loguru.
from telekinesis import vitreous
from datatypes import datatypes, io
import pathlib
import numpy as np
# Optional for logging
from loguru import loggerNext, a point cloud is loaded from a .ply file. Logging confirms the number of points in the cloud, ensuring that the data is ready for processing and analysis.
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")Finally, the filter_point_cloud_using_plane_defined_by_point_normal_proximity Skill is applied. A plane is first defined from coefficients, converted into a point on the plane and a normal vector. The Skill then filters out points that lie farther than a specified distance from this plane. This is especially useful in robotics pipelines for isolating surfaces, segmenting planar features, or focusing on regions of interest for manipulation, inspection, or 3D perception tasks.
# Execute operation
# Define plane using point and normal from coefficients
plane_coefficients = [0.028344755192329624, -0.5747207168510667, -0.8178585895344518, 555.4890362620131]
a, b, c, d = plane_coefficients
plane_point = -d / (a**2 + b**2 + c**2) * np.array([a, b, c])
# Filter point cloud using plane defined by point and normal
filtered_point_cloud = vitreous.filter_point_cloud_using_plane_defined_by_point_normal_proximity(
point_cloud=point_cloud,
plane_point=plane_point,
plane_normal=[a, b, c],
distance_threshold=50.0,
)
logger.success("Filtered points using plane defined by point and normal")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_defined_by_point_normal_proximityHow to Tune the Parameters
The filter_point_cloud_using_plane_defined_by_point_normal_proximity Skill has three parameters that control the filtering:
plane_point (required):
- A 3D point that lies on the plane
- Units: Uses the same units as your point cloud (e.g., if point cloud is in meters, point is in meters; if in millimeters, point is in millimeters)
- Defines the plane's position in space
- Any point on the plane can be used
- Typically set to a point you know lies on the plane (e.g., from plane fitting or manual selection)
plane_normal (required):
- The normal vector of the plane (perpendicular to the plane surface)
- Should be normalized (unit vector)
- Defines the plane's orientation
- For horizontal planes, use
[0, 0, 1]or[0, 0, -1] - For vertical planes, use
[1, 0, 0],[0, 1, 0], etc. - The direction (positive/negative) determines which side of the plane is considered "positive"
distance_threshold (required):
- The maximum perpendicular distance from the plane to keep 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 keep points farther from the plane, including points on nearby parallel surfaces
- Decrease to keep only points very close to the plane
- Typical range: 0.001-0.1 in point cloud units
- For precise plane extraction, use 0.001-0.01
- For filtering near a plane, use 0.01-0.1
TIP
Best practice: Ensure plane_normal is normalized (unit vector). Use calculate_point_cloud_centroid to get a reference point on the plane if needed. Use segment_point_cloud_using_plane to detect planes first.
Where to Use the Skill in a Pipeline
Plane proximity filtering (point+normal) is commonly used in the following pipelines:
- Planar surface extraction
- Ground plane removal
- Tabletop or work surface detection
- Wall or floor identification
A typical pipeline for planar surface extraction looks as follows:
# Example pipeline using plane proximity filtering (point+normal) (parameters omitted).
from telekinesis import vitreous
import numpy as np
# 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 to get plane information
plane_points = vitreous.segment_point_cloud_using_plane(
point_cloud=downsampled_cloud,
distance_threshold=0.01,
keep_outliers=False,
)
# 4. Get reference point (e.g., centroid of plane)
plane_centroid = vitreous.calculate_point_cloud_centroid(point_cloud=plane_points)
# 5. Get plane normal (from plane coefficients or estimation)
plane_normal = np.array([0.0, 0.0, 1.0]) # Example: vertical normal
# 6. Filter point cloud using plane proximity
filtered_cloud = vitreous.filter_point_cloud_using_plane_defined_by_point_normal_proximity(
point_cloud=downsampled_cloud,
plane_point=plane_centroid,
plane_normal=plane_normal,
distance_threshold=0.01,
)
# 7. Process the filtered point cloudRelated skills to build such a pipeline:
segment_point_cloud_using_plane: detect planes and get plane informationcalculate_point_cloud_centroid: get reference point on the planecalculate_plane_normal: extract normal vector from plane coefficientsfilter_point_cloud_using_statistical_outlier_removal: clean input before filteringfilter_point_cloud_using_plane_proximity: alternative method using plane coefficients
Alternative Skills
| Skill | vs. Filter Point Cloud Using Plane (Point+Normal) |
|---|---|
| filter_point_cloud_using_plane_proximity | Use plane coefficients when you have plane equation coefficients [a, b, c, d]. Use point+normal when you have a point on the plane and its normal vector. |
| filter_point_cloud_using_plane_splitting | Use plane splitting when you want to keep one side of the plane. Use plane proximity when you want to keep points within a distance threshold on both sides. |
| segment_point_cloud_using_plane | Use plane segmentation to detect and extract the largest plane. Use plane proximity filtering to extract points near a known plane. |
When Not to Use the Skill
Do not use filter point cloud using plane (point+normal) when:
- You have plane coefficients (use
filter_point_cloud_using_plane_proximityinstead) - The plane normal is not normalized (ensure it's a unit vector)
- You want to keep only one side of the plane (use
filter_point_cloud_using_plane_splittinginstead) - You need to detect planes (use
segment_point_cloud_using_planefirst to find planes) - The point is not on the plane (the filtering may not be as expected)
- You need to filter based on 3D box regions (use bounding box or passthrough filter instead)

