Home / Blog / Amharic OCR & Document Intelligence
blog

Amharic OCR & Document Intelligence

WesenAI Research Team • •
#amharic#ocr#ai#ge'ez#computer-vision#trocr#deep-learning
Amharic OCR & Document Intelligence

1. Morphological and Geometric Challenges

The Ethiopic writing system (an abugida or alphasyllabary) encodes consonants and vowels into unified syllographs across seven standard orders:

Order:     1st (ä)   2nd (u)   3rd (i)   4th (a)   5th (e)   6th (ə)   7th (o)
Syllable:    በ         ቡ         ቢ         ባ         ቤ         ብ         ቦ
IPA:       [bɐ]      [bu]      [bi]      [ba]      [be]      [bɨ]      [bo]

Large Inventory, Small Stroke Differences

An Ethiopic OCR model must distinguish over 300 syllabic glyphs, plus numerical ciphers (፩ to ፼) and punctuation delimiters (፡, ።, ፣, ፤).

Vowel changes appear as small variations on the base consonant:

  • Foot appendages: Adding a small right-hand horizontal or vertical foot (e.g., በ → ቡ in the 2nd order, ለ → ሉ).
  • Shortening/Extension of limbs: In the 3rd order, shortening the right limb and attaching a horizontal cross-stroke (e.g., በ → ቢ).
  • Base stroke modifications: Rounding, slanting, or modifying loops (e.g., በ → ቤ in the 5th order, በ → ቦ in the 7th order).
Confusion Set A (Intra-character order shifts):
  በ (1st: [bɐ])  vs.  ቤ (5th: [be])  vs.  ቦ (7th: [bo])
  ነ (1st: [nɐ])  vs.  ኔ (5th: [ne])  vs.  ኖ (7th: [no])

Confusion Set B (Inter-character structural twins):
  ሀ (hä)  vs.  በ (bä)  vs.  ከ (kä)
  አ (ʔä)  vs.  ዐ (ʕä)  vs.  የ (yä)
  ገ (gä)  vs.  ጉ (gu)  vs.  ጎ (go)

In low-resolution scans, paper bleed, ink spread, and photocopy degradation can erase or connect these strokes.


2. Document Degradation

  1. Vellum Parchment (Branna) Manuscripts: Hand-scribed with carbon-black and cinnabar-red inks on sheepskin or goatskin. Non-uniform ruling, warping, ink oxidation, and historical Ge’ez abbreviations (seraye) challenge line segmentation.
  2. 20th Century Letterpress and Typewriters (Negarit Gazeta, 1940s–1980s): Mechanical wear caused ink spread and tilt. Glyphs often touch or fuse, which breaks heuristic character segmentation.
  3. Mimeographed & Thermal Invoices: Tax invoices, land registries, and clinic logs printed on thermal or thin paper with uneven toner density.

3. Architectures

Analytical Segmentation

Early Amharic OCR systems (Worku, Cowell, Assabie) used horizontal and vertical projection profiles to slice images into lines, words, and character bounding boxes. Multi-limb characters overlap vertically and letters touch, so segmentation errors compounded downstream.

CRNN (CNN + BiLSTM + CTC)

Connectionist Temporal Classification (CTC) removed the need for character segmentation. The model scans full text lines:

  • A Convolutional Network (ResNet / VGG) extracts visual feature maps.
  • A Bidirectional LSTM models horizontal sequence dependencies.
  • A CTC Loss Layer computes the alignment between visual frames and the target text sequence.

Vision-Language Transformers (TrOCR)

Microsoft’s TrOCR combines a pre-trained Vision Transformer (ViT) image encoder with a language model decoder (e.g., RoBERTa or BART).

flowchart LR
    A["Raw Document Image<br/>(Text Line / Crop)"] --> B["Image Preprocessing<br/>(Binarization & Dewarp)"]
    B --> C["Vision Transformer (ViT)<br/>Patch Embeddings (16x16)"]
    C --> D["Cross-Attention Layer"]
    D --> E["Autoregressive Text Decoder<br/>(Ethiopic Subword BPE)"]
    E --> F["Predicted Unicode Text<br/>'ኢትዮጵያ በታሪክ...'"]

The ViT processes image patches without horizontal slicing, and the decoder’s language model prior can use context to reconstruct smudged characters.


4. Implementation: Preprocessing and Tesseract

import cv2
import numpy as np
import pytesseract

class EthiopicDocumentOCR:
    def __init__(self):
        # Use Tesseract 5 LSTM engine with Amharic language pack
        self.tess_config = r'--oem 1 --psm 6 -l amh'

    def preprocess_document(self, image_path: str) -> np.ndarray:
        """Removes paper stains, corrects illumination, and binarizes degraded documents."""
        img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
        
        # Step 1: Remove illumination gradients via morphological closing
        kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (25, 25))
        background = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
        normalized = cv2.divide(img, background, scale=255)
        
        # Step 2: Otsu's adaptive thresholding with Gaussian blur
        blurred = cv2.GaussianBlur(normalized, (3, 3), 0)
        _, binarized = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
        
        return binarized

    def recognize_text(self, processed_img: np.ndarray) -> str:
        return pytesseract.image_to_string(processed_img, config=self.tess_config)

# Demonstration
ocr_engine = EthiopicDocumentOCR()
preprocessed = ocr_engine.preprocess_document("legal_gazette_sample.png")
extracted_text = ocr_engine.recognize_text(preprocessed)
print("Extracted Amharic Text:\n", extracted_text)