description
Oversized-stack rule: fire when a cluster of max_pallet_number or more pallets is being moved as one stack. A moving seed pallet gathers vertically-stacked neighbours (horizontal overlap >= 50% of the narrower box, column split at y-gaps > 1.5x seed height); a big-enough cluster opens a pending window and is confirmed only after ~2 s of stability gates pass (count within tolerance, bounded count std-dev, enough frames at the threshold, merged bbox doesn't balloon, and the centroid actually DRIFTS >= min_centroid_disp_ratio of the cluster height — the stack must be in transport). At creation at least half the pallets must be moving — a parked warehouse stack is not a violation, the rule targets stacks in transport. Rejected seeds get a frame-count cooldown; confirmed cluster members never re-fire. Confidence blends detection confidence, cluster cohesion, motion consistency and a Gaussian of the count.
use cases
- forklift carrying more pallets than the safe stacking limit
- tip-over prevention for tall mobile stacks in aisles
- template for count-of-clustered-objects rules (any class via config)
limitations
- x-overlap clustering cannot distinguish a true vertical stack from a tight side-by-side row seen head-on — camera angle matters
- counts fluctuate with occlusion; the stability gates absorb some of it but low-FPS or heavily occluded scenes need threshold retuning
- the split threshold (1.5x seed height) assumes roughly camera-uniform pallet sizes
- uses the stock ByteTrack (min_consecutive_frames pinned to 1 in defaults); the legacy custom pallet matcher (cost-based re-assignment) is not reproduced
config parameters
general
| Parameter | Type | Default | Notes |
|---|---|---|---|
| max_pallet_number * | integer | 9 | cluster size that fires (min 2) |
| stability_window_seconds * | number | 2.0 | (min 0.5) |
advanced
| Parameter | Type | Default | Notes |
|---|---|---|---|
| pallet_classes | array of string | ["pallet", "product_package"] | |
| stability_tolerance | integer | 2 | (min 0) |
| max_total_std | number | 2.15 | (min 0) |
| min_above_threshold_ratio | number | 0.25 | (min 0, max 1) |
| max_bbox_area_growth_ratio | number | 2.2 | (min 1) |
| min_centroid_disp_ratio | number | 0.05 | (min 0) |
| max_cluster_height_px | integer | 700 | (min 1) |
| min_creation_moving_ratio | number | 0.5 | (min 0, max 1) |
| x_overlap_ratio | number | 0.5 | (min 0, max 1) |
| split_height_factor | number | 1.5 | (min 0) |
| move_ratio | number | 0.05 | (min 0) |
| rejection_cooldown_frames | integer | 100 | (min 0) |
| confidence_alpha | number | 0.2 | |
| confidence_beta | number | 0.2 | |
| confidence_gamma | number | 0.2 | |
| confidence_delta | number | 0.4 | |
| pallet_count_confidence_mu | number | 9 | |
| pallet_count_confidence_sigma | number | 1.5 |
golden replay cases
| Case | Frames | Expected events |
|---|---|---|
| moving-stack | 8 | 1 |