1、写在前面
读过前面文章的小伙伴一定知道我筹划 Android 版本的 OnnxOCR 已经有一段时间了,而且那时候是 PP-OCRv5 刚刚发布。但项目写着写着,v6 就发布了。以我对 Android 版本的定位,它最好能够让用户简单使用,支持多个模型在PC上可以,但是移动终端上还是有些繁琐,所以我最后决定只支持 PP-OCRv6。
另外,移动端更在意体积和速度,tiny 模型本来就是为此而生;再把 v5 / v6 两套默认参数、字典和后处理长期并行维护,性价比低了些。C# 桌面端 OnnxOCRSharp 已经把 v6 流水线跑顺了,Android 端直接对齐这一套就挺不错。
前面两篇前奏也不是白写的:
- 《OnnxOCRAndroid的前奏1》:用官方 MobileNet V2 示例,把OnnxRuntime Android的依赖引入、Session、预处理、资源释放摸了一遍
- 《OpenCV 5 来了》:同样的分类任务换成OpenCV 5 DNN,同时把官方 Maven 包
org.opencv:opencv:5.0.0在真机上跑通
推理用 OnnxRuntime、图像处理用 OpenCV——这和 OnnxOCRSharp 的分工一致。今天这篇,就是把两边拼起来,正式开源OnnxOCRAndroid。
Demo 已经支持从相册选图,也支持直接拍照识别。核心引擎拆成了独立的onnxocr-core库模块,以后别的 App 也可以本地依赖它。
2、我的成果物
| 交付物 | 说明 |
|---|---|
onnxocr-core | Kotlin OCR 引擎库(AAR),默认 PP-OCRv6 tiny |
app | Demo:相册 / 拍照 → 识别 → 画框 → 一键复制 |
| 模型资源 | det.onnx+rec.onnx+ 字典,打进 Demo assets |
| 流水线 | 检测 → 排序 → 透视裁剪 → 批识别 → 置信度过滤 |
还是采用跟C#端一样的方式,先做出一个能在真机稳定跑通的离线 OCR的MVP,后续继续加能力(方向分类、NNAPI、发布到 Maven 之类),不断完善,不断优化,敏捷开发。
3、核心技术栈
| 层次 | 技术 | 说明 |
|---|---|---|
| 语言 | Kotlin 1.9.20 | 与 Demo / 库统一 |
| 推理 | onnxruntime-android:1.18.0 | 官方 Android AAR,CPU + 多线程 |
| 图像 | org.opencv:opencv:5.0.0 | OpenCV 5 官方 Maven,预处理 / 轮廓 / 透视变换 |
| UI | AppCompat + Material | 选图、拍照、结果展示 |
| 构建 | AGP 8.5.0,compileSdk 34 | minSdk 24 |
关键依赖在onnxocr-core里:
implementation("com.microsoft.onnxruntime:onnxruntime-android:1.18.0") api("org.opencv:opencv:5.0.0")这里有个设计:
- OnnxRuntime 用
implementation:推理细节封在库里,业务 App 一般碰不到 OrtSession - OpenCV 用
api:对外接口是TextSystem.run(Mat),调用方需要自己持有Mat、做bitmapToMat,所以类型必须透传出去
和 C# 端Microsoft.ML.OnnxRuntime+OpenCvSharp4是同一思路,只是 Android 的打包方式换成了 Gradle。
4、项目结构
onnxocr-android/ ├── app/# Demo 应用│ └── src/main/ │ ├── assets/models/ppocrv6_tiny/ │ │ ├── det/det.onnx │ │ ├── rec/rec.onnx │ │ └── ppocrv6_tiny_dict.txt │ └── java/.../MainActivity.kt └── onnxocr-core/# OCR 核心类库└── src/main/java/com/linc/onnxocr/ ├── config/# OcrOptions(v6 默认参数)├── detection/# 检测 + DB 后处理├── recognition/# 识别 + CTC 解码├── imaging/# 裁剪、排序、嵌套框过滤├── inference/# OnnxSessionFactory├── model/# OcrResult / TextLine└── pipeline/# TextSystem 编排分层尽量对齐 OnnxOCRSharp:算法在 Core,Demo 只负责拿图、展示、复制。模型文件放在app的 assets 里——库保持瘦,模型按业务需要自行打包或下载。
5、整体流水线
和桌面端 v6 一样,默认是两阶段(检测 + 识别):
Bitmap / 拍照图 ↓ decode(最长边≤1600,EXIF 校正)→ Mat ↓ TextSystem.run()├─ RGBA/GRAY → BGR ├─ TextDetector(det.onnx)→ DbPostProcess ├─ BoxSorter(从上到下、从左到右) ├─ ImageCropper(透视裁剪;竖排高/宽≥1.5 则转90°) ├─ TextRecognizer(rec.onnx,按宽度比批推理)→ CTC └─ dropScore 过滤 ↓ OcrResult(文本 + 置信度 + 四边形框 + 总耗时)对外真正要记住的类就两个:OcrOptions和TextSystem。
6、让我们跑通 Demo
6.1 环境
- Android Studio Hedgehog(2023.1.1)或更新
- Kotlin 1.9.20 / AGP 8.5.0
- 真机
源码地址见文末。打开工程根目录即可。
6.2 同步、编译、安装
- Android Studio → Open → 选择
onnxocr-android/