Subtract Point Clouds
SUMMARY
Subtract Point Clouds removes every point in one point cloud that lies close to a point in another.
It removes any point in point_cloud1 that falls within distance_threshold (in the point clouds' coordinate units) of any point in point_cloud2 — a geometric set difference. It is the reverse operation of add_point_clouds: instead of merging two clouds together, it isolates what is not shared between them. Useful for subtracting a known background or reference scan from a new capture to isolate what changed, or removing one object's points from a scene that also contains it.
Use this Skill when you want to isolate the points that don't overlap with a reference point cloud, such as removing a known surface or background.
The Skill
from telekinesis import vitreous
result_point_cloud = vitreous.subtract_point_clouds(
point_cloud1=point_cloud1,
point_cloud2=point_cloud2,
distance_threshold=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
Input Point Cloud 1
Input Point Cloud 2
Output Point Cloud
The Code
"""
Demonstrates removing points from one cloud that are near points in another cloud.
"""
from loguru import logger
import rerun as rr
from telekinesis import vitreous, datatypes
def subtract_point_clouds_example():
"""
Removes points from one cloud that are near points in another cloud.
Subtracts point_cloud2 from point_cloud1 by removing any point in cloud1
that is within distance_threshold of any point in cloud2.
"""
# ===================== Load Data ==========================================
point_cloud_url_1 = "https://assets.telekinesis.ai/examples/v1/point_clouds/zivid_mixed_grocery_pallet_centered.ply"
point_cloud_url_2 = "https://assets.telekinesis.ai/examples/v1/point_clouds/zivid_mixed_grocery_pallet_box_filtered.ply"
point_cloud1 = datatypes.PointCloud.from_url(url=point_cloud_url_1, use_cache=True)
point_cloud2 = datatypes.PointCloud.from_url(url=point_cloud_url_2, use_cache=True)
# ===================== Run Skill ==========================================
subtracted_point_cloud = vitreous.subtract_point_clouds(
distance_threshold=0.1,
point_cloud1=point_cloud1,
point_cloud2=point_cloud2,
)
# ===================== Log ================================================
logger.success(
f"Subtracted {point_cloud2} from {point_cloud1} using distance threshold 0.1"
)
logger.success(f"Results: {subtracted_point_cloud}")
logger.info(
f"Subtracted point cloud positions shape: {subtracted_point_cloud.positions.shape}"
)
logger.info(
f"Subtracted point cloud has normals shape: "
f"{subtracted_point_cloud.normals.shape if subtracted_point_cloud.has_normals else None}"
)
logger.info(
f"Subtracted point cloud has colors shape: "
f"{subtracted_point_cloud.colors.shape if subtracted_point_cloud.has_colors else None}"
)
# ===================== Visualization (Optional) ===========================
rr.init("subtract_point_clouds_example", spawn=True)
datatypes.visualize(point_cloud1, entity_path="/1-point_cloud_1")
datatypes.visualize(point_cloud2, entity_path="/2-point_cloud_2")
datatypes.visualize(subtracted_point_cloud, entity_path="/3-subtracted_point_cloud")
if __name__ == "__main__":
subtract_point_clouds_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/subtract_point_clouds.pyParameter Configuration
| Parameter | Type | Default | Description |
|---|---|---|---|
point_cloud1 | datatypes.PointCloud | required | The source point cloud — points are removed from this one |
point_cloud2 | datatypes.PointCloud | required | The reference point cloud — any point in point_cloud1 near a point in this one is removed |
distance_threshold | datatypes.Float | float | int | 0.0002 | Maximum distance, in the point clouds' coordinate units, for a point in point_cloud1 to be considered "near" a point in point_cloud2 (and therefore removed). Must be > 0 |
Returns
| Type | Description |
|---|---|
datatypes.PointCloud | point_cloud1 with any point near point_cloud2 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 | distance_threshold is not greater than 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
distance_threshold
- Controls: How close a point in
point_cloud1must be to any point inpoint_cloud2before it gets removed. - Units: The point clouds' own coordinate units
- Default:
0.0002 - Increase → removes more points (more aggressive subtraction)
- Decrease → removes fewer points, only very close ones (more precise)
- Typical range: 0.001–0.1 (in the point clouds' coordinate units) — 0.001–0.01 for precise subtraction, 0.01–0.05 for moderate, 0.05–0.1 for aggressive
- Must be
> 0, or aValueErroris raised
TIP
Start with a small distance_threshold (e.g. 0.001–0.01 in the point clouds' coordinate units) and increase gradually until enough of the reference surface is removed — starting too large risks stripping out points that belong to the object you actually want to keep.
Where to Use the Skill
Common pipelines include:
- Background/table removal – subtract a known static surface from a new capture to isolate the parts placed on it
- Change detection – subtract a previous scan from a new one to isolate what moved or was added
- Scene cleanup before detection – remove known static structure so downstream clustering or detection only sees objects of interest
- Object isolation – remove a known reference region from the full scene before further processing
Alternative Skills
| Skill | vs. Subtract Point Clouds |
|---|---|
| add_point_clouds | The reverse operation: merges two point clouds together instead of removing their overlap. |
| filter_point_cloud_using_bounding_box | Crops a point cloud by fixed geometric bounds instead of by proximity to another point cloud. Use it when you know the region to remove by coordinates rather than by an actual reference scan. |
When Not to Use the Skill
Do not use Subtract Point Clouds when:
- You want to merge two point clouds instead of removing overlap — use
add_point_cloudsinstead - You want to crop by a fixed geometric region rather than by proximity to another point cloud — use
filter_point_cloud_using_bounding_boxinstead - The point clouds are in different coordinate frames — align them first (e.g. with a
register_point_clouds_using_*Skill followed byapply_transform_to_point_cloud), otherwise "near" is measured in the wrong frame point_cloud2is much denser or covers a larger area than intended — a dense or overly broad reference cloud will remove more ofpoint_cloud1than expected
WARNING
Every point in point_cloud1 within distance_threshold of any point in point_cloud2 is removed. If point_cloud2 is dense or covers a large area, this can remove far more of point_cloud1 than intended — check that point_cloud2 represents exactly the region you want to subtract.