Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OCR-BAC2026: Algerian University Orientation Guide Table Extraction Pipeline

A two-pass Vision Language Model (VLM) OCR pipeline designed to segment, filter, and extract structured Arabic table data from the Algerian University Orientation Guide (دليل التوجيه الجامعي).

The pipeline extracts three core fields per academic program:

  1. الرمز (Registration Code): Alphanumeric code identifier (e.g. B02TPN01).
  2. مؤسسة_التكوين (Institution Name): University, institute, or school name in Arabic.
  3. الدوائر_الجغرافية_للتسجيل (Geographic Districts / Wilayas): List of eligible 2-digit wilaya codes (e.g. ["04", "05", "16"]) or ["00"] for national registration (تسجيل وطني).

📁 Repository Structure

OCR-BAC2026/
├── config.py                # Central configuration & tunable hyperparameters
├── prompts.py               # VLM System/User prompts & Ollama native JSON schema
├── main.py                  # End-to-end pipeline execution entrypoint
├── run_pass1.py             # Pass 1: PDF rendering & page triage runner
├── run_pass2.py             # Pass 2: Row segmentation & structured JSON extraction runner
├── models/
│   ├── __init__.py
│   └── vlm_client.py        # Ollama client initialization, retries & VLM caller methods
├── utils/
│   ├── __init__.py
│   ├── image_processing.py  # Computer vision (DPI rendering, band cropping, HSV filter, row segmentation)
│   └── output_handler.py    # Wrapper stripping, JSON parsing, diagnostic logging & CSV exporter
├── data/
│   ├── input/               # Directory for source PDF files
│   ├── intermediate/        # Directory for filtered pages, crop rows, manifest, and JSONL/CSV outputs
│   └── output/              # Final exported output destination
├── requirements.txt         # Required Python dependencies
├── .gitignore               # Git exclusion rules
└── README.md                # Project documentation

⚙️ Architecture & Two-Pass Workflow

Pass 1: Page Triage & Filtering (run_pass1.py)

  • Renders PDF pages at high resolution (300 DPI).
  • Splits each page into 3 horizontal bands with a 10% overlap to handle split tables.
  • Calls a lightweight VLM (qwen3-vl:4b-instruct) with native Ollama JSON schema constraint (JUDGE_JSON_SCHEMA) to detect 3 key data signals (Registration Codes, Institution Names, Wilaya Codes).
  • Strict Decision Logic:
    1. Mandatory Registration Code: A page MUST contain at least one valid registration code adhering strictly to the LDDLLLDD format (1 letter + 2 digits + 3 letters + 2 digits, e.g. B02TPN01). If no valid code is found anywhere on the page, the page is skipped directly.
    2. Multi-Signal Verification: Requires at least 2 total data signals (e.g. code + institution or district) to accept the page.
  • Applies HSV Color Thresholding (turning stamps/highlights white and text pure black) and saves accepted pages to data/intermediate/filtered_pages/.

Pass 2: Row Segmentation & Single-Shot Extraction (run_pass2.py)

  • Segments accepted page images into individual table row crops using OpenCV contour detection of horizontal line separators.
  • Row Triage Filter: Calls qwen3-vl:8b-instruct to classify rows into YES FULL, YES PARTIAL, or NO FULL.
  • Structured Extraction: For valid rows, calls the model using the BALANCED prompt with Ollama's native grammar-constrained format=EXTRACT_JSON_SCHEMA for guaranteed valid JSON output.
  • Merged-Cell Context: Uses previous row context to complete partial rows (where codes or institutions span multiple lines).
  • Outputs raw diagnostic JSONL logs and formatted CSV files under data/intermediate/raw_json/.

🎛️ Tunable Parameters & Configuration Knobs

All pipeline hyperparameters can be tweaked in config.py to optimize for speed, memory, precision, or different visual document layouts.

1. Model & API Parameters

  • JUDGE_MODEL (default: "qwen3-vl:4b-instruct"): VLM used for fast page-level triage in Pass 1.
  • MODEL_NAME (default: "qwen3-vl:8b-instruct"): Primary VLM used for Pass 2 row filtering and extraction.
  • MODEL_NUM_CTX (default: 16384): Token context window allocated for image encoding and extraction response.
  • IMAGE_TIMEOUT (default: 90): Network timeout in seconds for VLM API requests.
  • MAX_RETRIES & RETRY_DELAY (default: 3, 2): Number of retry attempts with exponential backoff on network failures.

2. Image Processing & Computer Vision Knobs

  • DPI (default: 300): PDF rendering resolution. Lower (e.g. 150) speeds up rendering; higher (e.g. 300) improves fine Arabic OCR text clarity.
  • NUM_CROP_BANDS (default: 3): Number of horizontal slices per page in Pass 1 triage.
  • BAND_OVERLAP (default: 0.10): Overlap ratio between adjacent crop bands.
  • SATURATION_THRESH (default: 15): HSV saturation ceiling. Pixels above this are removed (colored stamps, highlighters).
  • BRIGHTNESS_THRESH (default: 200): HSV value floor. Pixels darker than this are enhanced to pure black text.
  • KERNEL_LEN_RATIO (default: 0.40): Minimum horizontal line length ratio relative to page width for row segmentation.
  • MIN_ROW_HEIGHT_PX (default: 15): Minimum pixel height threshold between horizontal table dividers.

3. VLM Sampling Options

  • temperature (default: 0.0): Deterministic greedy decoding.
  • top_p (default: 0.9) & top_k (default: 20): Nucleus sampling bounds.
  • num_predict (default: 8192): Maximum output token generation limit per row extraction call.

🚀 Getting Started

Prerequisites

  1. System Dependencies: Install poppler-utils (required for pdf2image):

    # Ubuntu/Debian
    sudo apt-get update && sudo apt-get install -y poppler-utils
  2. Ollama VLM Models: Pull the required vision models:

    ollama pull qwen3-vl:4b-instruct
    ollama pull qwen3-vl:8b-instruct
  3. Python Environment:

    pip install -r requirements.txt

🏃 Running the Pipeline

Run Full Pipeline End-to-End

python main.py

Run Pass 1 Only (Page Triage & Filtering)

python run_pass1.py

Run Pass 2 Only (Row Segmentation & Structured Extraction)

python run_pass2.py

📊 Output Files

  • data/intermediate/filtered_pages/manifest.json: Contains page triage evidence and list of accepted/rejected pages.
  • data/intermediate/raw_json/page_{N}_raw.jsonl: Detailed line-by-line JSONL records containing raw model inputs/outputs.
  • data/intermediate/raw_json/page_{N}_raw.csv: UTF-8 encoded CSV file of extracted program codes, Arabic institution names, and wilaya lists.
  • data/intermediate/raw_model_output/thinking_process.txt: Timestamped text log capturing full model responses and token evaluation statistics.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages