Real-time person detection and auto-tracking camera system for Raspberry Pi 5 with Hailo AI accelerator.
- Person Detection: YOLOv8s model running on Hailo-8L NPU at ~30 FPS
- Auto-Tracking Zoom: Smooth camera zoom that follows detected persons
- Multi-Person Tracking: Automatically frames all detected people
- Web Streaming: Live MJPEG stream accessible from any browser
- Zoom Hysteresis: Delayed zoom-out prevents jittery tracking
- Virtual Frame Mode: Preview tracking region without zooming
- Configurable: All tracking parameters adjustable via command line
- Raspberry Pi 5
- Hailo-8L AI Kit
- Pi Camera Module (wide-angle supported)
- Python 3.x
sudo apt install python3-gi python3-gi-cairo gir1.2-gst-1.0 python3-flask python3-opencv python3-numpy
pip install -r requirements.txt├── main.py # Main entry point
├── scripts/
│ ├── tracking.py # Zoom tracking state and calculations
│ ├── pipeline.py # GStreamer pipeline setup
│ └── streaming.py # Flask web streaming
├── requirements.txt
└── README.md
# Run with camera
python main.py
# Run with video file
python main.py -i video.mp4
# Virtual frame mode (shows tracking region without zooming)
python main.py --frame-mode
# Hide detection boxes
python main.py --no-boxes
# Custom settings
python main.py -p 8000 -s 0.05 -c 0.6Access the stream at http://<pi-ip>:8080
| Option | Default | Description |
|---|---|---|
-i, --input |
camera | Video file path |
-p, --port |
8080 | Web server port |
-s, --smooth |
0.1 | Smooth factor (lower = smoother) |
-d, --delay |
30 | Frames to wait before zooming out |
-c, --confidence |
0.5 | Minimum detection confidence |
--padding |
0.3 | Padding around detected person |
--no-boxes |
false | Hide detection boxes |
--frame-mode |
false | Show virtual frame instead of zooming |
--fps |
false | Show FPS counter |
- Camera captures 640x480 frames
- Hailo NPU runs YOLOv8s inference
- All persons above confidence threshold are detected
- Bounding box containing all persons is calculated
- Target crop region is calculated with padding
- Current crop smoothly interpolates toward target
- Cropped/zoomed frame is streamed via Flask
