Tracks workers in overhead warehouse CCTV footage and generates per-worker activity heatmaps, workload charts, and idle zone maps.
worker_heatmap/
│
├── main.py ← CLI entrypoint — run this
│
├── config/
│ ├── __init__.py
│ └── settings.py ← ALL tuneable constants (thresholds, colours, paths)
│
├── models/
│ ├── __init__.py
│ └── worker.py ← Pure data classes (BoundingBox, WorkerStats, VideoMeta …)
│
├── services/
│ ├── __init__.py
│ ├── detector.py ← YOLOv8 person detection
│ ├── tracker.py ← Centroid-based multi-worker tracking
│ ├── heatmap.py ← Grid accumulation + heatmap rendering
│ └── reporter.py ← Saves images, charts, JSON report
│
├── utils/
│ ├── __init__.py
│ ├── drawing.py ← OpenCV drawing helpers (dots, text, progress bar)
│ └── video.py ← cv2.VideoCapture helpers
│
└── requirements.txt
pip install -r requirements.txt
python main.py --video warehouse.mp4 --output results/| Flag | Default | Description |
|---|---|---|
--video |
(required) | Path to CCTV video |
--output |
results/ |
Output directory |
--fps |
2.0 |
Frames per second to sample |
--show |
off | Live preview window |
--model |
m |
YOLOv8 size: m l x |
--conf |
0.35 |
Detection confidence (0–1) |
All parameters live in config/settings.py as typed dataclasses.
Common tweaks:
# config/settings.py
# Smoother heatmap blobs
HeatmapConfig.gaussian_sigma = 35
# More sensitive detection (catches partially visible workers)
DetectionConfig.confidence = 0.25
# Bigger idle zone detection
HeatmapConfig.idle_threshold = 0.08
# Change output image quality
OutputConfig.jpeg_quality = 85main.py
├── config/settings.py (no app dependencies)
├── models/worker.py (no app dependencies)
├── utils/video.py (models)
├── utils/drawing.py (no app dependencies)
├── services/detector.py (config, models)
├── services/tracker.py (config, models)
├── services/heatmap.py (config, models)
└── services/reporter.py (config, models, services/heatmap)
config and models have zero internal imports — they are the foundation.
utils depend only on models. services depend on config and models.
main.py depends on everything and contains no business logic.