Skip to content

Cluster Point Cloud Based on Density Jump

SUMMARY

Cluster Point Cloud Based on Density Jump splits a point cloud into exactly two regions at the strongest density discontinuity along a chosen axis.

It projects points onto projection_axis, estimates local point density along that projection, and cuts the cloud where density changes abruptly — often where an object's volume or thickness changes rapidly (e.g. a part's head vs. its shaft, or a filled region vs. empty space). Unlike cluster_point_cloud_using_dbscan, which can discover any number of dense clusters, this Skill always returns exactly two regions, split at one density jump.

Use this Skill when you want to split a point cloud in two at a clear density transition, for example separating stacked or partially-touching objects where distance-based clustering can't tell them apart.

The Skill

python
from telekinesis import vitreous

regions = vitreous.cluster_point_cloud_based_on_density_jump(
    point_cloud=point_cloud,
    projection_axis=[0.0, 0.0, 1.0],
    num_nearest_neighbors=12,
    neighborhood_radius=0.001,
    is_point_cloud_linear=False,
)
API Reference
Full parameter and return type documentation for cluster_point_cloud_based_on_density_jump.
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

Raw Point Cloud Input

Calculated Clusters

Clusters found based on density change.
Parameters: projection_axis = np.array([0, 0, 1.0]), num_nearest_neighbors=5, neighborhood_radius=0.05.

The Code

python
"""
Demonstrates splitting a point cloud into regions based on density discontinuities.
"""

from loguru import logger
import rerun as rr

from telekinesis import vitreous, datatypes


def cluster_point_cloud_based_on_density_jump_example():
    """
    Splits a point cloud into regions based on density discontinuities.

    Detects and splits point clouds at locations where point density changes
    dramatically.
    """
    # ===================== Load Data ==========================================
    point_cloud_url = (
        "https://assets.telekinesis.ai/examples/v1/point_clouds/mug_preprocessed.ply"
    )
    point_cloud = datatypes.PointCloud.from_url(url=point_cloud_url, use_cache=True)

    # ===================== Run Skill ==========================================
    clusters = vitreous.cluster_point_cloud_based_on_density_jump(
        point_cloud=point_cloud,
        num_nearest_neighbors=5,
        neighborhood_radius=0.05,
        is_point_cloud_linear=False,
        projection_axis=[0.0, 0.0, 1.0],
    )

    # ===================== Log ================================================
    logger.success(f"Split {point_cloud} into density-based clusters")
    logger.success(f"Results: {clusters}")
    logger.info(f"Number of density-based clusters: {len(clusters)}")
    logger.info(f"Points per cluster: {[len(p) for p in clusters.positions]}")
    logger.info(f"First cluster is a PointCloud with {len(clusters[0])} points")

    # ===================== Visualization  (Optional) ===========================
    rr.init("cluster_point_cloud_based_on_density_jump_example", spawn=True)
    datatypes.visualize(point_cloud, entity_path="/1-input_point_cloud")
    datatypes.visualize(clusters, entity_path="/2-density_jump_clusters")


if __name__ == "__main__":
    cluster_point_cloud_based_on_density_jump_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/cluster_point_cloud_based_on_density_jump.py

Parameter Configuration

KeyTypeDefaultDescription
point_clouddatatypes.PointCloudrequiredThe point cloud to split
projection_axisdatatypes.Vector3D | np.ndarray | list[float]requiredThe direction [x, y, z] to project points onto before analyzing density. Set to the point cloud's principal axis (see estimate_principal_axes) for the clearest density signal
num_nearest_neighborsdatatypes.Int | int12The number of nearest neighbors used to estimate density at each point
neighborhood_radiusdatatypes.Float | float | int0.001The radius, in meters, of the spherical neighborhood used for density estimation
is_point_cloud_lineardatatypes.Bool | boolFalseWhether point_cloud is approximately one-dimensional (e.g. a rod, wire, or cable) rather than a 2D surface or 3D volume

Returns

TypeDescription
datatypes.PointCloudBatchA batch with exactly 2 entries, one per side of the density jump. Use len(...) (always 2), .positions for the list of each region's (N_i, 3) position array, or index ([0]/[1]) to get a single region as a datatypes.PointCloud.

Raises

ExceptionCondition
TypeErrorA parameter's value does not match its expected type (see the Parameter Configuration table above), or (for a list projection_axis) it contains a non-numeric element
ValueErrorprojection_axis does not have exactly 3 elements
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

projection_axis

  • Controls: The direction points are projected onto before density is analyzed.
  • Units: Unitless direction vector [x, y, z]
  • Default: none — required
  • Set to the point cloud's principal axis (see estimate_principal_axes) for the clearest density signal
  • Typical values: [0, 0, 1] for a vertical axis, [1, 0, 0] for horizontal along X

num_nearest_neighbors

  • Controls: How many nearest neighbors are used to estimate density at each point.
  • Units: Points (count)
  • Default: 12
  • Increase → more stable, smoother density estimate, but blurs out small/sharp density changes and is slower
  • Decrease → more sensitive to local variation, but noisier
  • Typical range: 6–30

neighborhood_radius

  • Controls: The radius of the spherical neighborhood used for density estimation.
  • Units: Meters
  • Default: 0.001
  • Increase → considers a wider area (more robust, less locally sensitive)
  • Decrease → more locally sensitive, but noisier
  • Scale to your point cloud
  • Typical range: 0.0001–0.01 for small objects, 0.01–0.1 for larger scenes

is_point_cloud_linear

  • Controls: Which density-estimation method is used — one suited to linear structures (e.g. a rod, wire, or cable) vs. the default suited to 2D surfaces or 3D volumes.
  • Units: Boolean flag
  • Default: False
  • Set to True only when the point cloud is approximately one-dimensional

TIP

Best practice: use estimate_principal_axes to find projection_axis rather than guessing it, then adjust neighborhood_radius to your point cloud's scale (it's in meters) before fine-tuning num_nearest_neighbors.

Where to Use the Skill

Common pipelines include:

  • Stacked object separation – splitting a head from its shaft, or a top item from the one beneath it
  • Layered structure analysis – separating regions of a scene that differ in thickness or fill along one axis
  • Assembly part identification – isolating a component whose density profile changes sharply from its neighbor
  • Conveyor belt item isolation – separating touching items where DBSCAN's distance-based grouping would merge them

Alternative Skills

Skillvs. Cluster Point Cloud Based on Density Jump
cluster_point_cloud_using_dbscanDiscovers an arbitrary number of dense clusters directly from the data, instead of always splitting into exactly two regions at one density jump. Use DBSCAN when objects are spatially separated; use density jump clustering when objects are closely packed or touching.
estimate_principal_axesComputes the point cloud's principal directions, useful for choosing a meaningful projection_axis instead of guessing it.

When Not to Use the Skill

Do not use Cluster Point Cloud Based on Density Jump when:

  • Objects are already spatially separated - use cluster_point_cloud_using_dbscan instead
  • There's no clear density discontinuity along any axis - the algorithm may not find a meaningful split
  • You need more than 2 regions - this Skill always returns exactly 2
  • The point cloud has roughly uniform density - there's no density jump to detect
  • You don't yet know the principal axis - run estimate_principal_axes first to choose projection_axis

WARNING

This Skill always returns exactly 2 regions, split at the single strongest density discontinuity found. If you need more than 2 groups, or the objects aren't aligned along one dominant axis, use cluster_point_cloud_using_dbscan instead.