Cluster Point Cloud Using DBSCAN
SUMMARY
Cluster Point Cloud Using DBSCAN groups a point cloud's points into density-based clusters, discovering the number of clusters directly from the data.
DBSCAN groups points that are densely packed together (within max_distance of each other, in chains) into separate clusters, and discards isolated points as noise. Unlike k-means-style clustering, you don't need to know the number of clusters in advance — DBSCAN discovers it from the data's density. A common use is separating multiple objects that were segmented together (e.g. after removing a background plane with segment_point_cloud_using_plane) into one point cloud per object. Compare with cluster_point_cloud_based_on_density_jump, which always splits a cloud into exactly two regions at a single density discontinuity, instead of finding an arbitrary number of dense clusters.
Use this Skill when you want to separate an unknown number of spatially distinct objects or regions in a point cloud while automatically discarding sparse noise.
The Skill
from telekinesis import vitreous
clusters = vitreous.cluster_point_cloud_using_dbscan(
point_cloud=point_cloud,
max_distance=0.5,
min_points=10,
)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. Shows full resolution, natural noise, and uneven sampling density.
Calculated Clusters
Clusters found with DBSCAN.
Parameters: max_distance = 0.5, min_points=10.
The Code
"""
Demonstrates clustering a point cloud using the DBSCAN density-based clustering algorithm.
"""
from loguru import logger
import rerun as rr
from telekinesis import vitreous, datatypes
def cluster_point_cloud_using_dbscan_example():
"""
Clusters a point cloud using the DBSCAN density-based clustering algorithm.
DBSCAN identifies clusters of points that are closely packed together,
separating distinct objects or regions.
"""
# ===================== Load Data ==========================================
point_cloud_url = "https://assets.telekinesis.ai/examples/v1/point_clouds/zivid_bottles_10_preprocessed.ply"
point_cloud = datatypes.PointCloud.from_url(url=point_cloud_url, use_cache=True)
# ===================== Run Skill ==========================================
clusters = vitreous.cluster_point_cloud_using_dbscan(
point_cloud=point_cloud,
max_distance=20,
min_points=50,
)
# ===================== Log ================================================
logger.success(f"Clustered {point_cloud} using DBSCAN")
logger.success(f"Results: {clusters}")
logger.info(f"Number of 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_using_dbscan_example", spawn=True)
datatypes.visualize(point_cloud, entity_path="/1-input_point_cloud")
datatypes.visualize(clusters, entity_path="/2-dbscan_clusters")
if __name__ == "__main__":
cluster_point_cloud_using_dbscan_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/cluster_point_cloud_using_dbscan.pyParameter Configuration
| Key | Type | Default | Description |
|---|---|---|---|
point_cloud | datatypes.PointCloud | required | The point cloud to cluster |
max_distance | datatypes.Float | float | int | 0.5 | The maximum distance, in meters, between two points for them to be considered neighbors (DBSCAN's "epsilon") |
min_points | datatypes.Int | int | 10 | The minimum number of neighbors a point needs (within max_distance) to count as a core point of a cluster |
Returns
| Type | Description |
|---|---|
datatypes.PointCloudBatch | A batch with one datatypes.PointCloud per discovered cluster (points classified as noise are dropped, not returned as their own cluster). Use len(...) for the cluster count, .positions for the list of each cluster's (N_i, 3) position array, or index/iterate to get a single cluster as a datatypes.PointCloud. |
Raises
| Exception | Condition |
|---|---|
TypeError | A parameter's value does not match its expected type (see the Parameter Configuration table above) |
ConfigurationError | The TELEKINESIS_API_KEY environment variable is not set |
SerializationError | The request input failed to serialize, 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 input, invalid data, or another unexpected 4xx response |
AuthenticationError | The API key was rejected as invalid or expired |
AuthenticationServiceError | The authentication service was unavailable |
ServerError | The Vitreous service returned a 5xx or otherwise unexpected error response |
How to Tune the Parameters
The cluster_point_cloud_using_dbscan Skill exposes two parameters that control how clusters are formed.
max_distance
- Controls: The maximum distance between two points for them to be considered neighbors (DBSCAN's "epsilon").
- Units: Meters
- Default:
0.5 - Increase → merges more distant points into the same cluster, producing fewer, larger clusters
- Decrease → produces more, smaller clusters and leaves more points classified as noise
- Set relative to the typical spacing between points in your cloud
- Typical range: 0.01–1.0 meters — use 0.01–0.1 for dense point clouds (e.g. from structured light), 0.1–1.0 for sparse ones
min_points
- Controls: The minimum number of neighbors a point needs (within
max_distance) to count as a core point of a cluster. - Units: Points (count)
- Default:
10 - Increase → requires denser regions to form a cluster, producing fewer clusters and more points labeled as noise
- Decrease → lets sparser groups count as clusters, but risks treating noise as a real cluster
- Typical range: 3–50 — use 3–10 for small objects, 10–50 for large scenes
TIP
Best practice: start with the defaults and adjust max_distance based on your point cloud's scale and typical point spacing (remember it's in meters); then tune min_points to filter out noise while keeping the small clusters you care about.
Where to Use the Skill
Common pipelines include:
- Object detection and segmentation – separating multiple objects that were segmented together, e.g. after
segment_point_cloud_using_planeremoves a background plane - Bin picking and item isolation – grouping a bin's contents into individually addressable point clouds
- Scene understanding – splitting a full-scene point cloud into per-object regions before computing per-object features
- Quality control and inspection – isolating each part on a tray or conveyor for size or shape assessment
Alternative Skills
| Skill | vs. Cluster Point Cloud Using DBSCAN |
|---|---|
| cluster_point_cloud_based_on_density_jump | Always splits a cloud into exactly two regions at a single density discontinuity, instead of discovering an arbitrary number of dense clusters. Use it when objects are closely packed or touching and DBSCAN can't separate them by distance; use DBSCAN when objects are spatially separated. |
| segment_point_cloud_using_plane | Removes a dominant planar region (e.g. a table or background) rather than grouping the remaining points. Commonly run before DBSCAN to isolate the objects that DBSCAN will then cluster. |
When Not to Use the Skill
Do not use Cluster Point Cloud Using DBSCAN when:
- Objects are closely packed or touching - use
cluster_point_cloud_based_on_density_jumpinstead - You need an exact, known number of clusters - DBSCAN determines the cluster count from density, not from a target count
- The point cloud has strongly varying density across the scene - a single
max_distancemay not fit every region well - Objects are connected by thin structures - DBSCAN may bridge them into a single cluster
WARNING
DBSCAN is sensitive to max_distance: too large merges separate objects into one cluster, too small splits a single object into multiple clusters or classifies valid points as noise.

