Filter Point Cloud Using Statistical Outlier Removal
SUMMARY
Filter Point Cloud Using Statistical Outlier Removal removes points whose neighbor distances are statistically unusual compared to the rest of the cloud.
For every point, it computes the mean distance to its num_neighbors nearest neighbors, then removes points whose mean distance exceeds overall_mean + standard_deviation_ratio * overall_std_dev, computed across the whole cloud — i.e. points that are unusually far from their neighbors relative to the cloud as a whole. Compare with filter_point_cloud_using_radius_outlier_removal, which uses a fixed search radius instead of adapting to the cloud's own distance distribution — this one handles varying point density better, at the cost of being less predictable and interpretable.
Use this Skill when you want to remove outlier points from a cloud with varying point density, where a fixed search radius wouldn't work well.
The Skill
from telekinesis import vitreous
filtered_point_cloud = vitreous.filter_point_cloud_using_statistical_outlier_removal(
point_cloud=point_cloud,
num_neighbors=90,
standard_deviation_ratio=0.1,
)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.
Mild Outlier Removal
Filtered point cloud produced using statistical outlier removal to eliminatie points that deviate significantly from their local neighborhood distribution. The thin outlier lines are partly removed.
Parameters: standard_deviation_ratio=5.0.
Moderate Outlier Removal
Full removal of the thin outlier lines.
Parameters: standard_deviation_ratio=3.0.
Aggressive Outlier Removal
Heavy outlier removal results in the removal of not only the thin noise lines but also some points belonging to the actual structure.
Parameters: standard_deviation_ratio=0.1.
The Code
"""
Demonstrates removing statistical outliers based on distance distribution.
"""
from loguru import logger
import rerun as rr
from telekinesis import vitreous, datatypes
def filter_point_cloud_using_statistical_outlier_removal_example():
"""
Removes statistical outliers based on distance distribution.
Removes points that are farther than a threshold from their neighbors,
where the threshold is computed from mean distance and standard deviation.
"""
# ===================== Load Data ==========================================
point_cloud_url = "https://assets.telekinesis.ai/examples/v1/point_clouds/can_vertical_6_masked.ply"
point_cloud = datatypes.PointCloud.from_url(url=point_cloud_url, use_cache=True)
# ===================== Run Skill ==========================================
filtered_point_cloud = (
vitreous.filter_point_cloud_using_statistical_outlier_removal(
num_neighbors=90,
standard_deviation_ratio=0.1,
point_cloud=point_cloud,
)
)
# ===================== Log ================================================
logger.success(f"Filtered {point_cloud} using statistical outlier removal")
logger.success(f"Results: {filtered_point_cloud}")
logger.info(
f"Filtered point cloud positions shape: {filtered_point_cloud.positions.shape}"
)
logger.info(
f"Filtered point cloud has normals shape: "
f"{filtered_point_cloud.normals.shape if filtered_point_cloud.has_normals else None}"
)
logger.info(
f"Filtered point cloud has colors shape: "
f"{filtered_point_cloud.colors.shape if filtered_point_cloud.has_colors else None}"
)
# ===================== Visualization (Optional) ===========================
rr.init("filter_point_cloud_using_statistical_outlier_removal_example", spawn=True)
datatypes.visualize(point_cloud, entity_path="/1-input_point_cloud")
datatypes.visualize(filtered_point_cloud, entity_path="/2-filtered_point_cloud")
if __name__ == "__main__":
filter_point_cloud_using_statistical_outlier_removal_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/filter_point_cloud_using_statistical_outlier_removal.pyParameter Configuration
| Parameter | Type | Default | Description |
|---|---|---|---|
point_cloud | datatypes.PointCloud | required | The point cloud to filter |
num_neighbors | datatypes.Int | int | required | The number of nearest neighbors used to compute each point's mean distance. Must be > 0 |
standard_deviation_ratio | datatypes.Float | float | int | required | How many standard deviations above the mean a point's neighbor-distance must be to count as an outlier. Must be > 0 |
Returns
| Type | Description |
|---|---|
datatypes.PointCloud | A point cloud with the statistical outliers removed; returns an empty datatypes.PointCloud if every point is removed. Use .positions for the surviving (N, 3) position array and len(...) for the point count. |
Raises
| Exception | Condition |
|---|---|
TypeError | A parameter's value does not match its expected type (see the Parameter Configuration table above) |
ValueError | num_neighbors or standard_deviation_ratio is not > 0 |
ConfigurationError | The TELEKINESIS_API_KEY environment variable is not set |
SerializationError | The request input failed to serialize, the response was not returned as an Arrow stream, 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 or malformed input (HTTP 400/422), an unrecognized endpoint (HTTP 404), or another unexpected 4xx response |
AuthenticationError | The API key was rejected as invalid or expired (HTTP 401) |
AuthenticationServiceError | The authentication service returned an invalid response, was temporarily unavailable, or timed out (HTTP 502/503/504) |
ServerError | The Vitreous service returned a 5xx or otherwise unexpected error response |
How to Tune the Parameters
The filter_point_cloud_using_statistical_outlier_removal Skill exposes two parameters that together define how far from its neighbors a point can be before it's treated as an outlier. Neither parameter has a default in the SDK — both must be supplied explicitly.
num_neighbors
- Controls: The number of nearest neighbors used to compute each point's mean distance.
- Units: Count (integer), must be
> 0 - Default: required — no default
- Increase → more stable distance statistics, at the cost of being slower and smoothing out local variation
- Decrease → faster, but more sensitive to noise
- Typical range: 10–50 — use 20–50 for dense clouds, 10–20 for sparse ones
standard_deviation_ratio
- Controls: How many standard deviations above the mean neighbor-distance a point must exceed to be flagged as an outlier.
- Units: Standard deviations (dimensionless multiplier), must be
> 0 - Default: required — no default
- Increase → removes fewer points (more lenient, tolerates points that are moderately far from their neighbors)
- Decrease → removes more points (stricter, keeps only points very close to their neighbors)
- Typical range: 0.5–3.0 — use 1.0–2.0 for moderate filtering, 2.0–3.0 for light filtering, 0.5–1.0 for aggressive filtering
TIP
Since neither parameter has a default, start from a moderate pair such as num_neighbors=20, standard_deviation_ratio=2.0, then loosen standard_deviation_ratio if too many points are removed, or tighten it if too few outliers are caught.
Where to Use the Skill
Common pipelines include:
- Point cloud denoising – smoothing out sensor noise before further processing
- Preprocessing before registration – cleaning a cloud before
register_point_clouds_using_point_to_point_icp - Noise removal for segmentation – improving the reliability of
segment_point_cloud_using_planeor clustering on noisy scans - Data cleaning for clustering – reducing spurious small clusters caused by outlier points
Alternative Skills
| Skill | vs. Filter Point Cloud Using Statistical Outlier Removal |
|---|---|
| filter_point_cloud_using_radius_outlier_removal | Uses a fixed search radius and neighbor count instead of adapting to the cloud's own distance statistics. Simpler and more predictable, but handles varying point density less well. |
When Not to Use the Skill
Do not use Filter Point Cloud Using Statistical Outlier Removal when:
- The point cloud is very sparse – too few neighbors makes the mean/standard-deviation statistics unreliable
- You need a simple, predictable neighbor-count rule – use
filter_point_cloud_using_radius_outlier_removalinstead, since its fixed radius is easier to reason about - The point cloud is already clean – running this adds cost without meaningfully changing the result
- You need every point preserved – this Skill removes points outright, so run it only when discarding outliers is acceptable
TIP
Both parameters here are required with no SDK default, unlike many other Vitreous filters — always pass explicit values for num_neighbors and standard_deviation_ratio rather than assuming a sensible default is applied for you.