How It Works#
Architecture#
Data Flow Diagram#
DBSCAN Clustering Configuration#
User-Configurable Parameters#
The config.json file allows customization of DBSCAN clustering parameters:
eps- Maximum distance (in meters) between objects to be considered in the same clustermin_samples- Minimum number of objects required to form a cluster
These parameters can be configured globally (default) or per object category.
Configuration File Structure#
The service uses a config.json file located in the config/ directory:
{
"dbscan": {
"default": {
"eps": 1,
"min_samples": 3
},
"category_specific": {
"person": {
"eps": 2,
"min_samples": 2
},
"vehicle": {
"eps": 4.0,
"min_samples": 2
},
"bicycle": {
"eps": 1.5,
"min_samples": 2
},
"motorcycle": {
"eps": 2.5,
"min_samples": 2
},
"truck": {
"eps": 5.0,
"min_samples": 2
},
"bus": {
"eps": 6.0,
"min_samples": 2
}
}
}
}
Parameter Descriptions#
default: Fallback parameters for object categories not explicitly configuredcategory_specific: Per-category parameters optimized for different object types:person- Optimized for people clustering (social distancing, queues)vehicle- Optimized for vehicle parking, traffic clustersbicycle- Optimized for bike racks, group ridingmotorcycle- Moderate spacing for motorcycle clusterstruck- Large vehicle spacing requirementsbus- Bus stops, depot formations
Shape Detection and Analysis#
ML-based Shape Classification: Detects geometric patterns using feature extraction
Size Calculations: Provides precise measurements for each detected shape type
Supported Shapes:
Circle: radius, diameter, area, circumference
Rectangle: width, height, area, perimeter, corner points
Line: length, endpoints, width spread
Irregular: bounding box dimensions, point spread
Shape Detection Logic#
Velocity Analysis and Movement Patterns#
Movement Classification: 6 distinct movement patterns
Velocity Statistics: Comprehensive speed and direction analysis
Pattern Types:
stationary- Objects with minimal movementcoordinated_parallel- Synchronized movement in same directionconverging- Objects moving toward cluster centerdiverging- Objects moving away from cluster centerloosely_coordinated- Some coordination but not highly synchronizedchaotic- Random or unpredictable movement patterns
Velocity Analysis Logic#
Category-Specific Clustering#
The service optimizes DBSCAN parameters based on object categories, providing more accurate clustering for different object types.
Benefits#
Optimized Parameters: Each object type uses clustering parameters optimized for its spatial characteristics
Better Accuracy: Improved clustering accuracy by considering object-specific grouping behaviors
Automatic Selection: Parameters are selected based on detected object category
Fallback Support: Unknown categories use sensible default parameters
Category Optimization Examples#
Category |
eps (meters) |
min_samples |
Rationale |
|---|---|---|---|
|
2.0 |
2 |
Social distancing, queue formations |
|
4.0 |
2 |
Parking lots, traffic clusters |
|
1.5 |
2 |
Bike racks, tight group riding |
|
2.5 |
2 |
Moderate spacing for motorcycle clusters |
|
5.0 |
2 |
Large vehicle spacing requirements |
|
6.0 |
2 |
Bus stops, depot formations |
|
1.0 |
3 |
Fallback for unknown categories |
Usage in Analysis#
The service automatically applies appropriate parameters when processing each object category, with user customizations taking precedence:
# Dynamic parameter selection with user overrides
for category, objects in objects_by_category.items():
# Get user-configured parameters for this scene and category
dbscan_params = self.get_dbscan_params_for_category(category, scene_id)
clustering = DBSCAN(eps=dbscan_params['eps'],
min_samples=dbscan_params['min_samples'])
Cluster Tracking Algorithm#
The service uses a lightweight greedy nearest-centroid matcher that assigns persistent UUIDs to clusters across frames. There is no state machine or confidence scoring — clusters are matched and published from the first frame.
Tracker Configuration Parameters#
Parameter |
Default |
Description |
|---|---|---|
|
2.0 m |
Maximum centroid distance to match a new detection to an existing cluster |
|
10.0 s |
Seconds after |
Matching Algorithm#
For each incoming frame, per object category:
Retrieve non-expired live clusters for the scene and category.
For each new DBSCAN detection, find the nearest unmatched live cluster centroid.
If the distance is within
max_matching_distance(default 2.0 m), reuse that cluster’s UUID.If no live cluster is within range, assign a new UUID.
Discard clusters whose
last_seenexceedsexpiry_seconds(default 10.0 s).
# Simplified greedy matching per category
for detection in new_detections:
nearest = min(live_clusters, key=lambda c: distance(c.centroid, detection.centroid))
if distance(nearest.centroid, detection.centroid) <= max_matching_distance:
nearest.uuid # reuse existing UUID
else:
str(uuid4()) # new UUID
UUID Persistence#
Each cluster carries a UUID (tracking_id) that persists as long as the cluster keeps being matched within max_matching_distance. The UUID survives temporary noise or brief frame gaps up to expiry_seconds.
Cluster Expiry#
A cluster is removed when current_time - last_seen > expiry_seconds. There is no archival or staged removal — clusters are either live or gone.