Persian OCR — Image-to-Text API for Persian & English
An image-to-text system for Persian and English: a REST API built around a custom CNN trained to recognize Persian letters, and a mobile client that captures images. Users upload an image, preview the result and confirm it, choosing per request between the custom model and Tesseract.
Overview
An image-to-text system for Persian and English: a REST API built around a custom CNN trained to recognize Persian letters, and a mobile client that captures images. Users upload an image, preview the result and confirm it, choosing per request between the custom model and Tesseract.
Problem
Persian is hard for general-purpose OCR: letters change shape with their position in a word and connect to their neighbours, and open-source engines handle the script far less reliably than Latin text. The project set out to recognize Persian letters with a purpose-built model while keeping a mature engine available for comparison and fallback.
Solution
A Django REST backend runs a two-step upload → preview → confirm flow. A preprocessing pipeline deskews the page and splits it into lines, words and characters; the characters are classified by a custom LeNet-5 CNN, or the page is passed to Tesseract, depending on the engine the user selects. A spell-correction step checks each recognized word against a 17K-word Persian dictionary and replaces it with the same-length candidate that matches it best character by character. A translation endpoint completes the API.
Architecture
Mobile client (image capture) → Django REST API → OCR engine → spell correction → result. The backend is Django + Django REST Framework with JWT authentication and PostgreSQL, deployed with Docker. Requests follow a two-step upload → preview → confirm flow. Recognition sits behind an engine choice: an OpenCV pipeline (deskew, then line, word and character segmentation) feeds the TensorFlow/Keras LeNet-5 classifier — 73 classes, trained on 570K images from the team’s own Kaggle dataset — while Tesseract handles the alternative path. Recognized words then pass through dictionary-based spell correction before being returned.
Challenges
Running two OCR engines behind one API, so each request can choose the custom CNN or Tesseract without the rest of the flow changing.
Segmenting connected Persian script into lines, words and individual characters after deskewing, so a per-character classifier receives clean input.
Correcting recognition errors without a language model: matching each word against a 17K-word dictionary, limited to same-length candidates and scored character by character.
Outcomes
A working image-to-text API for Persian and English with a preview-and-confirm flow, JWT authentication and a Dockerized deployment.
A custom LeNet-5 model covering 73 classes, trained on 570K images from the team’s own Kaggle dataset, integrated alongside Tesseract.
Dictionary-based spell correction and a translation endpoint on top of recognition.
Lessons Learned
Data quality matters far more than model architecture for OCR accuracy in practice.
Preprocessing — deskewing and clean segmentation — decides how well a character classifier can do before the model sees a single pixel.
Keeping a mature engine beside a custom model gives a baseline to measure against and a fallback when the custom path struggles.


