Skip to content

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 meters 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

python
from telekinesis import vitreous

result_point_cloud = vitreous.subtract_point_clouds(
    point_cloud1=point_cloud1,
    point_cloud2=point_cloud2,
    distance_threshold=0.1,
)
API Reference
Full parameter and return type documentation for subtract_point_clouds.
View Reference →

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

python
"""
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:

bash
cd telekinesis-examples
python examples/point_cloud/subtract_point_clouds.py

Parameter Configuration

KeyTypeDefaultDescription
point_cloud1datatypes.PointCloudrequiredThe source point cloud — points are removed from this one
point_cloud2datatypes.PointCloudrequiredThe reference point cloud — any point in point_cloud1 near a point in this one is removed
distance_thresholddatatypes.Float | float | intrequiredMaximum distance, in meters, for a point in point_cloud1 to be considered "near" a point in point_cloud2 (and therefore removed)

Returns

TypeDescription
datatypes.PointCloudpoint_cloud1 with any point near point_cloud2 removed. Use .positions for the surviving (N, 3) position array and len(...) for the point count.

Raises

ExceptionCondition
TypeErrorA parameter's value does not match its expected type (see the Parameter Configuration table above)
ConfigurationErrorThe TELEKINESIS_API_KEY environment variable is not set
SerializationErrorThe request input failed to serialize, or the response failed to deserialize
RequestTimeoutErrorThe request to the Vitreous service timed out
TransportErrorA network failure occurred before a response was received
ClientErrorThe Vitreous service rejected the request due to invalid input, invalid data, or another unexpected 4xx response
AuthenticationErrorThe API key was rejected as invalid or expired
AuthenticationServiceErrorThe authentication service was unavailable
ServerErrorThe Vitreous service returned a 5xx or otherwise unexpected error response

How to Tune the Parameters

distance_threshold

  • Controls: How close a point in point_cloud1 must be to any point in point_cloud2 before it gets removed.
  • Units: Meters
  • Default: required — no default, must be supplied
  • Increase → removes more points (more aggressive subtraction)
  • Decrease → removes fewer points, only very close ones (more precise)
  • Typical range: 0.001–0.1 meters — 0.001–0.01 for precise subtraction, 0.01–0.05 for moderate, 0.05–0.1 for aggressive

TIP

Start with a small distance_threshold (e.g. 0.001–0.01 meters) 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

Skillvs. Subtract Point Clouds
add_point_cloudsThe reverse operation: merges two point clouds together instead of removing their overlap.
filter_point_cloud_using_bounding_boxCrops 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_clouds instead
  • You want to crop by a fixed geometric region rather than by proximity to another point cloud — use filter_point_cloud_using_bounding_box instead
  • The point clouds are in different coordinate frames — align them first (e.g. with a register_point_clouds_using_* Skill followed by apply_transform_to_point_cloud), otherwise "near" is measured in the wrong frame
  • point_cloud2 is much denser or covers a larger area than intended — a dense or overly broad reference cloud will remove more of point_cloud1 than 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.