Metadata-Version: 2.4
Name: pyturboocr
Version: 0.1.0
Summary: Pure-Python OCR: onnxruntime + PP-OCRv6 ONNX weights, no C++ binding, no server.
Author-email: Mohammad Raziei <mohammadraziei1375@gmail.com>
License: MIT
License-File: LICENSE
Keywords: ocr,onnx,onnxruntime,text-detection,text-recognition
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.9
Requires-Dist: numpy>=1.23
Requires-Dist: onnxruntime>=1.17
Requires-Dist: opencv-python-headless>=4.8
Requires-Dist: pillow>=10.0
Requires-Dist: pyclipper>=1.3
Requires-Dist: requests>=2.31
Requires-Dist: shapely>=2.0
Provides-Extra: dev
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Provides-Extra: examples
Requires-Dist: jupyter>=1.0; extra == 'examples'
Requires-Dist: matplotlib>=3.8; extra == 'examples'
Provides-Extra: gpu
Requires-Dist: onnxruntime-gpu>=1.17; extra == 'gpu'
Description-Content-Type: text/markdown

# pyturboocr

**Pure-Python OCR.** Same PP-OCRv6 ONNX weights that [TurboOCR](https://github.com/aiptimizer/TurboOCR)'s
C++/CUDA/TensorRT server bakes into its Docker image — loaded here with
[`onnxruntime`](https://onnxruntime.ai/) and decoded with plain NumPy/OpenCV.
No C++ binding, no CUDA/TensorRT requirement, no server process, no Docker.

```bash
pip install pyturboocr
```

```python
from pyturboocr import OCR

ocr = OCR(tier="tiny")           # downloads + caches ONNX weights on first use
result = ocr.recognize_image("invoice.png")

print(result.text)
for line in result:
    print(line.text, line.confidence, line.box)
```

---

## Contents

- [Installation](#installation)
- [Why this exists](#why-this-exists)
- [How it works](#how-it-works)
- [Model tiers](#model-tiers)
- [Usage](#usage)
- [Benchmarks](#benchmarks)
- [Accuracy](#accuracy)
- [How this compares](#how-this-compares)
- [Development](#development)
- [Known limitations](#known-limitations)
- [License](#license)
- [Acknowledgments](#acknowledgments)

---

## Installation

```bash
pip install pyturboocr
```

Optional extras:

```bash
pip install pyturboocr[gpu]        # onnxruntime-gpu, for CUDAExecutionProvider
```

Requires Python ≥ 3.9. Runs on Linux, macOS, and Windows (CPU); GPU support
depends on your platform's `onnxruntime-gpu` / `onnxruntime-directml`
availability.

---

## Why this exists

TurboOCR's C++ server is built around a persistent GPU-resident pipeline —
worker pools, watchdog threads, TensorRT engine caches — designed to serve
hundreds of requests per second behind HTTP/gRPC. That's the right
architecture for a high-throughput inference server, but it's the wrong
shape for "I just want to call a function from my Python script."

The detection and recognition models themselves, however, are published as
plain ONNX files on GitHub Releases, independent of the server. And the
algorithms wrapped around them — **DB (Differentiable Binarization)** for
text detection, **CTC greedy decoding** for text recognition — are standard,
well-documented techniques from the PaddleOCR ecosystem, not proprietary
logic. `pyturboocr` re-implements just that thin layer in Python, so the
whole thing runs in-process with no server and no compiled extension.

## How it works

```mermaid
flowchart LR
    A[Input image] --> B["Resize + normalize<br/><i>preprocess.py</i>"]
    B --> C["Detection ONNX model<br/><i>onnxruntime</i>"]
    C --> D["DB post-process<br/>threshold → contours → unclip<br/><i>postprocess/db.py</i>"]
    D --> E["Per-line crop + perspective warp<br/><i>preprocess.py</i>"]
    E --> F["Recognition ONNX model<br/><i>onnxruntime</i>"]
    F --> G["CTC greedy decode<br/><i>postprocess/ctc.py</i>"]
    G --> H["TextResult(text, confidence, box)"]
```

Model weights are downloaded once from TurboOCR's GitHub Release assets and
cached under `~/.cache/pyturboocr` (override with `PYTURBOOCR_CACHE_DIR`).
Everything after that first download runs offline, in-process.

## Model tiers

| Tier | Detection params | Use case |
|---|---|---|
| `tiny` | smallest | fast, low-memory, good for short/clean text |
| `small` | medium | balance of speed and accuracy |
| `medium` | largest | best accuracy, slowest |

```python
OCR(tier="small")
```

## Usage

**Basic:**

```python
from pyturboocr import OCR

ocr = OCR(tier="tiny")
result = ocr.recognize_image("page.png")
print(result.text)
```

**Per-line results with boxes and confidence:**

```python
for line in result:
    print(f"{line.text!r}  conf={line.confidence:.3f}  box={line.box}")
```

**From a NumPy array (e.g. a frame from OpenCV/a webcam):**

```python
import cv2
frame = cv2.imread("page.png")
result = ocr.recognize_image(frame)
```

**GPU:**

```python
ocr = OCR(tier="tiny", providers=["CUDAExecutionProvider", "CPUExecutionProvider"])
```

**Custom detection thresholds:**

```python
from pyturboocr.postprocess.db import DBParams

ocr = OCR(tier="tiny", db_params=DBParams(thresh=0.3, box_thresh=0.6, unclip_ratio=1.5))
```

See `examples/quickstart.ipynb` for a runnable walkthrough with visualized
detection boxes.

## Benchmarks

Full methodology, raw numbers, and an explicitly-caveated comparison against
[RapidOCR](https://github.com/RapidAI/RapidOCR) live in
[`benchmarks/RESULTS.md`](benchmarks/RESULTS.md). Reproduce on your own
machine with:

```bash
pip install -r benchmarks/requirements.txt
python benchmarks/benchmark_all.py            # writes benchmarks/results.json
```

The script benchmarks pyturboocr alongside other installed OCR engines
(RapidOCR's onnxruntime/OpenVINO backends, EasyOCR if installed, ...),
skipping anything not installed, and records per-call timings plus system
info (CPU, cores, RAM) as JSON — see `benchmarks/results.sample.json` for an
example.

Headline numbers (1 vCPU, CPU-only, tier=`tiny`, steady-state after warm-up):

| Image | Lines | ms/image | img/s |
|---|---|---|---|
| Single line | 1 | ~30 | ~33 |
| 4-line invoice | 4 | ~70–110 | ~9–14 |

These numbers are from a single-core sandbox and will not match a real
deployment target — **benchmark on your own hardware before relying on
this for capacity planning.** For high-throughput batch processing (GPU,
thousands of pages), TurboOCR's own TensorRT server is meaningfully faster
than any pure-Python inference path, this one included.

## Accuracy

`pyturboocr` loads the exact same PP-OCRv6 ONNX weights TurboOCR's server
uses — the model itself is identical, only the pre/post-processing
implementation differs. In practice, expect near-identical text output to
the TurboOCR server on the same input, modulo:

- floating-point differences between ONNX Runtime and TensorRT execution
- any TurboOCR-side preprocessing (e.g. PDF rasterization, layout detection)
  that this package does not implement — `pyturboocr` handles raster images
  only, not PDFs or layout analysis

This package's own pre/post-processing has been validated against real
rendered text images (see `tests/data/`) but has **not** been stress-tested
against noisy real-world scans, rotated text, or handwriting the way a
mature library like RapidOCR or PaddleOCR has. See
[Known limitations](#known-limitations).

## How this compares

| | `pyturboocr` | TurboOCR (server) | RapidOCR |
|---|---|---|---|
| Model | PP-OCRv6 ONNX | PP-OCRv6 → TensorRT | PP-OCRv6 ONNX (and others) |
| Runtime | in-process, `onnxruntime` | persistent GPU server | in-process, multi-backend |
| Setup | `pip install` | Docker / native build + running server | `pip install` |
| Backends | CPU / CUDA (via onnxruntime) | TensorRT (GPU only) | onnxruntime / OpenVINO / TensorRT / PaddlePaddle / PyTorch |
| Best for | scripts, small apps, embedding | high-throughput batch/production serving | general-purpose production OCR |

If you need a battle-tested, actively maintained pure-Python OCR library and
don't specifically need TurboOCR's exact packaging, RapidOCR is a reasonable
default. `pyturboocr` exists for cases where you specifically want the
TurboOCR model weights with zero server/binding overhead.

## Development

```bash
git clone <this-repo>
cd pyturboocr
pip install -e '.[dev,examples]'
pytest
```

Run a notebook:

```bash
jupyter notebook examples/quickstart.ipynb
```

## Known limitations

- **Raster images only** — no PDF handling, no layout/table detection (the
  underlying TurboOCR server does more than text OCR; this package doesn't).
- **Detection/recognition post-processing is a from-scratch reimplementation**
  of standard DB/CTC algorithms, tested against clean rendered text and a
  handful of real-model smoke tests — not yet validated on noisy scans,
  rotated/skewed text, or handwriting at the scale a mature library has been.
- **No batching** — each detected line is recognized one at a time; batching
  crops into a single recognition call would improve throughput and isn't
  implemented yet.
- **CPU benchmarks only** — GPU numbers haven't been collected; if you run
  them, contributions to `benchmarks/RESULTS.md` are welcome.

## License

MIT — see [`LICENSE`](LICENSE). Downloaded model weights are a separate
artifact from this repository's source and carry their own upstream terms;
verify those before redistributing the weights themselves.

## Acknowledgments

`pyturboocr` exists entirely downstream of [**TurboOCR**](https://github.com/aiptimizer/TurboOCR) —
this package would not exist without its published PP-OCRv6 ONNX weights and
the detection/recognition algorithms its C++ server implements. If you need
production-grade throughput on GPU, use TurboOCR's own server directly
rather than this pure-Python re-implementation.

Model architecture: [**PP-OCRv6**](https://github.com/PaddlePaddle/PaddleOCR),
part of the PaddleOCR project by PaddlePaddle/Baidu.
