Cluster Point Cloud Using DBSCAN
SUMMARY
Cluster Point Cloud Using DBSCAN groups points into clusters based on local point density, automatically separating dense regions from sparse noise.
This Skill is well-suited for scenes where objects are spatially separated and have relatively uniform density. DBSCAN does not require specifying the number of clusters in advance and can naturally label outliers, making it a strong default choice for object-level clustering in 3D perception pipelines.
Use this Skill when you want to identify distinct objects or regions in a point cloud while robustly handling noise and background points.
The Skill
from telekinesis import vitreous
clusters = vitreous.cluster_point_cloud_using_dbscan(
point_cloud=point_cloud,
max_distance=0.5,
min_points=10,
)Performance Note
Current Data Limits: The system currently supports up to 1 million points per request (approximately 16MB of data). We're actively optimizing data transfer performance as part of our beta program, with improvements rolling out regularly to enhance processing speed.
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
from telekinesis import vitreous
from datatypes import datatypes, io
import pathlib
# Optional for logging
from loguru import logger
DATA_DIR = pathlib.Path("path/to/telekinesis-data")
# Load point cloud
filepath = str(DATA_DIR / "point_clouds" / "zivid_bottles_10_preprocessed.ply")
point_cloud = io.load_point_cloud(filepath=filepath)
logger.success(f"Loaded point cloud with {len(point_cloud.positions)} points")
# Execute operation
clusters = vitreous.cluster_point_cloud_using_dbscan(
point_cloud=point_cloud,
max_distance=0.5,
min_points=10,
)
logger.success(
f"Clustered point cloud with {len(point_cloud.positions)} points using DBSCAN into {clusters.__len__()} clusters"
)The Explanation of the Code
First, we import the necessary modules from the Telekinesis SDK and optionally set up logging using loguru. This gives us access to point cloud datatypes and the vitreous module for processing operations.
from telekinesis import vitreous
from datatypes import datatypes, io
import pathlib
# Optional for logging
from loguru import loggerNext, we load a preprocessed point cloud from a .ply file using the io.load_point_cloud function. Logging confirms the number of points loaded, ensuring the input data is valid and ready for processing.
DATA_DIR = pathlib.Path("path/to/telekinesis-data")
# Load point cloud
filepath = str(DATA_DIR / "point_clouds" / "zivid_bottles_10_preprocessed.ply")
point_cloud = io.load_point_cloud(filepath=filepath)
logger.success(f"Loaded point cloud with {len(point_cloud.positions)} points")Finally, we run the cluster_point_cloud_using_dbscan Skill. This method identifies dense regions in the point cloud by grouping points that are close together while ignoring sparse noise. Parameters such as max_distance and min_points control the sensitivity of clustering. This is useful in industrial robotics pipelines for detecting individual objects, segmenting bins of items, or isolating parts for manipulation or inspection tasks.
# Execute operation
clusters = vitreous.cluster_point_cloud_using_dbscan(
point_cloud=point_cloud,
max_distance=0.5,
min_points=10,
)
logger.success(
f"Clustered point cloud with {len(point_cloud.positions)} points using DBSCAN into {clusters.__len__()} clusters"
)Running the Example
Runnable examples are available in the Telekinesis examples repository. Follow the README in that repository to set up the environment. Once set up, you can run this specific example with:
cd telekinesis-examples
python examples/vitreous_examples.py --example cluster_point_cloud_using_dbscanHow to Tune the Parameters
The cluster_point_cloud_using_dbscan Skill has two parameters that control how clusters are formed:
max_distance (default: 0.5):
- The maximum distance (epsilon) between two points to be considered neighbors
- Units: Uses the same units as your point cloud (e.g., if point cloud is in meters, distance is in meters; if in millimeters, distance is in millimeters)
- Increase to merge more distant points into clusters, creating fewer but larger clusters
- Decrease to create more, smaller clusters and may leave more points as noise
- Should be set based on the typical spacing between points in your point cloud:
- Millimeter-scale point clouds (e.g., Zivid where 1 unit = 1 mm): Typical values 1-100 (representing 1-100 mm distance)
- Centimeter-scale point clouds (e.g., 1 unit = 1 cm): Typical values 0.1-10 (representing 0.1-10 cm distance)
- Meter-scale point clouds (e.g., 1 unit = 1 m): Typical values 0.01-1.0 (representing 0.01-1.0 m distance)
- For dense point clouds (e.g., from structured light), use smaller values
- For sparse clouds, use larger values
min_points (default: 10):
- The minimum number of points required to form a dense region (core point requirement)
- Increase to require more points to form a cluster, resulting in fewer clusters and more points classified as noise
- Decrease to allow smaller groups to form clusters but may create clusters from noise
- Point cloud density matters: The density of your point cloud directly affects the appropriate value. For very dense point clouds (e.g., high-resolution structured light sensors), you may need higher values (20-50) to avoid creating clusters from noise. For sparse point clouds, lower values (3-10) are often sufficient
- Typical range: 3-50
- For small objects, use 3-10
- For large scenes, use 10-50
TIP
Best practice: Start with default values and adjust max_distance based on your point cloud scale and typical spacing between objects. Then adjust min_points to filter out noise while preserving valid small clusters. Remember that max_distance uses the same units as your point cloud.
Where to Use the Skill in a Pipeline
DBSCAN clustering is commonly used in the following pipelines:
- Object detection and segmentation
- Bin picking and item isolation
- Scene understanding and analysis
- Quality control and inspection
A typical pipeline for object detection and segmentation looks as follows:
# Example pipeline using DBSCAN clustering (parameters omitted).
from telekinesis import vitreous
# 1. Load raw point cloud
point_cloud = vitreous.load_point_cloud(...)
# 2. Preprocess: remove outliers and downsample
filtered_cloud = vitreous.filter_point_cloud_using_statistical_outlier_removal(...)
downsampled_cloud = vitreous.filter_point_cloud_using_voxel_downsampling(...)
# 3. Cluster to separate objects
clusters = vitreous.cluster_point_cloud_using_dbscan(
point_cloud=downsampled_cloud,
max_distance=0.5,
min_points=10,
)
# 4. Process each cluster separately
for cluster in clusters:
# Compute bounding box, centroid, or other analysis
centroid = vitreous.calculate_point_cloud_centroid(point_cloud=cluster)
bbox = vitreous.calculate_oriented_bounding_box(point_cloud=cluster)Related skills to build such a pipeline:
filter_point_cloud_using_statistical_outlier_removal: clean input before clusteringfilter_point_cloud_using_voxel_downsampling: reduce point cloud density for faster processingcluster_point_cloud_based_on_density_jump: alternative clustering method for closely packed objectscalculate_point_cloud_centroid: compute center of each clustercalculate_oriented_bounding_box: compute bounding box for each cluster
Alternative Skills
| Skill | vs. Cluster Using DBSCAN |
|---|---|
| cluster_point_cloud_based_on_density_jump | Use density jump clustering when objects are closely packed or touching and you need to separate them based on density changes along an axis. Use DBSCAN when objects are spatially separated. |
When Not to Use the Skill
Do not use cluster using DBSCAN when:
- Objects are closely packed or touching (use
cluster_point_cloud_based_on_density_jumpinstead) - You need a specific number of clusters (DBSCAN automatically determines the number based on density)
- The point cloud has very uneven density (DBSCAN may struggle with varying densities across the scene)
- You need to separate objects based on orientation (DBSCAN is distance-based, not orientation-aware)
- Objects are connected by thin structures (DBSCAN may merge them into a single cluster)
WARNING
DBSCAN is sensitive to the max_distance parameter. If set too large, it may merge separate objects into one cluster. If set too small, it may split a single object into multiple clusters or classify valid points as noise.

