# PP-OCR (ONNX Runtime) Config Plugin

本插件在 `expo prebuild` 时注入 PP-OCR 本地 OCR 原生模块（plan.md 决策 4）。

引擎选用 **ONNX Runtime**（跨平台、微软官方、Windows 友好），替代原 NCNN 方案。

## 当前版本

**PP-OCRv6 small**（det 2.5M 参数 + rec 5.3M 参数，精度显著优于 v5 mobile）

| 指标          | PP-OCRv5 mobile | PP-OCRv6 small |
| ------------- | --------------- | -------------- |
| det Hmean     | 75.2%           | 84.1%          |
| rec W-Avg     | 73.7%           | 81.3%          |
| rec ONNX 大小 | ~17 MB          | ~21 MB         |

## 文件结构

```
plugins/ppocr/
├── app.plugin.js              # Config Plugin 入口（prebuild 时执行）
├── android/                   # Kotlin 原生实现（prebuild 时复制进原生工程）
│   ├── OcrModule.kt           # React Native Bridge：ONNX Runtime 推理 + det/rec 前后处理
│   └── OcrPackage.kt          # RN Package 注册（注入到 MainApplication.getPackages）
└── assets/                    # ONNX 模型 + 字典（需自行下载放置）
    ├── ppocrv6_det.onnx       # 文本检测模型（PP-OCRv6 small）
    ├── ppocrv6_rec.onnx       # 文本识别模型（PP-OCRv6 small，多语言）
    └── ppocrv6_dict.txt       # PP-OCRv6 多语言字典（CTC 解码用）
```

## 模型获取（一键下载）

PP-OCRv6 官方 ONNX 模型来自 [PaddlePaddle/PP-OCRv6 系列](https://huggingface.co/collections/PaddlePaddle/pp-ocrv6)：

```bash
# 在项目根目录执行
mkdir -p plugins/ppocr/assets
cd plugins/ppocr/assets

# det 模型（PP-OCRv6 small）
curl -L -o ppocrv6_det.onnx \
  https://huggingface.co/PaddlePaddle/PP-OCRv6_small_det_onnx/resolve/main/inference.onnx

# rec 模型（PP-OCRv6 small）
curl -L -o ppocrv6_rec.onnx \
  https://huggingface.co/PaddlePaddle/PP-OCRv6_small_rec_onnx/resolve/main/inference.onnx

# PP-OCRv6 多语言字典（必须与上面的 rec 模型配套）
curl -L -o ppocrv6_dict.txt \
  https://raw.githubusercontent.com/PaddlePaddle/PaddleOCR/main/ppocr/utils/dict/ppocrv6_dict.txt
```

> ⚠️ **字典必须与 rec 模型配套**：v6 字典字符集与 v5 完全不同，混用会导致 CTC 解码乱码。
> 若之前使用过 v5 模型，务必删除旧文件（`ppocrv5_det.onnx`、`ppocrv5_rec.onnx`、`ppocrv5_dict.txt`）。

## 性能配置（参考 AutoAccounting OcrProcessor.kt）

| 优化项   | 配置                                   |
| -------- | -------------------------------------- |
| 引擎     | ONNX Runtime Android                   |
| 执行器   | CPU（兼容性最稳，部分设备 GPU 会崩溃） |
| 线程     | intraOp=2 / interOp=2                  |
| det 图像 | 最大边 960px，短边压缩 720px           |
| rec 图像 | 固定高度 48px                          |
| ABI      | arm64-v8a（主流设备）                  |

## 使用

在 `app.json` 注册插件：

```json
{
  "plugins": ["./plugins/ppocr"]
}
```

JS 层通过 `src/services/ocrBridge.ts` 的 `NativeOcrBridge` 调用，桥接到 `NativeModules.PpOcr`：

- `recognizeText(base64)` → 返回纯文本（多行用 `\n` 连接）
- `recognizeTextBlocks(base64)` → 返回带坐标的文本块数组 `[{text, x, y, width, height, confidence}]`
- `isReady()` → 模型是否加载完成

## 当前状态

- `app.plugin.js`：✅ Config Plugin 逻辑（prebuild 注入 Kotlin + 模型 + gradle 依赖 + MainApplication 注册）
- `android/OcrModule.kt`：✅ ONNX Runtime 推理（det DB 后处理 + rec CTC 解码）
- `android/OcrPackage.kt`：✅ RN Package 注册
- `assets/`：需自行下载放置（见上「模型获取」），版权/体积原因不入仓库

真机构建步骤：放置模型文件 → `npx expo prebuild --platform android`（Config Plugin 会把 Kotlin 源码与 `assets/` 下的模型/字典复制进 `android/`）→ `npx expo run:android`。

> 若之前已 prebuild 过且更换过字典/模型文件，务必重新执行 `npx expo prebuild --clean`，否则 `android/app/src/main/assets/` 下可能残留旧模型/字典。

## v5 → v6 迁移说明

若从 PP-OCRv5 升级，需完成以下步骤：

1. **下载新模型**：按上述「模型获取」章节下载 v6 模型和字典
2. **删除旧文件**：移除 `ppocrv5_det.onnx`、`ppocrv5_rec.onnx`、`ppocrv5_dict.txt`
3. **代码已自动适配**：`OcrModule.kt` 中的常量已更新为 v6 文件名
4. **重新 prebuild**：`npx expo prebuild --clean` 确保旧资产被清理
5. **验证 tensor 名称**：v6 ONNX 模型的输入 tensor 名可能与 v5 不同，若推理报错需用 Netron 检查并调整 `OcrModule.kt` 中的 `detInputs`/`recInputs` map key
