# PhotoOCR **Repository Path**: kin1987/photo-ocr ## Basic Information - **Project Name**: PhotoOCR - **Description**: PhotoOCR - Android 离线 OCR 应用 基于 ONNX Runtime + PaddleOCR 模型的纯本地 Android OCR 应用。 零网络请求、零第三方 API 依赖,所有推理均在设备本地完成。 - **Primary Language**: Kotlin - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2026-04-30 - **Last Updated**: 2026-09-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # PhotoOCR - Android 离线 OCR 应用 基于 ONNX Runtime + PaddleOCR 模型的纯本地 Android OCR 应用。 零网络请求、零第三方 API 依赖,所有推理均在设备本地完成。 ## 功能 - 📷 拍照识别 / 相册选图 / 批量识别 - 📄 PDF 文件识别 - 📑 分页浏览结果,滑动换页 - ✏️ 点击高亮文字区域,长按编辑识别结果 - 📋 复制当前页 / 全部识别结果 - 💾 识别进度实时显示 - 🔒 完全离线,不上传任何数据 ## 环境要求 | 项目 | 要求 | |------|------| | 系统 | Android 7.0+ (API 24) | | 架构 | ARM64 / ARMv7 | | Android Studio | 2022.3.1+ (推荐最新版) | | JDK | 17+ (Android Studio 自带) | | SDK | compileSdk 35 | ## 快速开始 ### 方式一:Android Studio(推荐) 1. **克隆项目** ```bash git clone <仓库地址> cd PhotoOCR ``` 2. **打开项目** - 启动 Android Studio - File → Open → 选择项目根目录 - 等待 Gradle 自动同步完成 3. **运行** - 连接手机并开启 USB 调试,或启动模拟器 - 点击 Run 按钮 (▶️) 或 `Shift + F10` ### 方式二:命令行编译 ```bash # 编译 Debug 版本 ./gradlew assembleDebug # 编译 Release 版本 ./gradlew assembleRelease ``` APK 输出位置: - Debug: `app/build/outputs/apk/debug/app-debug.apk` - Release: `app/build/outputs/apk/release/app-release.apk` 安装到手机: ```bash adb install app/build/outputs/apk/debug/app-debug.apk ``` ### 常见问题 **Q: Gradle Sync 失败,提示 SDK 未安装** ``` Failed to find target with hash string 'android-35' ``` 打开 SDK Manager,安装 Android 15 (API 35) SDK Platform。 **Q: 提示 JDK 版本不匹配** Android Studio 自带 JDK,确保使用 AS 自带的 JDK: - File → Settings → Build → Gradle → Gradle JDK → 选择 `jbr` 或 `17` **Q: 编译时内存不足** 在 `gradle.properties` 中调整: ```properties org.gradle.jvmargs=-Xmx4096m ``` ## 架构 ``` 拍照/选图 → 检测(DBNet) → 分类(Cls) → 识别(CRNN+CTC) → 输出文字 ↑ ↑ ↑ det模型.onnx cls模型.onnx rec模型.onnx ``` 全部推理通过 ONNX Runtime Android SDK 执行,纯 Kotlin 实现 PP-OCR 的前处理和后处理逻辑。 ## 项目结构 ``` app/src/main/java/com/photoocr/ ├── MainActivity.kt # 主界面:菜单/选图/分页结果 ├── ImageSelectionAdapter.kt # 图片批量选择网格 ├── OcrPageAdapter.kt # ViewPager2 分页适配器 ├── TextLinesAdapter.kt # 文字列表适配器 ├── OcrHighlightView.kt # 文字框高亮绘制 ├── OCRManager.kt # OCR 管理器:协调 det→cls→rec ├── OCRResult.kt # 数据模型 └── ocr/ ├── OnnxEngine.kt # ONNX Runtime 推理封装 ├── OcrDetector.kt # DBNet 文本检测 + 后处理 ├── OcrClassifier.kt # 方向分类(180°旋转检测) ├── OcrRecognizer.kt # CRNN + CTC 文本识别 └── OcrUtils.kt # 图像处理工具 ``` ## 模型文件 内置 PP-OCRv5 mobile 模型(`app/src/main/assets/`): | 文件 | 说明 | 大小 | |------|------|------| | ch_PP-OCRv5_det_infer.onnx | 文本检测 | ~4.8MB | | ch_PP-OCRv5_rec_infer.onnx | 文本识别 | ~16.6MB | | ch_ppocr_mobile_v2.0_cls_infer.onnx | 方向分类 | ~571KB | | ppocr_keys_v1.txt | 中文字典 | ~74KB | **PP-OCRv5 vs PP-OCRv4(mobile 模型):** - 印刷中文检测:90.5% vs 87.2% (+3.3%) - 印刷英文检测:91.0% vs 77.3% (+13.7%) - 推理速度提升 22.6%,模型体积减少 50% ## 手写体优化 调整 `OcrDetector.kt` 中的阈值: ```kotlin const val BIN_THRESH = 0.3f // 降低 → 检测更多笔划 const val BOX_THRESH = 0.5f // 降低 → 保留低置信度区域 const val UNCLIP_RATIO = 1.6f // 增大 → 扩展文本框 ``` ## 性能参考 | 设备 | 检测 | 识别(25行) | 总计 | |-----|------|-------------|------| | 骁龙 865 | ~80ms | ~50ms/行 | ~1.1s | | 红米 Note 9 | ~400ms | ~300ms/行 | ~8s | ## 依赖 - ONNX Runtime Android 1.19.2 - CameraX 1.3.1 - Kotlin Coroutines 1.9.0 - Material Design 3 - ViewPager2 ## License MIT