A modular CLI application that processes dashcam video (file or RTSP stream) and outputs an MP4 with ADAS-style overlays including lane detection, road damage detection, pedestrian detection with collision-risk highlighting, and forward motion estimation.
- Lane Detection - Classical CV pipeline (Canny + Hough + polynomial fit) with temporal motion-based stabilization
- Pedestrian Detection - YOLOv8 COCO-based person detection with time-to-collision (TTC) risk classification (LOW/MEDIUM/HIGH)
- Road Damage Detection - YOLO-based pothole/crack detection with severity scoring (requires custom-trained model)
- Motion Estimation - Dense optical flow (Farneback) with EMA smoothing for ego-motion tracking
- Sensor Fusion - Cross-stage temporal smoothing and jitter removal
- HUD Overlay - FPS, speed proxy, heading, detection counts, collision warnings
- Multi-Core CPU Acceleration - Parallel detection stages, async frame I/O, and tuned thread backends for CPU-only mode
- HTML Run Reports - Auto-generated run analysis reports with sample frames, performance stats, and pipeline config
# Create virtual environment
python -m venv .venv
source .venv/bin/activate # or .venv\Scripts\activate on Windows
# Install dependencies
pip install -r requirements.txt- Python 3.9+
- PyTorch (with CUDA for GPU acceleration)
- OpenCV
- Ultralytics (YOLOv8)
# Basic usage
python -m adas_pipeline --input dashcam.mp4 --output result.mp4
# With GPU acceleration
python -m adas_pipeline --input dashcam.mp4 --output result.mp4 --use-gpu
# With custom models and thresholds
python -m adas_pipeline \
--input dashcam.mp4 \
--output result.mp4 \
--model-yolo yolov8n.pt \
--damage-model pothole_model.pt \
--confidence-threshold 0.5 \
--damage-threshold 0.15 \
--use-gpu
# With live preview
python -m adas_pipeline --input dashcam.mp4 --output result.mp4 --display
# RTSP stream input
python -m adas_pipeline --input rtsp://camera-ip:554/stream --output result.mp4
# Generate an HTML run report
python -m adas_pipeline --input dashcam.mp4 --output result.mp4 --htmllog ./lastrun
# Debug mode with frame saving
python -m adas_pipeline --input dashcam.mp4 --output result.mp4 --save-frames --debug
# Multi-core CPU acceleration (auto-detects optimal thread count)
python -m adas_pipeline --input dashcam.mp4 --output result.mp4
# Specify exact number of CPU worker threads
python -m adas_pipeline --input dashcam.mp4 --output result.mp4 --cpu-workers 4
# Disable CPU parallelism (sequential mode)
python -m adas_pipeline --input dashcam.mp4 --output result.mp4 --cpu-workers 1| Flag | Required | Default | Description |
|---|---|---|---|
--input |
Yes | - | Input video file or stream URL |
--output |
Yes | - | Output MP4 file path |
--model-yolo |
No | yolov8n.pt |
YOLOv8 model for pedestrian detection |
--damage-model |
No | yolov8n.pt |
YOLO model for road damage detection |
--use-gpu |
No | False | Enable GPU (CUDA/MPS) acceleration |
--cpu-workers |
No | 0 (auto) |
Number of CPU worker threads (0=auto, 1=sequential) |
--confidence-threshold |
No | 0.5 | Pedestrian detection confidence threshold |
--damage-threshold |
No | 0.15 | Road damage detection confidence threshold |
--display |
No | False | Show live preview window |
--save-frames |
No | False | Save individual debug frames |
--htmllog |
No | - | Directory to write HTML run report (e.g. ./lastrun) |
--debug |
No | False | Enable debug output |
adas_pipeline/
├── main.py # CLI entry point & pipeline orchestration
├── config.py # Dataclass configuration
├── report.py # HTML run report generator
├── pipeline/
│ ├── video_loader.py # Video ingestion & output (OpenCV)
│ ├── motion_estimator.py # Farneback optical flow ego-motion
│ ├── lane_detector.py # Canny/Hough lane detection
│ ├── pedestrian_detector.py # YOLOv8 person detection + TTC
│ ├── damage_detector.py # YOLO road damage detection
│ ├── fusion.py # Sensor fusion & temporal smoothing
│ ├── renderer.py # OpenCV overlay rendering & HUD
│ └── parallel.py # Multi-core CPU parallelism engine
├── models/ # Model weights directory
└── utils/
- Video Ingestion - OpenCV VideoCapture (file/RTSP), extracts FPS/resolution/timestamps
- Motion Estimation - Farneback dense optical flow, rolling buffer (N=5), EMA smoothing
- Lane Detection - HLS color filter (white/yellow) -> Canny -> ROI mask -> Hough -> length-weighted polynomial fit with outlier rejection -> motion stabilization
- Pedestrian Detection - YOLOv8 COCO
personclass -> proximity/size/velocity -> TTC -> risk level - Road Damage Detection - YOLO
pothole/crackclasses -> area*confidence severity - Sensor Fusion - EMA lane smoothing, nearest-neighbor pedestrian tracking, conflict resolution
- Overlay Rendering - Lane polygon fill, color-coded bboxes, HUD bar, collision warning banner
- Video Output - OpenCV VideoWriter preserving original FPS and resolution
The default yolov8n.pt (COCO) does not contain pothole/crack classes. To enable road damage detection, supply a model trained on a road damage dataset:
python -m adas_pipeline --input video.mp4 --output out.mp4 --damage-model runs/segment/runs/damage_seg/train_v2/weights/best.ptThe model should have classes named pothole and/or crack.
You can train your own model using the training pipeline / See : [./taining]
Leading output: [runs/segment/runs/damage_seg/train_v2/]
Leading model: [runs/segment/runs/damage_seg/train_v2/weights/best.pt]
!(runs/segment/runs/damage_seg/train_v2/val_batch2_labels.png)[Example]
!(runs/segment/runs/damage_seg/train_v2/results.png)
Use --htmllog <directory> to automatically generate a timestamped HTML report after each run:
python -m adas_pipeline \
--input dashcam.mp4 \
--output result.mp4 \
--damage-model runs/segment/runs/damage_seg/train_v2/weights/best.pt \
--htmllog ./lastrunEach report (e.g., ./lastrun/2026-03-30_143500.html) includes:
- Run summary (status, total time, frames processed, avg FPS)
- Input/output comparison (resolution, FPS, duration, file size)
- System configuration (CPU, RAM, device, worker count)
- Pipeline stage config (models, thresholds, active/inactive status)
- Pipeline flow diagram (adapts to parallel vs sequential mode)
- Performance analysis (min/max/avg/median FPS, realtime ratio, ms/frame)
- Stability metrics (errors, warnings, dropped frames)
- 7 sample frames extracted from the output video
- Full CLI command reconstruction
- Target: >= 20 FPS on mid-tier GPU (RTX 3060)
- Memory-efficient single-frame processing (no full-video buffering)
- Lazy model loading (models loaded on first frame)
- EMA smoothing for stable overlays without expensive tracking
When running in CPU mode (no --use-gpu), the pipeline automatically enables multi-core parallelism:
| Component | How it helps |
|---|---|
| Parallel detection | Lane, pedestrian, and damage detection run concurrently via ThreadPoolExecutor after motion estimation completes |
| Frame prefetching | Background thread decodes frames ahead into a buffer, hiding I/O latency |
| Async frame writing | Background thread encodes output frames, overlapping with next-frame processing |
| Thread backend tuning | cv2.setNumThreads() and torch.set_num_threads() are balanced against the worker pool to avoid core oversubscription |
This works because OpenCV and PyTorch C++ backends release the Python GIL, allowing true multi-core execution with threads.
--cpu-workers 0(default): auto-detects optimal count (half of available cores)--cpu-workers 1: disables parallelism (original sequential mode)--cpu-workers N: use exactly N worker threads- GPU mode (
--use-gpu): parallelism is disabled (GPU already saturates compute)
Kyle Younge [@t4g]