Downloads · 30 days
0
Dibachain/Platrix
Platrix is a image-to-text model from Dibachain. Use it when you need a caption or text from an image. It is set up for onnxruntime. The card lists the license as mit.
<p align="center" <img src="https://huggingface.co/Dibachain/Platrix/resolve/main/banner.png" alt="Platrix" width="100%" / </p
Downloads · 30 days
0
Access
Public
Updated Jul 25, 2026
Repo size
73 MB
Likes
0
Public
Click a slice to open those files.
.onnx37.6 MB · 94%
From the Hugging Face model README
Production ONNX models for detecting and reading Iranian vehicle license plates, powering the Platrix real-time, self-hosted plate-surveillance system.
📦 Code & full pipeline: https://github.com/AliAkrami1375/Platrix 🤗 This model repo: https://huggingface.co/Dibachain/Platrix
The pipeline is two-stage: a YOLO detector locates the plate in the
frame, an image-quality enhancement step cleans the crop, then a
segmentation-free CRNN + CTC reader reads the whole plate at once and returns
the standard Iranian layout DD L DDD DD (two digits · letter · three digits ·
two-digit region), e.g. ۸۱ و ۶۳۸ ۱۳.
All models run with ONNX Runtime — no PyTorch or TensorFlow needed at inference time.
Measured on 220 real Iranian surveillance photos (grayscale gate/road cameras — the hard, real-world domain, not staged shots).
<p align="center"> <img src="https://huggingface.co/Dibachain/Platrix/resolve/main/assets/benchmark.png" width="88%" /> </p>A lightweight secondary detector runs only when the primary finds nothing. It recovers plates the primary is blind to — trucks, night shots, small/far and dim plates — lifting the end-to-end read rate from 95.9% → 97.7% with no regression on the easy majority (the fallback fires on only ~2% of frames).
<p align="center"> <img src="https://huggingface.co/Dibachain/Platrix/resolve/main/assets/recovery.png" width="70%" /> </p>The reader reaches ~93% whole-plate accuracy in training and ~98% on real photos; the detector reaches mAP@0.5 ≈ 0.99 on held-out real frames.
| File | Role | Input | Output |
|---|---|---|---|
plate_yolo.onnx | Plate detector (YOLOv8, primary) | 1×3×H×W RGB, letterboxed, /255 | 1×5×N → cx,cy,w,h,conf |
plate_yolo_fallback.onnx | Secondary detector — runs only when the primary finds nothing; recovers hard surveillance frames | 1×3×640×640 | 1×5×N |
ocr_crnn.onnx | Whole-plate reader (CRNN+CTC) — recommended | 1×1×32×128 grayscale, /255 | 1×T×(C+1) logits (CTC, blank = last) |
ocr_crnn.labels.json | Class list for the CRNN (index → character) | — | 32 classes |
ocr_cnn.onnx | Per-character classifier (lightweight fallback reader) | 1×1×32×32 grayscale | class logits |
ocr_cnn.labels.json | Class list for the per-char classifier | — | — |
Character set (32 classes): digits 0–9 and the Persian plate letters
ا ب ت ث ج ح د ز س ش ص ط ع ق ل م ن ه و پ ژ ی.
The complete app (web dashboard, multi-camera streaming, watchlists, API) lives in the GitHub repo. It downloads these models for you.
git clone https://github.com/AliAkrami1375/Platrix.git
cd Platrix
# fetch the models from this repo into ./models
pip install -U "huggingface_hub[cli]"
huggingface-cli download Dibachain/Platrix \
plate_yolo.onnx plate_yolo_fallback.onnx \
ocr_crnn.onnx ocr_crnn.labels.json ocr_cnn.onnx ocr_cnn.labels.json \
--local-dir models/
# then either:
docker compose up --build # Docker
# — or —
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt && pip install -e .
platrix serve # dashboard at http://localhost:8080
pip install onnxruntime opencv-python-headless numpy
huggingface-cli download Dibachain/Platrix \
plate_yolo.onnx plate_yolo_fallback.onnx ocr_crnn.onnx ocr_crnn.labels.json \
--local-dir models/
import json, cv2, numpy as np, onnxruntime as ort
# --- Reader (CRNN + CTC) ---
labels = json.load(open("models/ocr_crnn.labels.json", encoding="utf-8"))
blank = len(labels) # CTC blank is the last index
crnn = ort.InferenceSession("models/ocr_crnn.onnx", providers=["CPUExecutionProvider"])
def read_plate(plate_bgr):
g = cv2.cvtColor(plate_bgr, cv2.COLOR_BGR2GRAY)
g = cv2.resize(g, (128, 32)).astype(np.float32) / 255.0 # 1x1x32x128
logits = crnn.run(None, {"input": g[None, None]})[0][0] # T x (C+1)
ids, out, prev = logits.argmax(1), [], -1
for i in ids: # greedy CTC decode
if i != blank and i != prev:
out.append(labels[i])
prev = i
return "".join(out)
Two-stage flow: run plate_yolo.onnx first (standard YOLOv8 letterbox
pre-process + confidence/NMS post-process) to crop the plate, then pass the crop
to read_plate. If the primary detector returns nothing, run
plate_yolo_fallback.onnx at 640×640 as a second pass — it recovers the hard
surveillance frames the primary is blind to. A few real test photos ship
under img-test/ so you can try it immediately.
۴ vs ۶) are read correctly.Splitting a plate into individual characters is fragile on real photos (shadows, motion blur, tilt, dirt); reading the entire plate at once is far more robust.