[English] | 中文
Industrial-grade computer vision reference for Raspberry Pi 5 + Hailo-8
(reComputer R20 series). YOLOv8 object detection with real-time MJPEG preview,
REST API, and offline batch video analysis — designed around Pi 5's actual
hardware (no h264_v4l2m2m HW encoder, modest LAN bandwidth, PCIe-attached
Hailo-8 accelerator).
The single module under src/ is built as a template: copy it and swap the
.hef to retarget to other Hailo Model Zoo models (yolov8s/m, yolov5,
yolov8-seg, etc.).
| Board | Raspberry Pi 5 (reComputer R20 series carrier) |
| Accelerator | Hailo-8 M.2 (PCIe), device node /dev/hailo0 |
| OS | Raspberry Pi OS Bookworm, kernel 6.12+ aarch64 |
| Host drivers | hailo-all apt package (provides PCIe driver, firmware, libhailort.so) |
| HailoRT | 4.23.x validated — host driver / firmware / container wheel must share major.minor |
The quick-start example below uses the published YOLOv8 image, which already
contains the source code, HailoRT wheel, ffmpeg, and the three Model Zoo .hef
weights (yolov8n/s/m). You only need a working Hailo toolchain on the host.
Published GHCR images are stored under this repository namespace:
| Model | Image |
|---|---|
| YOLOv8 | ghcr.io/seeed-projects/recomputer-r20-cv/yolov8:latest |
| YOLOv5 | ghcr.io/seeed-projects/recomputer-r20-cv/yolov5:latest |
| YOLOv10 | ghcr.io/seeed-projects/recomputer-r20-cv/yolov10:latest |
| YOLOv11 | ghcr.io/seeed-projects/recomputer-r20-cv/yolov11:latest |
| YOLOv8 Pose | ghcr.io/seeed-projects/recomputer-r20-cv/yolov8_pose:latest |
| SCRFD | ghcr.io/seeed-projects/recomputer-r20-cv/scrfd:latest |
| SCDepthV3 | ghcr.io/seeed-projects/recomputer-r20-cv/scdepthv3:latest |
| FastDepth | ghcr.io/seeed-projects/recomputer-r20-cv/fast_depth:latest |
| Person Attribute ResNet | ghcr.io/seeed-projects/recomputer-r20-cv/person_attr_resnet:latest |
| SegFormer B0 BN | ghcr.io/seeed-projects/recomputer-r20-cv/segformer_b0_bn:latest |
| U-Net MobileNetV2 | ghcr.io/seeed-projects/recomputer-r20-cv/unet_mobilenet_v2:latest |
| DeepLabV3 MobileNetV2 | ghcr.io/seeed-projects/recomputer-r20-cv/deeplab_v3_mobilenet_v2:latest |
Run the following commands on the development board to install Docker:
# Download installation script
curl -fsSL https://get.docker.com -o get-docker.sh
# Install using Aliyun mirror source
sudo sh get-docker.sh --mirror Aliyun
# Start Docker and enable auto-start on boot
sudo systemctl enable docker
sudo systemctl start dockersudo apt update
sudo apt install hailo-all
sudo reboot
# After reboot, confirm the chip and note the firmware version
hailortcli fw-control identify # should report 4.23.0
ls /dev/hailo0sudo docker run --rm --privileged --net=host \
-e PYTHONUNBUFFERED=1 \
--device /dev/hailo0:/dev/hailo0 \
-v /usr/lib/libhailort.so.4.23.0:/usr/lib/libhailort.so.4.23.0:ro \
-v /usr/lib/libhailort.so:/usr/lib/libhailort.so:ro \
ghcr.io/seeed-projects/recomputer-r20-cv/yolov8:latestDocker will pull the image on first run (~1.8 GB). The container then loops the
bundled video/test.mp4 and serves the Web UI on port 8000 — open
http://<Pi5_IP>:8000 in a browser.
Why the
libhailort.sobind-mount? The image ships only the Python bindings; the native library has to come from the host'shailo-allpackage. If your firmware version isn't4.23.0, replace both4.23.0references with the version printed byhailortcli fw-control identify(and rebuild the image from source against a matching wheel if the major.minor differs).
sudo docker run --rm --privileged --net=host \
-e PYTHONUNBUFFERED=1 \
--device /dev/hailo0:/dev/hailo0 \
--device /dev/video0:/dev/video0 \
-v /usr/lib/libhailort.so.4.23.0:/usr/lib/libhailort.so.4.23.0:ro \
-v /usr/lib/libhailort.so:/usr/lib/libhailort.so:ro \
ghcr.io/seeed-projects/recomputer-r20-cv/yolov8:latest \
python web_detection.py --model_path model/yolov8n.hef --camera_id 0reComputer-R20-CV/
├── docker/hailo8/
│ ├── yolov8.dockerfile # Image: python:3.11-slim arm64 + ffmpeg + HailoRT wheel (yolov8n default)
│ ├── yolov5.dockerfile # Same base, yolov5s default
│ └── yolov11.dockerfile # Same base, yolov11n default
└── src/
├── rpi5_hailo8_yolov8/ # Reference module — validated end-to-end (see TEST_REPORT.md)
├── rpi5_hailo8_yolov5/ # Sibling module, same pipeline with yolov5 .hef weights
└── rpi5_hailo8_yolov11/ # Sibling module, same pipeline with yolov11 .hef weights
# Per-module layout (same for all three):
src/rpi5_hailo8_yolovN/
├── web_detection.py # FastAPI + inference/encode threading pipeline
├── py_utils/
│ ├── hailo_executor.py # HailoRT wrapper, long-lived InferVStreams
│ └── coco_utils.py # Letterbox + box coordinate restoration
├── model/ # `.hef` weights (bundled in the image)
├── hailort-packages/ # HailoRT wheel (bundled in the image)
├── video/test.mp4 # Bundled demo source
├── requirements.txt
├── README.md / README_zh.md # Module deep dive: deployment, CLI, troubleshooting
└── TEST_REPORT.md # Validation log (v8 has full report; v5/v11 are stubs)
When you need to change the code, swap a different .hef, or rebuild against a
different HailoRT version:
git clone https://github.com/Seeed-Projects/reComputer-R20-CV.git
cd reComputer-R20-CV/src/rpi5_hailo8_yolov8
# Replace assets if needed (already bundled — only swap to customize)
# ls model/ # .hef files
# ls hailort-packages/ # hailort wheel
sudo docker build -f ../../docker/hailo8/yolov8.dockerfile \
-t r20-hailo8-yolov8:latest .
# Same run command, with the local tag instead of ghcr.io
sudo docker run --rm --privileged --net=host \
-e PYTHONUNBUFFERED=1 \
--device /dev/hailo0:/dev/hailo0 \
-v /usr/lib/libhailort.so.4.23.0:/usr/lib/libhailort.so.4.23.0:ro \
-v /usr/lib/libhailort.so:/usr/lib/libhailort.so:ro \
r20-hailo8-yolov8:latestAll endpoints listen on port 8000 of the container; with --net=host they're
reachable at http://<Pi5_IP>:8000.
| Endpoint | Method | Purpose |
|---|---|---|
/api/models/yolov8/predict |
POST | One-shot inference on uploaded image, specific video frame, or current camera frame |
/api/video_feed |
GET | MJPEG live stream with boxes overlaid (embed in an <img>) |
/api/config |
GET / POST | Read or update obj_thresh / nms_thresh |
/api/video/upload |
POST | Upload a video for batch analysis |
/api/video/analyze |
POST | Start an offline analysis job (form-data filename=...) |
/api/video/status |
GET | Poll job progress |
/api/video/list |
GET | List uploaded sources and finished outputs |
/api/video/download/{filename} |
GET | Download an annotated output |
# Image upload
curl -X POST http://<Pi5_IP>:8000/api/models/yolov8/predict -F "file=@cat.jpg"
# Specific frame of an uploaded video (timestamp in seconds)
curl -X POST http://<Pi5_IP>:8000/api/models/yolov8/predict \
-F "video=@test.mp4" -F "timestamp=5.5"
# Current camera frame
curl -X POST http://<Pi5_IP>:8000/api/models/yolov8/predict -F "realtime=true"
# Per-call threshold override
curl -X POST http://<Pi5_IP>:8000/api/models/yolov8/predict \
-F "file=@cat.jpg" -F "conf=0.5" -F "iou=0.4"Response:
{
"success": true,
"source": "uploaded image",
"predictions": [
{
"class": "car",
"confidence": 0.787,
"box": { "x1": 2108, "y1": 1483, "x2": 2291, "y2": 1651 }
}
],
"image": { "width": 3840, "height": 2160 }
}Embed the live stream in any HTML page:
<img src="http://<Pi5_IP>:8000/api/video_feed"># Read current
curl http://<Pi5_IP>:8000/api/config
# {"obj_thresh":0.25,"nms_thresh":0.45}
# Update (either field is optional)
curl -X POST http://<Pi5_IP>:8000/api/config \
-H "Content-Type: application/json" \
-d '{"obj_thresh":0.4}'
nms_threshis kept for API compatibility, but the Model Zooyolov8n.hefperforms NMS on-chip — the slider only acts as an extra confidence filter.
Treat src/rpi5_hailo8_yolov8/ as the template:
- Copy the whole directory, rename (e.g.
rpi5_hailo8_yolov8_seg/). - Drop the new
.hefintomodel/. - If the model uses the same output layout (NMS on-chip,
(1, num_classes, max_dets, 5)) — nothing else changes. - For seg / pose / obb / non-NMS models, rewrite
post_process_hailo()inweb_detection.pyagainst the actual tensor spec. Hailo Model Zoo's per-model README documents the output layout. - Add a matching
docker/hailo8/<model>.dockerfile.
Walkthrough: src/rpi5_hailo8_yolov8/README.md § 7.
Per-module deep dives (deployment, CLI arguments, troubleshooting):
- src/rpi5_hailo8_yolov8/README.md — YOLOv8 (English) / README_zh.md
- src/rpi5_hailo8_yolov5/README.md — YOLOv5 (English) / README_zh.md
- src/rpi5_hailo8_yolov11/README.md — YOLOv11 (English) / README_zh.md
Validation:
- src/rpi5_hailo8_yolov8/TEST_REPORT.md — full end-to-end validation log + V1→V2 performance analysis
- v5 / v11 modules ship stub TEST_REPORTs — fill in after running the validation checklist on actual hardware