Skip to content

Releases: Bodhi42/Occular-ocr

0.5.1 — Reading order on by default, simpler settings

Choose a tag to compare

@Bodhi42 Bodhi42 released this 27 Oct 09:54

0.5.1 — Reading order on by default, simpler settings, bug fixes

Lines now come out in reading order: multi-column pages are read column by column instead of across.

  • Reading order is on by default (reading_order=True). Occular finds the layout regions of the page and assigns each line to the text region that covers it. Lines outside any region become their own objects. A small trained model orders the regions and these lines, and lines inside a region are read top to bottom. A region that lies inside a larger one is not treated as a separate block, so a paragraph is never split between "half a column" and "the whole column".

    • CER on 947 pages with page-level reference text fell from 0.341 to 0.225: OmniDocBench plus two sets of Russian documents, run on GPU.
    • On 755 OmniDocBench pages with human-annotated order, the share of line pairs in the right order rose from 85.4 % to 92.0 %. On two-column pages it rose from 72.8 % to 84.3 %, on three-column pages from 63.5 % to 79.3 %.
    • A page takes about 14 % longer, and the layout weights (~55 MB) are downloaded on first use.
    • reading_order=False (CLI --no-reading-order) gives plain top-to-bottom order.
  • ocr() and the CLI keep the reading order in their text output. Both used to re-sort lines top to bottom before printing.

  • One unwarp setting. unwarp=False is the default and turns dewarping off. unwarp=True dewarps a page only if its text then reads better, and unwarp="always" dewarps every page. The dewarping model is downloaded automatically.

  • Removed settings:

    • experimental_layout_order and layout_order_method (including the XY-cut option);
    • unwarp_gate and unwarp_margin;
    • the older reading-order model.

    Code that passes the removed settings now fails with a TypeError. download_reading_order() and reading_order_ready() still work and now handle the new reading-order weights.

  • Bug fixes:

    • Changing languages or recognizer within one process now takes effect. Previously a cached recognizer was reused.
    • Unknown language codes raise an error that lists the supported codes.
    • model_info() and layout_ready() now detect weights in the Hugging Face cache.

This code was briefly published as 0.6.0. That release is yanked; please use 0.5.1.

Full details are in CHANGELOG.md.

Upgrade:

pip install -U occular-ocr==0.5.1

With GPU dependencies:

pip install -U "occular-ocr[gpu]==0.5.1"

0.5.0 — Tables in the pipeline, layout regions, multi-core PDF

Choose a tag to compare

@Bodhi42 Bodhi42 released this 27 Oct 08:38

0.5.0 — Tables in the pipeline, layout regions, and multi-core PDF processing

This release adds table output to the regular OCR pipeline, introduces optional layout analysis, and makes multi-page documents scale across CPU cores.

  • Tables in the OCR pipeline. Use Settings(tables=True), ocr(..., tables=True) or the CLI flag --tables. Recognized lines are placed into table cells (table, cell with row/column and spans), PDF pages gain a tables key, and plain-text output prints tables as Markdown in place. Lines that run across a cell border are split at a space, never inside a word. Off by default.

  • New table models in TableRecognizer. Trained on our own annotated corpus of real documents (forms, statements, invoices, books, scans). On its held-out part:

    • detection F1 0.82 (was 0.43), neighbouring tables no longer merge;
    • row/column grid F1 0.92 (was 0.80), merged cells F1 0.83 (was 0.58);
    • tall tables are no longer squashed; on tables with more than 50 rows, row F1 is 0.89 (was close to 0);
    • empty or missing rows and columns are fixed.

    Single-row and single-column tables no longer crash on GPU.

  • Layout regions (new, optional): LayoutDetector. Returns page regions with boxes, scores and one of 18 labels. It runs on CPU in about 0.3 s per page, and its weights (~42 MB) are downloaded on first use. The labels are informational only: nothing is removed or skipped because of them.

  • Experimental reading order from layout (off by default). OCRPipeline(experimental_layout_order=True) reorders lines by layout regions, using either a small trained block-order model (~5 ms per page) or XY-cut. The text itself is unchanged; each line gains layout_region and layout_label.

  • Multi-page work scales across cores. process_pdf(workers=N), ocr() on PDFs and the CLI --workers option (now also for folders) process pages in separate worker processes instead of threads. Throughput rose from 0.66 to 1.57 pages/s at 8 workers, and to about 3 pages/s on large PDFs. Cores are split by physical cores on Linux and macOS. A single page is also faster: 2.35 → 1.64 s.

    Processes require an if __name__ == "__main__": guard in your script. Without it, Occular falls back to threads and shows a one-time warning.

  • Faster native decoder. occular-decode 0.2.0 (optional, in native/wheels/) now scales under concurrent load: 13k → 49k lines/s at 16 parallel requests, with byte-identical text. A macOS arm64 wheel is now available.

  • Installation and platform fixes:

    • No source builds on supported platforms (#4). macOS gets OpenCV wheels that match its version, and Linux aarch64 uses plain onnxruntime. PyMuPDF is capped below 2.0.
    • On Windows, a separate wheel ships the Microsoft C++ runtime DLLs. Clean installs without the Visual C++ Redistributable now work.
    • On Windows, CLI output redirected to a file or pipe no longer fails with UnicodeEncodeError.
    • All console output is in English (#5).
    • The PyMuPDF fitz deprecation warning no longer appears.
  • Removed the ocr_skel alias, deprecated since 0.3.0. Use import occular and python -m occular.

Without the new options, the output is byte-identical to 0.4.6.

Full details are in CHANGELOG.md.

Upgrade:

pip install -U occular-ocr==0.5.0

With GPU dependencies:

pip install -U "occular-ocr[gpu]==0.5.0"

0.4.6 — Stability, dependency fixes, and ONNX-only inference

Choose a tag to compare

@Bodhi42 Bodhi42 released this 11 Oct 00:10

0.4.6 — Stability, dependency fixes, and ONNX-only inference

This release focuses on reliable installation, fewer dependency conflicts, and a consistent runtime across CPU and GPU.

  • All models now run through ONNX Runtime. PyTorch is no longer required for inference, including table structure recognition, merged cells, and UVDoc document dewarping. CPU and GPU use the same ONNX model files, with no separate GPU weights to download.

  • Fewer NumPy dependency conflicts. Replaced pyctcdecode with a bundled beam-search implementation that preserves its output without imposing numpy<2. OpenCV versions are constrained to avoid forcing a NumPy 2 upgrade and breaking existing environments. This also resolves the dependency chain that triggered failing NumPy source builds on Python 3.13 and 3.14.

  • Better support for Docker and headless servers. Switched to opencv-python-headless, removing the GUI-related libGL requirement that caused import failures in minimal containers.

  • Simpler GPU setup. The appropriate ONNX Runtime package is selected automatically for each supported platform. The [gpu] extra installs CUDA and cuDNN libraries through pip. If CUDA cannot be loaded, Occular explains the issue and falls back to CPU.

  • Stable table ordering. Tables are now returned from top to bottom, then left to right, instead of being sorted by detection confidence. Small floating-point differences no longer reshuffle tables on the page.

  • Performance improvements. Internal benchmarks show approximately 4× faster table structure inference and 25% faster pure-Python beam decoding. Table grids and merged cells were checked against the previous PyTorch implementation.

  • Improved compatibility checks and diagnostics. Dependency minimums were verified across Python 3.8–3.14. Conflicting ONNX Runtime/OpenCV installations now receive clearer diagnostics and repair guidance, while PyMuPDF import errors report the underlying cause.

Upgrade:

pip install -U occular-ocr==0.4.6

With GPU dependencies:

pip install -U "occular-ocr[gpu]==0.4.6"

0.4.3 bug fix

Choose a tag to compare

@Bodhi42 Bodhi42 released this 02 Oct 18:01

bug fix

0.4.2 — Better tables, rotated text and numeric fields

Choose a tag to compare

@Bodhi42 Bodhi42 released this 02 Oct 17:58

This release improves table structure recognition, adds line-level orientation correction, and protects numeric fields from unwanted language-model corrections.

  • Better table structure recognition. A new peak-based separator decoder improves row and column boundaries without retraining the model. In internal benchmarks, structure F1 increased from 90.5% to 92.0% overall, and from 76.2% to 79.5% on real Russian tables.

  • Line-level orientation correction, enabled by default with deskew=True. The detector now preserves text-region angles, allowing the recognizer to handle tilted lines, sideways text and vertically stacked characters. Confidence-based checks reduce false 180° rotations and improve handling of vertical numeric fields, including passport series and numbers. Whole-page orientation remains separately controlled by orientation=True.

  • Numeric-field protection during beam + LM decoding. The new code_lock mechanism preserves the recognizer’s greedy reading for digit-heavy sequences, reducing unwanted language-model changes to account numbers, tax IDs, document numbers and amounts. Regular text still benefits from language-model correction.

  • Improved confidence scores. Beam-decoding confidence now uses the selected hypothesis’s acoustic score, normalized by text length, providing a more useful signal for identifying uncertain recognition results.

  • Experimental UVDoc document unwarping. Added an optional module for flattening curved or warped document photos, with a self-contained PyTorch implementation and support for local or Hugging Face weights. Disabled by default; requires the [unwarp] extra. In 0.4.2, this is available through the low-level API.

Upgrade:

pip install -U occular-ocr==0.4.2

0.4.1 Faster recogniser inference!

Choose a tag to compare

@Bodhi42 Bodhi42 released this 05 Sep 17:00

New default recognizer svtr_lcnet (~5x faster on CPU at 99.6% of the
previous model's accuracy), for both Russian/English and the 12 Cyrillic
languages. The larger svtr_t stays available via recognizer="svtr_t";
models are now selected by architecture name.

Page orientation detection (0/90/180/270 degrees), off by default, enabled
with orientation=True or --orientation. Rotation is applied only above 0.8
confidence, so non-document inputs are left untouched.

GPU support for the new default recognizer: svtr_lcnet runs natively on
PyTorch/CUDA for both scripts and matches the CPU (ONNX) path line for line.

Detector graph trimmed to its single inference output (240 -> 222 nodes);
boxes are bit-identical.

0.3.2

Choose a tag to compare

@Bodhi42 Bodhi42 released this 28 Aug 06:42

occular-ocr 0.3.2

Multilingual recognition — 12 more languages.

  • 12 additional Cyrillic-script languages beyond the default Russian/English: Bashkir, Belarusian, Bulgarian, Chuvash, Kazakh, Kyrgyz, Macedonian, Mongolian, Serbian, Tajik, Tatar, Ukrainian. Turn them on with languages=:

    • ocr(img, languages=["uk"]) — a single language (fastest)
    • ocr(img, languages=["ru", "kk"]) — detect the language per line
    • ocr(img, languages="auto") — auto-detect across all supported languages

    Also available on OCRPipeline(...), Settings(languages=...), and the CLI (--languages / --lang).

  • Per-language decoding. Each language uses its own tuned settings — a language model where it helps, fast greedy decoding where it doesn't. The recognizer and only the requested language's weights are downloaded from the Hub on first use. More languages will follow in future releases.

  • Default path unchanged. Russian/English works exactly as before — same model, same output, no extra downloads.

Upgrade: pip install -U occular-ocr

0.3.1

Choose a tag to compare

@Bodhi42 Bodhi42 released this 28 Aug 06:40

occular-ocr 0.3.1

  • --json now emits clean JSON. Model-loading messages ("Loaded …", language-model info) were moved from stdout to stderr, so occular img.png --json > out.json produces valid, parseable JSON.
  • python -m ocr_skel fixed. The deprecated ocr_skel alias worked for import but not python -m; the compatibility shim now keeps it a real package, so both forms work. (python -m occular was already fine.)

Upgrade: pip install -U occular-ocr

v 0.3.0

Choose a tag to compare

@Bodhi42 Bodhi42 released this 25 Aug 05:55
  • Table recognition model (TableRecognizer) — rows, columns, merged cells
  • Native (Rust) decoder for beam + LM — faster, byte-identical output
  • Package renamed ocr_skel → occular (old name still works)

v0.2.2

Choose a tag to compare

@Bodhi42 Bodhi42 released this 10 Aug 03:35

Фикс confidence на beam CTC
gpu переходит на торч веса, onnx-gpu у меня работает нестабильно