Pure Java OCR with mica-ppocr: How It Parses Documents and Invoices

This article details the pure‑Java mica‑ppocr library built on Java 17 and ONNX Runtime, covering its rapid version evolution, core engine upgrades, structured parsing of six document types, Spring Boot and Solon integration, performance optimizations, and architectural refactors, providing a comprehensive technical overview for developers.

Java Architecture Diary
Java Architecture Diary
Java Architecture Diary
Pure Java OCR with mica-ppocr: How It Parses Documents and Invoices

1. Introduction

Core points:

mica-ppocr is a pure Java 17 implementation using ONNX Runtime, with zero PaddlePaddle dependency, achieving bit‑exact reproduction of the PP‑OCRv6 Python reference.

Rapid community‑driven iteration: from v1.0.0 (Aug 7) to v1.1.3 (Aug 15) – six releases in eight days.

Upgrade path: from a bare OCR engine to a full‑stack structured‑parsing suite with one‑click Spring Boot / Solon integration.

2. Version timeline

v1.0.0 (Aug 7) – PP‑OCRv6 core engine, detection + recognition pipeline.

v1.0.1 (Aug 10) – Fixed native resource leak, improved stability.

v1.1.0 (Aug 12) – Added structured‑parsing module and Spring Boot starter.

v1.1.1 (Aug 13) – Document orientation classification, performance tweaks, compatibility fixes.

v1.1.2 (Aug 13) – Added Solon plugin, support for business licence and VAT invoice parsers.

v1.1.3 (Aug 15) – Code refactor, ID card parsing improvements, chain‑style API simplification.

3. Core engine upgrades

3.1 Document orientation classification (v1.1.1)

Problem: OCR fails when images are taken in portrait or upside‑down orientation.

Solution: Introduced PP-LCNet_x1_0_doc_ori model supporting four orientations (0°, 90°, 180°, 270°) with automatic pre‑rotation.

Cost: ~3 ms extra CPU time per image, ~30 MB additional memory for a third ONNX session.

Default is disabled to keep backward compatibility; can be enabled per request.

Parameter tuning: docOrientationThresh lowered from 0.5 to 0.3 for more stable detection.

3.2 API redesign (v1.1.0)

Public API now exposes only five input types: String, File, Path, byte[], InputStream.

Removed easy‑to‑misuse Mat parameters; native OpenCV handling is internal.

Advanced scenarios can still use runMat, detectMat, recognizeMat where the caller manages Mat lifecycle.

Path handling now prefers native file reads and falls back for unsupported file systems.

3.3 Performance and bug fixes (v1.1.1)

Fixed native Mat leak in DocOrientationPreprocessor.resizeShort (~1.5 MB per call, OOM risk).

CTC decoder loop reduced from three passes to one, speeding up decoding.

Removed redundant array copies in DbPostProcessor.boxScore.

String handling upgraded to Java 11+ String.stripTrailing.

ONNX Runtime downgraded to 1.18.0 for broader OS compatibility (thanks to @goalsword).

4. Structured parsing module

4.1 Supported parsers (six types)

Vehicle license – fields: plate, owner, type, VIN, issue date (v1.1.0).

ID card (front/back auto‑detect) – name, gender, ethnicity, number, address (v1.1.0).

Bank card – number, holder, bank, expiry (v1.1.0).

Driver’s license – name, permitted vehicle class, expiry, licence number (v1.1.0).

Business licence – credit code, company name, legal representative, registered capital (9 fields, v1.1.2).

VAT invoice – code, number, date, amount, tax, buyer/seller info (v1.1.2).

4.2 Extensible label matcher

Combines label positioning, regex fallback, and layout fallback. findLabelBox supports fuzzy matching of truncated labels. collectMultiLineRight merges multi‑line values (e.g., business scope, address).

Custom parsers implement BaseStructuredParser<R> and register with PPOcrTemplate.

4.3 ID card parsing enhancements (v1.1.3)

Handles combined gender/ethnicity tags (“性别男民族汉”).

Improved gender and ethnicity extraction when tags and values merge.

Regex fallback for ID number to cope with missing or merged labels.

Added unit tests for these edge cases.

5. Dual‑framework support

5.1 Spring Boot starter (v1.1.0, simplified in v1.1.3)

// One‑line usage: detection → recognition → structured parsing
VehicleLicenseResult r = ppocrTemplate.vehicleLicense().parse(file.getBytes());
IdCardResult i = ppocrTemplate.idCard().parse(path);
InvoiceResult v = ppocrTemplate.invoice().parse(inputStream);
PPOcrTemplate

provides six getter methods for chainable calls.

Each parser offers the five overloaded input methods. StructuredParserAutoConfiguration auto‑registers the six built‑in parsers, the engine, and the template. PPOCRPropertiesCustomizer allows model size overrides (tiny/small/medium).

Native OpenCV libraries are pre‑loaded via OpenCVNativeLoader.

5.2 Solon plugin (added v1.1.2)

API mirrors Spring Boot starter for seamless migration.

Provides PPOcrTemplate bean with six parsers auto‑wired.

Configuration metadata ( additional-solon-configuration-metadata.json) adds enum hints for detLimitType and supports camelCase/kebab‑case.

End‑to‑end integration test PPOcrV6SolonIntegrationTest validates full OCR flow.

6. Architectural refactor (v1.1.3)

6.1 Structured parser base class

BaseStructuredParser

changed from @FunctionalInterface to abstract class.

Holds a reference to PPOcrV6Engine and implements a single parseResults(List<PPOcrV6Result>) method.

Static singleton INSTANCE removed to improve extensibility.

6.2 Test framework overhaul

BaseTest

now generic <R, P extends BaseStructuredParser<R>> and manages engine creation, OCR calls, and result printing.

Common test utilities moved to ParserTestSupport.

Constants for model tiers, document orientation, thresholds live in BaseTest.

7. Conclusion

Community contributions (e.g., @goalsword) fixed ONNX Runtime compatibility and added document‑orientation classification.

Source code is open on Gitee and GitHub; contributions are welcomed.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaOCRSpring BootSolonONNX Runtimemica-ppocrstructured parsing
Java Architecture Diary
Written by

Java Architecture Diary

Committed to sharing original, high‑quality technical articles; no fluff or promotional content.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.