license: mit
library_name: onnx
pipeline_tag: image-classification
tags:
- ocr
- persian
- farsi
- alpr
- anpr
- license-plate
- iran
- onnx
- computer-vision
language:
- fa
Persian OCR — Character Recognition (ONNX)
A compact convolutional neural network that recognizes Persian license‑plate
characters — the digits 0–9 and the Persian letters used on Iranian vehicle
plates — trained on real‑world plate character crops. It is the OCR stage of
the Platrix real‑time ALPR engine and ships as a portable ONNX graph, so
it runs anywhere ONNX Runtime runs — no TensorFlow or
PyTorch required at inference time.
- Task: single‑character image classification (28 classes)
- Input:
1 × 1 × 32 × 32grayscale tensor, values in[0, 1](white glyph on black) - Output:
1 × 44logits →argmax→ character via the bundled label map - Format: ONNX (opset 13), ~2.2 MB
- Author: Dibachain
Project & source code: https://github.com/AliAkrami1375/Platrix
Files
| File | Description |
|---|---|
ocr_cnn.onnx |
The inference graph (opset 13) |
ocr_cnn.labels.json |
Ordered list mapping each output neuron to its character |
How the pipeline works
Platrix reads a plate in three stages; this model is stage 3:
- Detect the plate region in the frame.
- Segment the plate into individual character images (normalized to a
white‑on‑black
32 × 32glyph). - Recognize each glyph with this model and assemble the plate string.
The training images are preprocessed identically to the segmenter's output (Otsu binarization, tight crop, square‑pad, resize) so the model sees the same glyph framing in training and in production. Training also applies random affine augmentation (scale / shift / rotation) for robustness to how characters are framed.
Usage
import json
import numpy as np
import onnxruntime as ort
from huggingface_hub import hf_hub_download
onnx_path = hf_hub_download("Dibachain/ocr-persian", "ocr_cnn.onnx")
labels_path = hf_hub_download("Dibachain/ocr-persian", "ocr_cnn.labels.json")
labels = json.load(open(labels_path, encoding="utf-8"))
session = ort.InferenceSession(onnx_path, providers=["CPUExecutionProvider"])
input_name = session.get_inputs()[0].name
def classify(glyph_32x32_uint8):
"""glyph: a 32x32 grayscale image, white character on black background."""
x = (glyph_32x32_uint8.astype("float32") / 255.0).reshape(1, 1, 32, 32)
logits = session.run(None, {input_name: x})[0]
return labels[int(np.argmax(logits))]
With Platrix (end‑to‑end plate reading)
git clone https://github.com/AliAkrami1375/Platrix.git
cd Platrix
pip install -r requirements.txt
# place ocr_cnn.onnx + ocr_cnn.labels.json in ./models/
PLATRIX_OCR=onnx platrix serve # dashboard on http://localhost:8080
Labels
28 classes: the digits 0–9 and the Persian letters that appear on Iranian
plates (ا ب پ ت ج د س ص ط ع ق ل م ن و ه ی and special markers). Each neuron
maps to exactly one plate character; the exact order is in ocr_cnn.labels.json.
Model architecture
A small CNN: Conv(32) → Conv(32) → MaxPool → Conv(64) → MaxPool → FC(128) → FC(28)
with dropout, trained with Adam and cross‑entropy on real plate character crops
with affine augmentation (~98% validation accuracy).
Intended use & limitations
- Intended for parking, access control and traffic‑analytics pipelines that first detect and segment plates, then classify each character with this model.
- Not an end‑to‑end plate reader on its own — it classifies single, pre‑segmented characters. Overall accuracy on a full plate depends on the quality of the upstream detection and segmentation.
- Real‑world plates vary in font, angle, lighting and wear; for best results, pair with a strong plate detector and clean segmentation.
License
Released under the MIT License. © Dibachain.