Skip to main content

anyocr

One unified API over every major OCR engine — from Tesseract to vision LLMs.

PyPI Python License

anyocr gives you a single anyocr.read() call that extracts text from images and documents using whichever OCR engine you have installed. It auto-selects the best available backend by priority (Surya > EasyOCR > PaddleOCR > Tesseract > Vision-LLM), applies a smart preprocessing pipeline (auto-rotate, deskew, contrast enhancement, binarization), and returns structured results with bounding boxes, confidence scores, and reading order.

Built by Viet-Anh Nguyen at NRL.ai.

Why anyocr?

  • One-liner API — anyocr.read("scan.png") just works with any installed backend
  • Plugin architecture — Register new OCR engines via @register_backend
  • Local-first — Surya, EasyOCR, Paddle, Tesseract all run on your machine
  • Minimal core deps — Only pillow and numpy; every OCR engine is an optional extra
  • Production-ready — Auto-preprocessing, structured dataclass results, batch inference

Installation

pip install anyocr

For optional backends:

pip install anyocr[surya]        # Surya OCR — SOTA open source, 90+ languages
pip install anyocr[easyocr]      # EasyOCR — CRNN models, 80+ languages
pip install anyocr[paddle]       # PaddleOCR — strong Asian languages
pip install anyocr[tesseract]    # Tesseract via pytesseract (needs tesseract binary)
pip install anyocr[vlm]          # Vision-LLM via anyllm (GPT-4V, Claude, Gemini)
pip install anyocr[all]          # everything

Python 3.8+ supported (tested on 3.8, 3.9, 3.10, 3.11, 3.12, 3.13)

Quick Start

import anyocr

# 1. Auto-selects the best installed backend (Surya > EasyOCR > Paddle > Tesseract > VLM)
result = anyocr.read("receipt.png")
print(result.text)                       # full extracted text
for line in result.lines:
    print(line.text, line.confidence, line.bbox)

# 2. Force a specific backend
text = anyocr.read("chinese.jpg", backend="paddle", lang="ch").text

# 3. Use a vision LLM for hard cases (tables, handwriting)
text = anyocr.read("handwritten.jpg", backend="vlm", model="gpt-4o").text

Models & Methods

Supported backends (auto-selected by priority)

Priority Backend Model family Languages Install
1 Surya OCR Transformer-based detection + recognition (DETR + Donut-style) 90+ anyocr[surya]
2 EasyOCR CRAFT detector + CRNN recognizer 80+ anyocr[easyocr]
3 PaddleOCR PP-OCRv4 (DBNet + SVTR) 80+, strong CJK anyocr[paddle]
4 Tesseract LSTM-based (Tesseract 4+) 100+ anyocr[tesseract]
5 Vision-LLM Any multi-modal LLM via anyllm (GPT-4V, Claude 3.5 Sonnet, Gemini, LLaVA) Any anyocr[vlm]

You can change the priority or force a backend via anyocr.read(..., backend="easyocr") or anyocr.set_priority(["paddle", "surya"]).

Preprocessing pipeline

Applied automatically (can be disabled per call):

  1. EXIF orientation fix — rotate based on metadata
  2. Auto-rotate — detect 90/180/270 rotation via text-line angle histogram
  3. Deskew — Hough-transform-based angle correction (<= 15 degrees)
  4. Contrast enhancement — CLAHE (adaptive histogram equalization)
  5. Binarization — adaptive threshold for low-quality scans (opt-in)
  6. Denoise — bilateral filter for scanned documents (opt-in)

Result dataclasses

@dataclass
class OCRLine:
    text: str
    confidence: float
    bbox: tuple[float, float, float, float]   # x1, y1, x2, y2
    polygon: list[tuple[float, float]] | None  # 4-point quad if supported

@dataclass
class OCRResult:
    text: str                  # joined full text in reading order
    lines: list[OCRLine]
    backend: str               # which backend produced this result
    language: str | None

API Reference

Function Purpose
anyocr.read(image, backend="auto", lang=None) Run OCR, returns OCRResult
anyocr.read_pdf(pdf_path) OCR every page of a PDF
anyocr.list_backends() Show installed backends
anyocr.set_priority([...]) Override auto-selection order
anyocr.preprocess(image, ops=[...]) Run preprocessing pipeline only
anyocr.register_backend(name, cls) Add a custom backend

CLI Usage

anyocr read receipt.png
anyocr read scan.jpg --backend paddle --lang ch
anyocr read-pdf document.pdf --out text.txt
anyocr list-backends

Examples

OCR an entire PDF and save as text

import anyocr

# Rasterizes each page and runs the auto-selected backend
result = anyocr.read_pdf("report.pdf")
with open("report.txt", "w") as f:
    for page_num, page in enumerate(result.pages, 1):
        f.write(f"=== Page {page_num} ===\n{page.text}\n\n")

Combine preprocessing with a specific backend

import anyocr

# Run the preprocessing pipeline explicitly before OCR
cleaned = anyocr.preprocess("noisy_scan.jpg", ops=["deskew", "clahe", "binarize"])
result  = anyocr.read(cleaned, backend="tesseract", lang="eng")
print(result.text)

Compare two backends on the same image

import anyocr

for backend in ["surya", "easyocr", "paddle"]:
    r = anyocr.read("test.jpg", backend=backend)
    print(f"{backend}: {r.text[:80]}... (avg conf {r.mean_confidence():.2f})")

License

MIT (c) Viet-Anh Nguyen

Release files for anyocr 0.2.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for anyocr 0.2.4
File Size Uploaded
anyocr-0.2.4.tar.gz 40.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for anyocr 0.2.4
File Interpreter ABI Platform
anyocr-0.2.4-py3-none-any.whl Python 3 none any Details

Total release size: 76.5 kB

Release files / anyocr-0.2.4.tar.gz

Download URL anyocr-0.2.4.tar.gz
Size 40.0 kB
Tags Source
SHA-256 checksum
How to use checksums
ee5e0862ce781d743b7d176141509dfa52ea698e6c6ec498fb9d50fa3bba2f5b
BLAKE2b-256 checksum
How to use checksums
31c07438533af7d245f9d0ddad60925edf9bb14f2143f7cbf6b7362d7ff211ec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.9

Release files / anyocr-0.2.4-py3-none-any.whl

Download URL anyocr-0.2.4-py3-none-any.whl
Size 36.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2661b06ee9a1188afc9631f3bf02e3f33e705af8c1201d3d1be21e1a772e096b
BLAKE2b-256 checksum
How to use checksums
4554fe25ecc0c0ea85ebc54a2c817e25735d3343986a7d2dbff1d418491b3b4e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.9

Release history Release notifications | RSS feed

This release

0.2.4 This release

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page