Edge ANPR / OCR with DeGirum PySDK + Dahua snapshot + MQTT to Home Assistant (Dockerized)

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/events for 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

:locked: 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 :light_bulb:

  • 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.

2 Likes