šŸ”„ 0
⭐ 0
Lesson 4 of 5 25 min +100 XP

Hybrid Mode & OCR

OpenDataLoader's hybrid mode combines local processing with AI-powered extraction for the best of both worlds. In this lesson, you'll learn when and how to use it.

Understanding Processing Modes

ModeSpeedAccuracyUse Case
LocalFast (~0.1s/page)GoodClean, digital PDFs
HybridMedium (~0.5s/page)Best (0.907)Complex documents
Force OCRSlowerVariableScanned documents

Setting Up Hybrid Mode

Hybrid mode requires the OpenDataLoader server running locally:

Step 1: Start the Server

# Install and start the hybrid server
pip install opendataloader-pdf[hybrid]
opendataloader-server start

Or using Docker:

docker run -p 8000:8000 opendataloader/hybrid-server

Step 2: Use Hybrid Mode

import opendataloader_pdf

opendataloader_pdf.convert(
    input_path="complex-document.pdf",
    output_dir="output/",
    format="json",
    hybrid=True  # Enable AI-enhanced extraction
)

OCR for Scanned Documents

Automatic OCR Detection

OpenDataLoader automatically detects scanned pages and applies OCR:

# OCR is automatic when needed
opendataloader_pdf.convert(
    input_path="scanned-contract.pdf",
    output_dir="output/",
    format="markdown"
)

Forcing OCR

Sometimes PDFs have embedded text that's incorrect (copy-paste garbled text). Force OCR to re-extract:

opendataloader_pdf.convert(
    input_path="garbled-text.pdf",
    output_dir="output/",
    format="markdown",
    force_ocr=True  # Ignore embedded text, use OCR
)

Multi-Language OCR

Specify language(s) for better accuracy:

# Single language
opendataloader_pdf.convert(
    input_path="german-document.pdf",
    output_dir="output/",
    format="markdown",
    ocr_lang="deu"  # German
)

# Multiple languages
opendataloader_pdf.convert(
    input_path="multilingual.pdf",
    output_dir="output/",
    format="markdown",
    ocr_lang="eng+fra+deu"  # English, French, German
)

Common Language Codes

CodeLanguage
engEnglish
fraFrench
deuGerman
spaSpanish
chi_simChinese (Simplified)
chi_traChinese (Traditional)
jpnJapanese
korKorean
araArabic
hinHindi

Formula Extraction

OpenDataLoader extracts mathematical formulas as LaTeX:

opendataloader_pdf.convert(
    input_path="math-paper.pdf",
    output_dir="output/",
    format="json",
    hybrid=True  # Needed for formula extraction
)

Formula Output

{
  "type": "formula",
  "page number": 3,
  "bounding box": [100.0, 400.0, 450.0, 450.0],
  "content": "E = mc^2",
  "latex": "E = mc^{2}"
}

Complex Formulas

{
  "type": "formula",
  "content": "integral",
  "latex": "\\int_{0}^{\\infty} e^{-x^2} dx = \\frac{\\sqrt{\\pi}}{2}"
}

Using Extracted Formulas

import json

with open('output/math-paper.json', 'r') as f:
    data = json.load(f)

# Extract all formulas
formulas = [el for el in data['kids'] if el['type'] == 'formula']

for formula in formulas:
    print(f"Formula on page {formula['page number']}:")
    print(f"  LaTeX: {formula.get('latex', formula['content'])}")

Image Descriptions

Hybrid mode can generate AI descriptions for images:

opendataloader_pdf.convert(
    input_path="report-with-charts.pdf",
    output_dir="output/",
    format="json",
    hybrid=True,
    describe_images=True  # Generate image descriptions
)

Image Output

{
  "type": "image",
  "page number": 2,
  "bounding box": [72.0, 300.0, 400.0, 500.0],
  "content": "Bar chart showing quarterly revenue growth from Q1 to Q4 2024, with values increasing from $1.2M to $2.8M",
  "image_path": "output/images/image_002_001.png"
}

When to Use Hybrid Mode

Use Hybrid Mode For:

  • Scanned documents - OCR extraction
  • Complex tables - Better structure detection
  • Mathematical papers - LaTeX formula extraction
  • Documents with charts - Image descriptions
  • Multi-column academic papers - Improved reading order

Stay with Local Mode For:

  • Clean digital PDFs - No AI needed
  • High-volume processing - Speed priority
  • Sensitive documents - No external API calls
  • Simple text extraction - Overkill for basic needs

Checking Document Quality

Before choosing a mode, analyze the PDF:

import opendataloader_pdf
import json

# Quick analysis with local mode
opendataloader_pdf.convert(
    input_path="document.pdf",
    output_dir="output/",
    format="json"
)

with open('output/document.json', 'r') as f:
    data = json.load(f)

# Check for potential issues
elements = data['kids']
tables = [e for e in elements if e['type'] == 'table']
formulas = [e for e in elements if e['type'] == 'formula']
images = [e for e in elements if e['type'] == 'image']

print(f"Tables: {len(tables)}")
print(f"Formulas: {len(formulas)}")
print(f"Images: {len(images)}")

# Recommend hybrid if complex elements found
if formulas or len(tables) > 5:
    print("\n→ Consider using hybrid mode for better accuracy")

Challenge: Scanned Document Processor

Create a script that:

  • Detects if a PDF is scanned (image-based)
  • Applies appropriate OCR settings
  • Extracts and validates the text quality
import opendataloader_pdf
import json

def process_scanned_document(pdf_path, language='eng'):
    """
    Process a potentially scanned PDF with smart OCR handling.
    """
    # Your code here:
    # 1. First, try local extraction
    # 2. Check if text was extracted (or if it's mostly images)
    # 3. If scanned, re-process with OCR
    # 4. Validate extraction quality
    # 5. Return structured data

    pass

def detect_scanned_pdf(json_data):
    """
    Heuristic to detect if PDF is scanned.
    Returns True if likely scanned.
    """
    elements = json_data.get('kids', [])

    # Count element types
    images = sum(1 for e in elements if e['type'] == 'image')
    text_elements = sum(1 for e in elements if e['type'] in ['paragraph', 'heading'])

    # High image-to-text ratio suggests scanned
    if images > 0 and text_elements == 0:
        return True

    # Check for very short text content (garbled OCR)
    total_text = sum(len(e.get('content', '')) for e in elements)
    if total_text < 100 and images > 0:
        return True

    return False

# Process a document
result = process_scanned_document("mystery-document.pdf", language="eng")
print(result)

Expected output:

Analyzing: mystery-document.pdf
- Initial extraction: 2 images, 0 text elements
- Detected as: SCANNED DOCUMENT
- Applying OCR with language: eng
- Re-extraction: 0 images, 45 text elements
- Text quality score: 0.92

Extraction complete:
- Pages: 3
- Paragraphs: 42
- Headings: 3
- Total words: 1,847

🧠 Quick Quiz

Test your understanding of this lesson.

1

When should you use hybrid mode?

2

What does --force-ocr do?

3

What format does formula extraction use?

Table Extraction