Skip to main content

Arabic handwritten text recognition — CRNN-CTC with Arabic-specific multi-scale vertical encoding, trained on the KHATT dataset

Project description

ArabicOCR-KHATT — Arabic Handwritten Text Recognition (CRNN-CTC)

PyPI License: MIT Model on HF

Arabic handwritten text recognition — line-level OCR (a line or paragraph image → Arabic text), trained on the KHATT dataset.

What makes it Arabic-specific rather than a generic CRNN:

  • 3-zone vertical pooling — preserves where dots sit (above vs below the baseline), the only difference between ب/ت/ث and ن/ي
  • Input height 96 — keeps diacritic dots large enough (3–5 px) for 3×3 convolutions to detect
  • Dot-safe augmentation — shear, kashida stretch, mild rotation; erosion / dilation / elastic are banned because they destroy 2–4 px dots
  • Beam-search decoding with an Arabic character bigram LM
  • Dot-group CER metric — tracks errors on dot-differentiated letter groups, the #1 Arabic OCR error source

Install

pip install arabicocr-khatt

Quickstart

from arabicocr_khatt import ArabicOCR

ocr = ArabicOCR.from_pretrained()        # downloads weights from the HF Hub
text = ocr.recognize("handwritten_page.jpg")   # multi-line pages segmented automatically
print(text)

Or from the command line:

arabicocr handwritten_page.jpg
arabicocr line.png --no-segment --greedy       # single line, fastest decode
arabicocr scan.jpg --checkpoint runs/exp1/crnn_best.pt   # local weights

Try it in the browser: demo Space on Hugging Face.


Architecture

Input [B, 1, 96, 1536] grayscale
  → CNN (7 conv layers, full BatchNorm, Dropout2d)
  → adaptive pool to 3 vertical zones (dot position preserved)
  → 2-layer BiLSTM(1536 → 384)
  → FC → CTC loss
  → greedy or beam-search decode (+ Arabic bigram LM), reversed back to RTL

Preprocessing (shared between training and inference): grayscale → CLAHE → dual-polarity Otsu binarization → LANCZOS resize to H=96 → pad to W=1536.

Project structure

ArabicOCR_KHATT/
├─ arabicocr_khatt/            # the installable package
│  ├─ pipeline.py              # ArabicOCR API + CLI (inference single-source)
│  ├─ model.py                 # CRNN + CTC decoders + bigram LM builder
│  ├─ preprocess.py            # CLAHE, binarization, resize, padding
│  ├─ augment.py               # Arabic-safe augmentation
│  ├─ dataset.py               # KHATTDataset
│  ├─ metrics.py               # CER / WER / dot-group CER
│  ├─ train_crnn_ctc.py        # training script
│  ├─ webocr.py                # Gradio test bench (rich debugging UI)
│  ├─ show_metrics.py, monitor.py, compare_runs.py, eval_val.py, ...
│  └─ charset_arabic.txt       # 75-class charset
├─ scripts/upload_to_hf.py     # publish weights + model card to the HF Hub
├─ space/                      # Hugging Face Space demo app
├─ archive/                    # (gitignored) KHATT images + labels + splits
├─ runs/                       # (gitignored) checkpoints + metrics.csv
└─ pyproject.toml

Training your own model

Get the KHATT dataset (request access at khatt.ideas2serve.net) and lay it out as:

archive/
├─ images/   *.jpg            # line images
├─ labels/   *.txt            # Arabic text (Windows-1256 / UTF-8)
└─ splits/                    # auto-created train/val/test CSVs (80/10/10)

Then, with the training extras installed:

pip install -e ".[train]"
python -m arabicocr_khatt.train_crnn_ctc                 # trains to runs/exp1
python -m arabicocr_khatt.show_metrics --run ./runs/exp1 # inspect metrics
python -m arabicocr_khatt.monitor                        # live training dashboard

Training uses OneCycleLR, gradient accumulation, early stopping, and logs per-epoch CER / WER / WER(norm) / dot-group CER to runs/<exp>/metrics.csv. Checkpoints are saved as {"model": state_dict, "vocab": [...], "arch_version": 2}.

Web test bench (Gradio)

A rich debugging UI with crop/rotate, polarity control, decoder comparison, confidence heatmaps, char-level diff against ground truth, and batch evaluation:

pip install -e ".[demo]"
python -m arabicocr_khatt.webocr

Publishing weights to the Hub

After training (on the machine that has runs/ and archive/):

hf auth login
python scripts/upload_to_hf.py --run-dir runs/exp1

This validates the checkpoint, builds the bigram LM from the training split, fills the model card with your best-epoch metrics, and uploads everything to FixFips/arabicocr-khatt.


Notes and limitations

  • Trained on KHATT: performance is best on handwriting similar to that dataset. Printed fonts, very noisy backgrounds, or strongly curved text may fail.
  • Line-level model: pages are segmented into lines with classical morphology; complex layouts may segment poorly.
  • Labels use Windows-1256 encoding (KHATT standard); the reader falls back to UTF-8 automatically.

Contributing

Contributions are very welcome — Arabic OCR is an underserved area and there is plenty to do. See CONTRIBUTING.md and the good first issues.

License

MIT — see LICENSE.

If you use this project in research, please also cite the KHATT dataset:

Mahmoud, S. A., et al. "KHATT: An open Arabic offline handwritten text database." Pattern Recognition 47.3 (2014): 1096–1112.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

arabicocr_khatt-0.1.0.tar.gz (59.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

arabicocr_khatt-0.1.0-py3-none-any.whl (65.8 kB view details)

Uploaded Python 3

File details

Details for the file arabicocr_khatt-0.1.0.tar.gz.

File metadata

  • Download URL: arabicocr_khatt-0.1.0.tar.gz
  • Upload date:
  • Size: 59.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for arabicocr_khatt-0.1.0.tar.gz
Algorithm Hash digest
SHA256 7305298604c44d13f8299a44117fa7cf92f59f457a3f1a9227e40577573acbf6
MD5 037df7a160459ee673de91c1be3a448e
BLAKE2b-256 67bef3802f7325812ec9fa9492b4c9e1bafdfb54575f999db930b5c8bb2bf7a3

See more details on using hashes here.

File details

Details for the file arabicocr_khatt-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: arabicocr_khatt-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 65.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for arabicocr_khatt-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a6f4bc2cb05953d06b0dc810ed526558bb3ad044e9e41cc41bbd2011719cc832
MD5 16a6aac6295bb505186fe78e55ed7649
BLAKE2b-256 35c43076117ccc0e67cc841752b5ca5c992d1f2093bc1337a7bc7b38e21ae619

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page