rust-paddle-ocr
Library Listed
A lightweight and efficient OCR library based on PaddleOCR models, using the MNN inference framework for high-performance text detection and recognition
- Downloads
- 2,742
- Dependents
- 5
- Stars
- 346
- Forks
- 49
- Contributors
- 3
- Commits
- 112
- Latest release
- 2.4.1 ·
About
A lightweight Rust OCR library based on PaddleOCR models and the MNN inference runtime. It provides text detection, text recognition, and end-to-end OCR with file or in-memory model loading.
Related projects:
- CLI: newbee-ocr-cli
- C API bindings: paddle-ocr-capi
- HTTP service:
newbee_ocr_serviceis local-only and is not published as a public repository.
Supported Models
All runtime model files should be placed under models/.
| Family | Detection | Recognition | Notes |
|---|---|---|---|
| PP-OCRv4 | ch_PP-OCRv4_det_infer.mnn | ch_PP-OCRv4_rec_infer.mnn | Legacy CN/EN model |
| PP-OCRv5 | PP-OCRv5_mobile_det.mnn or PP-OCRv5_mobile_det_fp16.mnn | PP-OCRv5_mobile_rec*.mnn | Default CN/EN/JP plus script-specific models |
| PP-OCRv6 tiny | PP-OCRv6_tiny_det.mnn | PP-OCRv6_tiny_rec.mnn | Lightweight v6 tier; Japanese is not supported |
| PP-OCRv6 small | PP-OCRv6_small_det.mnn | PP-OCRv6_small_rec.mnn | Balanced v6 tier |
| PP-OCRv6 medium | PP-OCRv6_medium_det.mnn | PP-OCRv6_medium_rec.mnn | Accuracy-first v6 tier |
Read the full README
PP-OCRv6 small and medium support the official 50 v6 recognition languages: Simplified Chinese, Traditional Chinese, English, Japanese, and 46 Latin-script languages. PP-OCRv6 tiny follows the same set except Japanese. Korean, Cyrillic, Arabic, Devanagari, Thai, Greek, Tamil, and Telugu should continue using the PP-OCRv5 script-specific recognition models.
V6 charset files are tier-specific:
models/ppocr_keys_v6_tiny.txt
models/ppocr_keys_v6_small.txt
models/ppocr_keys_v6_medium.txt
Convert Paddle Models To MNN
The converter defaults to MNN FP16 to reduce model size. Use --install-dir ./models to copy converted runtime files into the expected directory and filenames.
python script/convert_paddle_to_mnn.py \
--ocr-dir /path/to/paddle/inference/models \
--install-dir ./models
Use --no-fp16 only when full precision MNN output is required.
Rust Usage
use ocr_rs::OcrEngine;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let engine = OcrEngine::new(
"models/PP-OCRv6_small_det.mnn",
"models/PP-OCRv6_small_rec.mnn",
"models/ppocr_keys_v6_small.txt",
None,
)?;
let image = image::open("test.jpg")?;
let results = engine.recognize(&image)?;
for item in results {
println!("{:.2}: {}", item.confidence, item.text);
}
Ok(())
}
Detection-only and recognition-only engines are also available:
let det = ocr_rs::OcrEngine::det_only("models/PP-OCRv6_small_det.mnn", None)?;
let rec = ocr_rs::OcrEngine::rec_only(
"models/PP-OCRv6_small_rec.mnn",
"models/ppocr_keys_v6_small.txt",
None,
)?;
Mixed horizontal and vertical text
The existing recognize method keeps the original single-pass behavior. For
images that mix horizontal text with text rotated by 90 or 270 degrees, enable
the opt-in robust mode for that call:
use ocr_rs::{RecognizeOptions, RotatedTextMode};
let options = RecognizeOptions::new()
.with_rotated_text_mode(RotatedTextMode::Robust);
let results = engine.recognize_with_options(&image, &options)?;
Robust mode runs detection on 90° and 270° copies, maps recovered boxes back to
the input coordinates, and recognizes only vertical candidates. This adds no
work to existing recognize calls. RotatedTextMode::DetectedOnly is a lighter
option when the normal detector already finds the vertical boxes.
Character alignment
Use the additive alignment API when an image UI needs character hit testing or selection geometry:
let results = engine.recognize_with_options_and_alignment(&image, &options)?;
for line in results {
for character in line.characters {
println!("{}: {:?}", character.character, character.points);
}
}
The four source-image points for each character are derived from the
recognition model's CTC time steps and the detected text quadrilateral. This
does not run an additional inference pass. The existing RecognitionResult,
OcrResult_, recognize, and recognize_with_options APIs are unchanged.
Build
cargo build --release
cargo test
Performance Checks
Run Criterion benchmarks locally:
cargo bench --bench bench_metrics
Run the CI-style performance smoke test:
OCR_RS_PERF_TESTS=1 cargo test --release --test performance_tests -- --nocapture --test-threads=1
GitHub Actions runs these release tests serially and stores the PERF_METRIC log as an artifact. The regression guard compares the direct exact-width pipeline with the legacy crop pipeline on the same runner and fails when the median ratio exceeds OCR_RS_PERF_REGRESSION_LIMIT (default 1.15), avoiding unstable absolute latency limits.
Native MNN ownership is provided by mnn-runtime, while ocr-rs keeps its existing public inference API through a compatibility layer. This lets multiple model crates in one application share a single mnn-runtime-sys / MNN link owner.
Compatible CPU and GPU prebuilts are selected automatically. Unsupported target/feature combinations fall back to building MNN from source:
cargo build --features build-mnn-from-source
cargo build --release --features cuda
cargo build --release --features vulkan
Install the SDK and development libraries required by the selected backend before building. GPU backends are selected through OcrEngineConfig:
use ocr_rs::{Backend, OcrEngineConfig};
let config = OcrEngineConfig::new().with_backend(Backend::Metal);
assert!(Backend::Metal.is_available());
Engine creation returns MnnError::BackendUnavailable when the requested backend was not registered instead of silently falling back to CPU.
OcrEngineConfig uses OpenCL buffer memory by default so very wide text regions do not exceed the GPU's 2D image-width limit. Advanced users can override this with with_gpu_memory_mode(GpuMemoryMode::Auto) or GpuMemoryMode::Image; the setting is ignored by non-OpenCL backends.
x86_64-pc-windows-gnu builds MNN from source and requires a MinGW C/C++ toolchain. By default, applications must distribute the matching MinGW runtime DLLs. Enable static-cpp-runtime to statically link libstdc++, libgcc, and winpthreads so the resulting binary does not depend on MinGW runtime DLLs:
cargo build --release --target x86_64-pc-windows-gnu --features static-cpp-runtime
NVIDIA's Windows CUDA toolchain requires MSVC; use x86_64-pc-windows-msvc for source-built CUDA, or provide a compatible MNN library with mnn-dynamic/mnn-static.
This feature controls the runtime linked by ocr-rs; a user-supplied DLL selected with mnn-dynamic may still have its own MinGW runtime dependencies.
License
Apache-2.0
GPU cold-start and wide-image troubleshooting
OpenCL OCR defaults to Buffer memory and fast tuning. Vulkan OCR defaults to no
tuning and High precision when OcrEngineConfig uses Normal precision. Use
with_gpu_tuning to choose another tuning tradeoff and with_gpu_cache_dir to
persist model-specific kernels. See issue #49 validation and cache guidance
for CPU/GPU text comparisons, cold/warm benchmarks and driver-specific testing.
Compatibility
- Runs on
- CUDA, Metal, Vulkan
What shows it
- CUDA: ocr-rs feature cuda
- Metal: ocr-rs feature metal
- Vulkan: ocr-rs feature vulkan
- Native code
- Build tool
- Build uses a native toolchain: bindgen, cc, cmake
- Python bindings
- No Python binding crate found
- License
- Apache-2.0
Compare with similar projects
Order: strongest tier first, then most downloads, then name, with unmeasured values last. A library counts downloads over 30 days. An app counts binary downloads per release. An app with none counts its crate downloads over 30 days.
| Project | Downloads | Dependents | Stars | Latest release | Runs on (GPU) | Native code | License |
|---|---|---|---|---|---|---|---|
|
A lightweight and efficient OCR library based on PaddleOCR models, using the MNN inference framework for high-performance text detection and recognition |
2,742 downloads over 30 days | 5 | 346 | 2.4.1 | CUDA, Metal, Vulkan | Build uses a native toolchain: bindgen, cc, cmake | Apache-2.0 |
|
oar-ocr Listed
An Optical Character Recognition (OCR) and Document Layout Analysis library written in Rust. |
34,387 downloads over 30 days | 9 | 204 | 0.10.2 | CUDA, WebGPU, Metal | Binds native code: ort-sys | Apache-2.0 |
|
Higher-level bindings for Tesseract OCR |
24,101 downloads over 30 days | 12 | 176 | 0.15.2 | GPU support unknown | Binds native code: tesseract-sys, leptonica-sys | MIT |
|
Productive Rust binding for Tesseract and Leptonica. |
16,918 downloads over 30 days | 14 | 286 | 0.14.0 | GPU support unknown | Binds native code: leptonica-sys, tesseract-sys | MIT |
|
rusto-rs New
RustO! - Pure Rust OCR library based on RapidOCR with PaddleOCR engine |
1,618 downloads over 30 days | 1 | 127 | 0.3.2 | CUDA, Metal, Vulkan | Binds native code: rusto-mnn-sys. Build uses a native toolchain: bindgen, cc, cmake | MIT |
|
franken_ocr New
Pure-Rust, CPU-hyper-optimized runner for the Baidu Unlimited-OCR model (single-binary CLI: focr) |
40 downloads over 30 days | 0 | 346 | 0.9.0 | GPU support unknown | No native code found | Not measured |
Why ListedNo archive, New or Featured rule places it, so it is Listed.
What it lacks for Featured
- It has 2 active dependents and 2 new dependents in 365 days. Featured needs 11 active dependents or 9 new dependents in 365 days. The repository route reads 346 stars, 49 forks and 3 contributors. It needs 4,539 stars, 434 forks and 79 contributors together.
What else the check found
- The last activity is on 11 Sep 2026, 59 days ago. The rules expect an update within 365 days. Dormancy rule
Exact rules: Listed, Featured library. The check on applied thresholds version 9.
Every rule outcome, as the check records it
expected-interval: version 2.4.1 base 300, raised to the 365-day floor: E = 365 daysdormancy: last activity 2026-09-11, 59 days ago, E = 365: activefeatured: not featured: active_users 2 < 11 and new_adopters 2 < 9 and repository route stars 346 (needs 4539), forks 49 (needs 434), contributors 3 (needs 79)listed: listed: no archive, new or featured rule applies
Measurements and sources
Each signal row shows the raw value, its source and the fetch date. The Sources list gathers every distinct source on this page. Movement needs more history.
Sources6 sources
- Description: the crates.io description
- crates.io database dump, fetched
- RustSec advisory database, fetched
- GitHub repository, fetched
- crates.io package, fetched
- GitHub contributors, fetched
Adoption2 active dependents, 2 new dependents in 365 days1 not measured
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Active dependents | 2 | crates.io database dump | Yes | |
| New dependents (365 days) | 2 | crates.io database dump | Yes | |
| Peak active dependents | 2 | crates.io database dump | Yes | |
| Active dependents as a share of the peak | 1 | crates.io database dump | Yes | |
| Binary downloads per release | Not measured | Yes |
MaintenanceLatest human commit: 59 days ago3 not measured
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Latest human commit | 2026-09-11 | GitHub repository | Yes | |
| Latest release | 2026-08-05 | crates.io database dump | Yes | |
| First release | 2025-12-21 | crates.io database dump | Yes | |
| Latest version | 2.4.1 | crates.io database dump | Yes | |
| Days the oldest outside issue waits for a reply | 0 | GitHub repository | Yes | |
| Maintainer replies over 365 days | 63 | GitHub repository | Yes | |
| Repository archived | false | GitHub repository | Yes | |
| Repository gone | false | GitHub repository | Yes | |
| Release commit or manifest in the repo | true | crates.io package | Yes | |
| Published docs | true | crates.io database dump | Yes | |
| Latest release fails cargo check | Not measured | Yes | ||
| Build check date | Not measured | Yes | ||
| Build check toolchain | Not measured | Yes |
SecurityUnpatched vulnerabilities: none
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Unpatched vulnerabilities past the grace window | none | RustSec advisory database | Yes | |
| RustSec unmaintained advisory | none | RustSec advisory database | Yes | |
| Deprecation notice | none | crates.io database dump | Yes | |
| Deprecated requirement | none | crates.io database dump | Yes |
Distribution16 releases, 2,742 downloads over 30 days5 not measured
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Releases | 16 | crates.io database dump | Yes | |
| Downloads over 30 days | 2742 | crates.io database dump | Yes | |
| Binary downloads over the last 3 releases | Not measured | Yes | ||
| Homebrew installs on request over 365 days | Not measured | Yes | ||
| Repology repository families | Not measured | Yes | ||
| Docker pull growth over 90 days | Not measured | Yes | ||
| Docker pulls at the growth baseline | Not measured | Yes | ||
| Every version a prerelease | false | crates.io database dump | Yes | |
| Every version 0.0.x | false | crates.io database dump | Yes | |
| Every version yanked | false | crates.io database dump | Yes | |
| Crate deleted from crates.io | false | crates.io database dump | Yes |
Repository346 stars, 49 forks, 3 contributors, 112 commits. Stars alone never qualify a project.
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| GitHub stars | 346 | GitHub repository | Yes — one part of the repository route | |
| GitHub forks | 49 | GitHub repository | Yes — one part of the repository route | |
| Contributors with a GitHub account | 3 | GitHub contributors | Yes — one part of the repository route | |
| Commits on the default branch | 112 | GitHub repository | No | |
| Repository's main crate left out of the entry | none | crates.io database dump | Yes |
Facts that never count
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| License | Apache-2.0 | crates.io database dump | No | |
| Runs on, from listed crates and their direct dependencies | CUDA, Metal, Vulkan | crates.io database dump | No | |
| What shows each backend | CUDA: ocr-rs feature cuda; Metal: ocr-rs feature metal; Vulkan: ocr-rs feature vulkan | crates.io database dump | No | |
| Native code, from listed crates and their dependencies | Build uses a native toolchain: bindgen, cc, cmake | crates.io database dump | No | |
| Python bindings, from direct dependencies of listed crates | No Python binding crate found | crates.io database dump | No | |
| Crates that depend on a listed crate directly | 5 | crates.io database dump | No |
Corrections and review history
No correction applies to this entry.
Judgments
A judgment enters only through an approved issue and a merged pull request.
No judgment applies to this entry.