A FastAPI app that talks to a DeGirum AI Server, runs license-plate detection + OCR recognition on live snapshots from a Dahua camera, shows overlays in a web UI, and publishes events to MQTT for Home Assistant. Dockerized for quick spin-up.
Code: github.com/yac69/degirum-ocr-demo
Why I built this
I wanted a small, reliable edge pipeline that:
-
pulls a snapshot every second from a camera,
-
runs a detector → recognizer OCR chain,
-
only surfaces meaningful events (debounce + pre-filters),
-
and notifies Home Assistant via MQTT—complete with overlay images and who/what was detected.
It’s a simple recipe that shows how DeGirum PySDK lets you wire multiple devices together and still keep a tidy, portable codebase.
What it does
-
Single-shot: upload a photo, pick a model, and run detection or OCR (detector+recognizer).
-
Live mode: every second → grab snapshot → detect → OCR → debounce (avoid spam) → overlay → MQTT event.
-
Confidence & size gating before OCR to reduce false positives.
-
Daily retention of overlays: only keep annotated images from today.
-
Server-Sent Events (SSE) at
/live/eventsfor a simple live feed in the UI. -
Autostart the live OCR loop on container boot.
Heterogeneous inference (PySDK superpower)
Thanks to DeGirum PySDK’s device-agnostic runtime, I run license-plate detection on a Coral M.2 (TFLite/EdgeTPU) and OCR recognition on an Intel GPU (OpenVINO) in parallel. On my Coral M.2 + i950 setup, end-to-end latency averages < 150 ms per frame.
Hardware / Models
-
Dahua (or any ONVIF) camera with a snapshot endpoint.
-
DeGirum AI Server (local or cloud).
-
Example models:
-
Detection:
licence_plate--640x640_quant_tflite_edgetpu_1 -
Recognition:
paddle_ocr_recognition--48x320_float_openvino_cpu_1
-
Privacy: Plates + names in this post and repo are anonymized. Swap in your own mapping in
identify_label()if you want friendly names for known plates.
Home Assistant
Publish events to degirum/plates/event. Example payload:
{
"ts": "2025-10-10T12:34:56",
"server": "192.168.1.10:8778",
"det_ms": 12.3,
"rec_ms": 4.5,
"total_ms": 16.8,
"overlay_url": "http://<host>:8083/static/out/2025-10-10/live_..._overlay.jpg",
"texts": [{"text": "AB123CD", "conf": 98.1, "bbox": [x1,y1,x2,y2], "who": "Resident A"}],
"people": ["Resident A"],
"has_target": true
}
The UI also exposes /api/diag for a quick health check (live loop status, MQTT connectivity, last event count).
Get started (Docker)
Repo: github.com/yac69/degirum-ocr-demo
git clone https://github.com/yac69/degirum-ocr-demo.git
cd degirum-ocr-demo
cp .env.example .env # fill in your AI server, camera, MQTT settings
docker compose up -d --build
Open:
-
App UI →
http://<host>:8083/ -
Live events (SSE) →
http://<host>:8083/live/events -
Diagnostics →
http://<host>:8083/api/diag
How it stays practical
-
Debounce: prevents repeated notifications for the same “who” within N seconds.
-
Pre-filters: gate on detector confidence, bounding box size, and aspect ratio before running OCR.
-
Daily folders for overlays; automatic cleanup of prior days.
Call for feedback / ideas 
-
Multi-camera: best ways to fan-out the loop (threads vs. async), per-camera model routing.
-
RTSP ingestion: anyone happy with lightweight RTSP frame grabs (OpenCV, PyAV, GStreamer) while keeping CPU overhead low?
-
Async MQTT: interest in moving to an async client or batching events for high-traffic scenes?
If this looks useful, I’m happy to add examples (multi-camera, RTSP snapshots, or HA blueprints). Also open to performance tips on mixed Coral + Intel GPU deployments.
Thanks to the DeGirum team & community for the PySDK and docs—this project made me appreciate how painless heterogeneous inference can be.