Repository navigation
Releases: Bodhi42/Occular-ocr
Release list
0.5.1 — Reading order on by default, simpler settings
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
unwarpsetting.unwarp=Falseis the default and turns dewarping off.unwarp=Truedewarps a page only if its text then reads better, andunwarp="always"dewarps every page. The dewarping model is downloaded automatically. -
Removed settings:
experimental_layout_orderandlayout_order_method(including the XY-cut option);unwarp_gateandunwarp_margin;- the older reading-order model.
Code that passes the removed settings now fails with a
TypeError.download_reading_order()andreading_order_ready()still work and now handle the new reading-order weights. -
Bug fixes:
- Changing
languagesorrecognizerwithin one process now takes effect. Previously a cached recognizer was reused. - Unknown language codes raise an error that lists the supported codes.
model_info()andlayout_ready()now detect weights in the Hugging Face cache.
- Changing
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.1With GPU dependencies:
pip install -U "occular-ocr[gpu]==0.5.1"0.5.0 — Tables in the pipeline, layout regions, multi-core PDF
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,cellwith row/column and spans), PDF pages gain atableskey, 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 gainslayout_regionandlayout_label. -
Multi-page work scales across cores.
process_pdf(workers=N),ocr()on PDFs and the CLI--workersoption (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-decode0.2.0 (optional, innative/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
fitzdeprecation warning no longer appears.
- No source builds on supported platforms (#4). macOS gets OpenCV wheels that match its version, and Linux aarch64 uses plain
-
Removed the
ocr_skelalias, deprecated since 0.3.0. Useimport occularandpython -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.0With GPU dependencies:
pip install -U "occular-ocr[gpu]==0.5.0"0.4.6 — Stability, dependency fixes, and ONNX-only inference
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
pyctcdecodewith a bundled beam-search implementation that preserves its output without imposingnumpy<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-relatedlibGLrequirement 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.6With GPU dependencies:
pip install -U "occular-ocr[gpu]==0.4.6"0.4.3 bug fix
0.4.2 — Better tables, rotated text and numeric fields
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 byorientation=True. -
Numeric-field protection during beam + LM decoding. The new
code_lockmechanism 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.20.4.1 Faster recogniser inference!
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
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 lineocr(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
occular-ocr 0.3.1
--jsonnow emits clean JSON. Model-loading messages ("Loaded …", language-model info) were moved from stdout to stderr, sooccular img.png --json > out.jsonproduces valid, parseable JSON.python -m ocr_skelfixed. The deprecatedocr_skelalias worked forimportbut notpython -m; the compatibility shim now keeps it a real package, so both forms work. (python -m occularwas already fine.)
Upgrade: pip install -U occular-ocr