Real-time drone detection and multi-object tracking pipeline optimized for Apple M4 (MPS).
Uses YOLOv8 for detection and ByteTrack/BoTSORT for tracking with trajectory visualization and persistent alert system.
drone_detection_system/
├── drone_tracker.py # MAIN: end-to-end detection + tracking pipeline
├── configs/
│ ├── bytetrack_drone.yaml # ByteTrack config (tuned for fast drone movement)
│ ├── botsort_drone.yaml # BoTSORT config (adds Re-ID for crossing drones)
│ └── drone_data.yaml # Dataset paths config
├── models/
│ ├── best.pt # Trained YOLOv8n weights (mAP50=0.945)
│ └── last.pt # Last training checkpoint
├── scripts/
│ ├── finetune_drone.py # Training script (YOLOv8m upgrade, drone-optimized)
│ ├── evaluate_tracker.py # Evaluation: mAP + MOTA/IDF1 metrics
│ ├── export_model.py # Export to CoreML/ONNX for max M4 speed
│ └── prepare_dataset.py # Dataset verification & label analysis
├── original_scripts/ # Original code (reference only)
├── requirements.txt
└── README.md
# Create conda environment (recommended)
conda create -n drone-tracker python=3.11 -y
conda activate drone-tracker
# Install dependencies
pip install -r requirements.txt
# Verify MPS is available (M4 Mac)
python -c "import torch; print('MPS:', torch.backends.mps.is_available())"# Basic usage
python drone_tracker.py --source path/to/drone_video.mp4 --save --show-fps
# With alerts (warns when drone persists > 3 seconds)
python drone_tracker.py --source video.mp4 --save --show-fps --alert
# Webcam (live)
python drone_tracker.py --source 0 --show-fps --alert
# High accuracy mode (slower, imgsz=1280)
python drone_tracker.py --source video.mp4 --imgsz 1280 --save
# Use BoTSORT (better when multiple drones cross paths)
python drone_tracker.py --source video.mp4 --tracker configs/botsort_drone.yaml --save# Detection metrics (mAP, precision, recall)
python scripts/evaluate_tracker.py --mode detect --model models/best.pt --data configs/drone_data.yaml
# Tracking metrics (MOTA, IDF1) — requires ground truth
python scripts/evaluate_tracker.py --mode track --gt data/gt.txt --pred outputs/pred.txtThe current model is YOLOv8n (nano, 3M params). For better small-drone detection, upgrade to YOLOv8m (medium, 25M params):
# Fresh training with YOLOv8m
python scripts/finetune_drone.py --model yolov8m.pt --epochs 150 --imgsz 960
# Fine-tune from existing best.pt
python scripts/finetune_drone.py --model models/best.pt --epochs 80 --imgsz 960| Parameter | Original | Optimized | Why |
|---|---|---|---|
| Model | YOLOv8n (3M) | YOLOv8m (25M) | 8x more capacity for small objects |
| imgsz | 640 | 960 | Higher resolution catches tiny drones |
| optimizer | auto (SGD) | AdamW | Better convergence for fine-tuning |
| cos_lr | False | True | Smoother learning rate decay |
| copy_paste | 0.0 | 0.3 | Doubles effective small-object samples |
| multi_scale | False | True | Random scale improves robustness |
| amp | True | False | MPS does NOT support FP16 reliably |
| degrees | 0 | 10 | Drones appear at any rotation |
| mixup | 0 | 0.15 | Extra regularization |
# CoreML — uses M4 Neural Engine (ANE), 3-5x faster than MPS PyTorch
python scripts/export_model.py --model models/best.pt --format coreml
# ONNX — cross-platform fallback
python scripts/export_model.py --model models/best.pt --format onnx
# Benchmark current speed
python scripts/export_model.py --model models/best.pt --benchmark- Pure IoU-based matching (fast)
- Tuned thresholds for small/fast drones
- 2-second track buffer for temporary occlusions
- Adds CNN Re-ID appearance features
- Better when multiple visually similar drones cross paths
- Includes camera motion compensation (GMC)
- Slightly slower than ByteTrack
| Parameter | Value | Purpose |
|---|---|---|
| track_high_thresh | 0.25 | Low threshold — don't miss faint distant drones |
| track_low_thresh | 0.05 | Second-pass association catches very low-conf detections |
| track_buffer | 60 | Keep lost tracks for 2s (at 30fps) |
| match_thresh | 0.85 | Strict matching — avoids wrong track associations |
| Kalman velocity noise | 1/80 | Increased from default 1/160 for erratic drone motion |
| Metric | Value |
|---|---|
| mAP@0.5 | 0.9448 |
| mAP@0.5:0.95 | 0.6074 |
| Precision | 0.9510 |
| Recall | 0.8969 |
- ~14,000 annotations (single class: "drone")
- Mostly small objects (median bbox ~2-5% of image area)
- Sources: mixed (video frames, static images, various backgrounds)
Ensure half=False and amp=False in all scripts. MPS on macOS does not reliably support FP16.
- Try
imgsz=640for faster speed (trade-off: misses tiny drones) - Export to CoreML:
python scripts/export_model.py --format coreml - Check that no other GPU-heavy apps are running
Ensure persist=True in the model.track() call. This is already set in drone_tracker.py.
Run from the project root directory, or pass full path: --tracker /full/path/to/bytetrack_drone.yaml
# Verify your dataset structure
python scripts/prepare_dataset.py --verify --data-dir /path/to/dataset
# Analyze label statistics (box sizes, class balance)
python scripts/prepare_dataset.py --analyze --data-dir /path/to/datasetUpdate the path in configs/drone_data.yaml to match your dataset location.
For personal/research use. Model weights are derived from Ultralytics YOLOv8 (AGPL-3.0).