Skip to content

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

python
from telekinesis import vitreous

clusters = vitreous.cluster_point_cloud_using_dbscan(
    point_cloud=point_cloud,
    max_distance=0.5,
    min_points=10,
)

API Reference

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

python
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.

python
from telekinesis import vitreous
from datatypes import datatypes, io
import pathlib

# Optional for logging
from loguru import logger

Next, 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.

python

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.

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

bash
cd telekinesis-examples
python examples/vitreous_examples.py --example cluster_point_cloud_using_dbscan

How 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:

python
# 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 clustering
  • filter_point_cloud_using_voxel_downsampling: reduce point cloud density for faster processing
  • cluster_point_cloud_based_on_density_jump: alternative clustering method for closely packed objects
  • calculate_point_cloud_centroid: compute center of each cluster
  • calculate_oriented_bounding_box: compute bounding box for each cluster

Alternative Skills

Skillvs. Cluster Using DBSCAN
cluster_point_cloud_based_on_density_jumpUse 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_jump instead)
  • 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.