Handwritten Greek OCR

An ONNX model for recognizing handwritten Greek text, fine-tuned from PaddlePaddle's PP-OCRv5 server-grade recognition checkpoint. This fine-tune adapts it specifically to the Greek alphabet.

The model was trained on a synthetic dataset of 50,000 images generated using handwritten Greek fonts and containing up to 50 characters (including spaces).


Examples

Input Image Predicted Text Confidence
example 1 η διαδικασία είναι περίπλοκη 0.9450
example 2 η διαδικασία είναι περίπλοκη 0.9595
example 3 Ο Γιώργος ο Γιάννης (missed the comma) 0.8893
example 3 Ο Γιώργος, ο Γιάννης 0.9575

Input & Preprocessing

  • Color format: BGR (converted from RGB to match PaddleOCR training convention)
  • Resize: image is scaled to height 48px, width padded to 320px with zeros
  • Normalization: pixel values normalized to [-1, 1]

Limitations

  • Designed for single text-line images — for multi-line documents, segment lines before running inference.
  • Can mostly recognise Greek characters and punctuation .

Quick Start

Installation

pip install onnxruntime pillow numpy
# For GPU support:
pip install onnxruntime-gpu pillow numpy

Inference

from PIL import Image
import numpy as np
import math
import onnxruntime as ort

def resize_norm_img(img, imgH=48, imgW=320):
    h, w = img.shape[:2]
    ratio = w / float(h)
    resized_w = imgW if math.ceil(imgH * ratio) > imgW else int(math.ceil(imgH * ratio))
    pil_img = Image.fromarray(img)
    resized_image = np.array(pil_img.resize((resized_w, imgH), Image.BILINEAR)).astype('float32')
    resized_image = resized_image.transpose((2, 0, 1)) / 255.0
    resized_image = (resized_image - 0.5) / 0.5
    padding_im = np.zeros((3, imgH, imgW), dtype=np.float32)
    padding_im[:, :, :resized_w] = resized_image
    return np.expand_dims(padding_im, axis=0)

def load_dict(dict_path):
    with open(dict_path, "rb") as f:
        lines = f.readlines()
    character = [line.decode('utf-8').strip() for line in lines] + [" "]
    return ['<blank>'] + character

def decode(preds, character):
    preds_idx = preds.argmax(axis=2)[0]
    preds_prob = preds.max(axis=2)[0]
    char_list, conf_list = [], []
    for i, idx in enumerate(preds_idx):
        if idx != 0 and not (i > 0 and idx == preds_idx[i - 1]):
            char_list.append(character[idx])
            conf_list.append(preds_prob[i])
    text = ''.join(char_list)
    confidence = float(np.mean(conf_list)) if conf_list else 0.0
    return text, confidence

# Load model and dictionary
session = ort.InferenceSession("model.onnx", providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])
characters = load_dict("greek_dict.txt")

# Run on an image
img = np.array(Image.open("your_image.png").convert("RGB"))
img_bgr = img[:, :, ::-1]  # RGB → BGR
input_tensor = resize_norm_img(img_bgr)

outputs = session.run(None, {session.get_inputs()[0].name: input_tensor})
text, confidence = decode(outputs[0], characters)

print(f"Recognized: {text}")
print(f"Confidence: {confidence:.4f}")

Model Details

Property Value
Task Handwritten Greek text recognition
Architecture SVTR_HGNet (PPHGNetV2_B4 backbone + SVTR neck, CTC head)
Format ONNX
Input size 3 × 48 × 320 (C × H × W)
Language Greek (el)
Runtime ONNX Runtime (CPU & CUDA)

Repository Files

├── model.onnx        # ONNX model weights
├── greek_dict.txt    # Greek character dictionary
├── inference.py      # Ready-to-run inference script
└── test.png          # Sample test image

Citation

If you use this model, please cite this repository:

@misc{handwritten-greek-ocr,
  title  = {Handwritten Greek OCR},
  author = {Iordanis Sapidis},
  year   = {2026},
  url    = {https://huggingface.co/iordanissap/handwritten-greek-ocr}
}
Downloads last month
367
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support