Skip to content

About

A superfast, lightweight, memory-efficient CPU-only OCR API.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

Repository files navigation

OCR Service

A superfast, lightweight, memory-efficient CPU-only OCR API. Upload any image (PNG/JPEG/GIF/BMP/TIFF/WebP) or PDF and get per-page OCR text with line boxes and confidence — no GPU, no LLM, no external OCR daemon.

document type handling typical latency
image RapidOCR PP-OCRv5 (ONNX Runtime, CPU) ~0.2–1 s/page
digital PDF text layer read directly (no OCR at all) ~10–50 ms
scanned PDF render page via pdftoppm, then OCR ~1–2 s/page
same doc again SHA-256 result cache ~1 ms

How it works

  • RapidOCR PP-OCRv5 (PP-OCRv5_mobile det + cls + rec models) runs on ONNX Runtime with a single intra-op thread — ideal for shared CPU hosts. Models are embedded in the binary and extracted to the cache dir on first run.
  • Only a small C library is needed at runtime: libonnxruntime.so (Linux) / libonnxruntime.dylib (macOS). Place it next to the binary or point ORT_LIB_PATH at it.
  • Digital PDFs never touch the OCR engine: their embedded text layer is extracted with a pure-Go PDF reader. Pages without a text layer are rendered with pdftoppm (poppler-utils) and OCR'd, in parallel.
  • The response is plain OCR data — no schema, no heuristics, no LLM. Your app does the parsing.

Build

make build       # equivalent to: go build -o invoiceocr .

go:embed bundles the ONNX models into the binary; go build requires the models/ directory (already in the repo).

Runtime dependency

Download libonnxruntime.so from an onnxruntime release (≥ 1.24) and put it next to the binary:

curl -LO https://github.com/microsoft/onnxruntime/releases/download/v1.24.1/onnxruntime-linux-x64-1.24.1.tgz
tar xzf onnxruntime-linux-x64-1.24.1.tgz --strip-components=1 onnxruntime-linux-x64-1.24.1/lib/libonnxruntime.so

Run

make run                      # builds then serves on 127.0.0.1:8080
./invoiceocr                  # or run the binary directly
./invoiceocr -addr :9000

Configuration (env vars)

variable default description
ADDR 127.0.0.1:8080 listen address (-addr flag overrides)
ORT_LIB_PATH libonnxruntime.so path to the ONNX Runtime shared library
MODEL_DIR (embedded) optional directory of ONNX models on disk
ORT_THREADS 1 intra-op threads per inference session
OCR_MAX_DET_SIDE 1280 detection resize limit (longer side, px)
OCR_MAX_CONCURRENCY GOMAXPROCS parallel scanned-page OCR jobs
PDF_BIN pdftoppm path to pdftoppm (poppler-utils)
PDF_MAX_PAGES 20 cap on pages processed per PDF
PDF_DPI 200 render resolution for scanned pages
OCR_CACHE_MAX 500 in-memory result cache entries (LRU)
OCR_CACHE_TTL_SECONDS 86400 cache entry lifetime
MAX_UPLOAD_MB 20 max request body size
API_KEY (off) require Authorization: Bearer <key>
DEBUG (off) include per-stage timing (stages field)

API

GET /health

Engine readiness probe:

{ "status": "ok", "ocr": { "ready": true, "engine": "rapidocr-pp-ocrv5", "lib": "libonnxruntime.so", "threads": 1 } }

POST /v1/ocr

Upload a document as multipart (file part) or as JSON with image_base64.

curl -X POST http://127.0.0.1:8080/v1/ocr -F "[email protected]"

Response (application/json):

{
  "success": true,
  "file_type": "pdf",
  "pages": [
    {
      "page": 1,
      "method": "ocr",
      "text": "INVOICE\nACME SUPPLIES INC.\n4000 Industrial Parkway...",
      "confidence": 0.979,
      "lines": [
        { "text": "INVOICE", "score": 1.0, "box": [[48,110],[170,108],[171,130],[49,132]] }
      ]
    }
  ],
  "elapsed_ms": 3256,
  "cached": false
}
  • method is "ocr" (image/scanned page) or "text_layer" (digital PDF page).
  • lines are in reading order, top-to-bottom, left-to-right.
  • Non-image/PDF input returns 422 with success: false and a warning.

More examples, including the JSON body and API-key calls: examples/curl.sh.

Project layout

cmd/ocr-invoice/   entry point (server bootstrap, routes, graceful shutdown)
internal/server/   OCR engine, pipeline, cache, PDF handling, HTTP handlers
  ocr.go           RapidOCR engine: ONNX sessions, reading order
  image.go         image decoding (PNG/JPEG/GIF/BMP/TIFF/WebP)
  pdf.go           PDF text layer (layout-aware) + scanned-page rendering
  extract.go       per-document pipeline (sniff → text layer → OCR → cache)
  cache.go         in-memory LRU result cache (SHA-256 keyed)
  server.go        HTTP handlers, upload parsing, auth middleware
  config.go        environment configuration
internal/models/   PP-OCRv5 det/cls/rec ONNX models + char dict (go:embed)
examples/          sample fixtures (sample-invoice.png, ac-statement-new.pdf) + curl.sh
tools/samplegen/   regenerates the sample invoice fixture
libonnxruntime.so  runtime dependency (copy next to the binary when deploying)

Tests

make test                 # offline unit + pipeline tests (stub engine)
make smoke                # real PP-OCRv5 smoke test (needs libonnxruntime.so)

Equivalently: go test ./... and ORT_SMOKE=1 go test -run TestRealOCR -v ..

About

A superfast, lightweight, memory-efficient CPU-only OCR API.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages