OCR: embedded, cross-platform ONNX backend with pluggable fallback
Make on-device OCR a pluggable local service so it runs locally on every platform (not just Windows), aimed at GoodNotes/Notability-class handwriting on low-power hardware (e.g. Zen2 APU, CPU/iGPU). - New OcrBackend abstraction (lib/services/ocr/): selector prefers an embedded ONNX recognition backend, falling back to the OS-native backend (Windows WinRT), and to a clean no-op when neither is available. - OnnxRecognitionBackend: flutter_onnxruntime session from a bundled asset, dart:ui preprocessing (resize to 48px, CHW float32, normalized), pure-Dart CTC greedy decode. Fully guarded — absent model/dict is a no-op; never throws. - ocr_engine.dart kept as a thin facade (recognizeImage) delegating to the selector, so ocr_service.dart is unchanged. - CtcDecoder unit-tested (6 tests). flutter analyze clean; all tests pass. - Model is not committed; tool/fetch_ocr_model.sh + assets/models/ocr/README.md document fetching PP-OCRv4 rec + dict on the dev machine. - CI: forward HTTPS_PROXY to the Windows build so CMake can fetch the ONNX Runtime native lib behind the GFW; README documents the system-install alternative. PP-OCR geometry/blank assumptions documented for on-device tuning. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
69
tool/fetch_ocr_model.sh
Executable file
69
tool/fetch_ocr_model.sh
Executable file
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# fetch_ocr_model.sh — download and prepare the embedded OCR recognition model.
|
||||
#
|
||||
# RUN THIS ON YOUR DEV MACHINE. It downloads the PaddleOCR PP-OCRv4 mobile
|
||||
# recognition inference model + the character dictionary, converts the Paddle
|
||||
# inference model to ONNX, and places the results as:
|
||||
#
|
||||
# assets/models/ocr/rec.onnx
|
||||
# assets/models/ocr/ppocr_keys_v1.txt
|
||||
#
|
||||
# These files are intentionally NOT committed; the app treats their absence as
|
||||
# a clean no-op (OCR falls back to the native backend or returns nothing).
|
||||
#
|
||||
# Requirements: bash, curl, tar, and paddle2onnx (pip install paddle2onnx).
|
||||
#
|
||||
# proxy: export HTTPS_PROXY=http://127.0.0.1:7890 (and HTTP_PROXY) if you are
|
||||
# behind a firewall/GFW that blocks the download hosts.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Resolve repo root relative to this script so it works from any cwd.
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||
OUT_DIR="${REPO_ROOT}/assets/models/ocr"
|
||||
WORK_DIR="$(mktemp -d)"
|
||||
|
||||
# Canonical PaddleOCR sources. Swap to the en_ variant for English-only.
|
||||
REC_INFER_URL="https://paddleocr.bj.bcebos.com/PP-OCRv4/chinese/ch_PP-OCRv4_rec_infer.tar"
|
||||
# REC_INFER_URL="https://paddleocr.bj.bcebos.com/PP-OCRv4/english/en_PP-OCRv4_rec_infer.tar"
|
||||
KEYS_URL="https://raw.githubusercontent.com/PaddlePaddle/PaddleOCR/main/ppocr/utils/ppocr_keys_v1.txt"
|
||||
|
||||
cleanup() { rm -rf "${WORK_DIR}"; }
|
||||
trap cleanup EXIT
|
||||
|
||||
mkdir -p "${OUT_DIR}"
|
||||
|
||||
echo "==> Downloading recognition inference model"
|
||||
curl -fL "${REC_INFER_URL}" -o "${WORK_DIR}/rec_infer.tar"
|
||||
|
||||
echo "==> Extracting"
|
||||
tar -xf "${WORK_DIR}/rec_infer.tar" -C "${WORK_DIR}"
|
||||
# The tarball extracts into a single directory; find it.
|
||||
MODEL_DIR="$(find "${WORK_DIR}" -maxdepth 1 -type d -name '*_rec_infer' | head -n1)"
|
||||
if [[ -z "${MODEL_DIR}" ]]; then
|
||||
echo "ERROR: could not locate the extracted *_rec_infer directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "==> Downloading character dictionary"
|
||||
curl -fL "${KEYS_URL}" -o "${OUT_DIR}/ppocr_keys_v1.txt"
|
||||
|
||||
echo "==> Converting Paddle inference model to ONNX (requires paddle2onnx)"
|
||||
if ! command -v paddle2onnx >/dev/null 2>&1; then
|
||||
echo "ERROR: paddle2onnx not found. Install with: pip install paddle2onnx" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
paddle2onnx \
|
||||
--model_dir "${MODEL_DIR}" \
|
||||
--model_filename inference.pdmodel \
|
||||
--params_filename inference.pdiparams \
|
||||
--save_file "${OUT_DIR}/rec.onnx" \
|
||||
--opset_version 14 \
|
||||
--enable_onnx_checker True
|
||||
|
||||
echo "==> Done:"
|
||||
echo " ${OUT_DIR}/rec.onnx"
|
||||
echo " ${OUT_DIR}/ppocr_keys_v1.txt"
|
||||
Reference in New Issue
Block a user