← Все статьи

react-native-glyph-ocr: кириллица на Android без ML Kit

Библиотека OCR для React Native: Apple Vision на iOS, PaddleOCR на Android. На русских этикетках 77–83% против 13–28% у ML Kit; пакет в npm.

react-native-glyph-ocr: кириллица на Android без ML Kit
Содержание

Коротко

Автор выложил в npm пакет react-native-glyph-ocr: распознавание текста прямо на устройстве для React Native. На iOS работает системный Apple Vision, на Android — PaddleOCR.

На фото этикеток с русским составом Android-ветка читает 77–83% ингредиентов. Обёртки над Google ML Kit на том же наборе дали 13–28%: у Text Recognition v2 нет модели для кириллицы, и русский текст часто «читается» как похожая латиница.

Пакету нужна «новая архитектура» (New Architecture); проверен на React Native 0.85 и 0.87. Для Expo — отдельная сборка для разработки (development build), в Expo Go не заработает.

Что произошло

Нужно было приложение, которое снимает этикетку и разбирает состав. Текст на русском, часто вперемешку с английским, на фольге, мятом пакете, термопечати и даже по дуге банки. Стандартный путь в React Native — обёртки над ML Kit. На латинице они справляются; на кириллице — ломаются: буквы подменяются похожими латинскими, и слово уже не узнать.

На iOS системный Vision с iOS 16 читает русский и украинский без своей модели. Значит, одна библиотека должна скрыть два движка за одним результатом для JavaScript. Автор сначала прогнал спайки на одних фото и одном ручном эталоне: Vision (ревизия 3, режим .accurate, языки ru-RU и en-US) против PaddleOCR PP-OCRv5 mobile на ONNX Runtime с пакетом для восточнославянских языков (eslav: ru, uk, be, en).

Цифры спайков: на обрезанном составе Vision на iPhone 13 Pro Max — около 0,15 с и до 97% ингредиентов; PaddleOCR на Pixel 6a — около 1,1 с и 77–83%. Модели Paddle весят 12,7 МБ один раз; ONNX Runtime добавляет ~33 МБ на архитектуру процессора (ABI). Готовый пакет на TypeScript поверх ONNX автору не подошёл: нужны были кадры камеры и форма результата как у ML Kit, поэтому конвейер на Android написан нативно на Kotlin и C++.

Результат устроен привычно: блоки → строки → слова, уверенность, рамка и угол. Языки задаются при создании экземпляра (createOcr / recognize), модели готовятся один раз (prepare) и кэшируются. Источники — локальные URI, base64, кадр VisionCamera; ссылки http(s) отклоняются намеренно. Есть типизированные ошибки (OcrError) и отмена через AbortSignal. Модели качаются по манифесту с проверкой sha256; можно указать свой сервер или встроить пакеты в сборку.

Для камеры — хук useTextScanner: сначала нативный измеритель (~1 мс) ждёт резкий, неподвижный и достаточно светлый кадр, и только потом один раз запускает распознавание. Перевёрнутый текст на Android решается двойным чтением длинных строк, а не отдельным классификатором ориентации — тот на русских этикетках ошибался слишком часто.

Почему это важно

Представьте кассу самообслуживания, которой подсовывают мятый чек на языке, которого «глаза» камеры не учили. Система не молчит — она уверенно читает чужой алфавит и выдаёт мусор. Именно так ведёт себя ML Kit на кириллице без своей модели: формально ответ есть, смысла в составе продукта — нет.

Для мобильных продуктов с русскими, украинскими и смешанными этикетками это не мелочь интерфейса, а потолок точности. Пока команда тащит облачное распознавание или мирится с 13–28% на устройстве, приложение для состава еды, аптечных вкладышей или документов просто не дотягивает до боевой среды.

Разные движки под одной обёрткой снимают ложную дилемму «либо нативный iOS-код, либо слабый Android». Один API в JavaScript, привычная форма результата для тех, кто уже на ML Kit, и честные цифры по размеру и скорости — так проще спорить на архитектурном разборе, а не на ощущениях.

Цена тоже на виду: на Android тянется ONNX Runtime, набор для замеров узкий (пищевые этикетки), бюджетный телефон пока только оценён по медленным ядрам. Зато альтернатива ExecuTorch (~1,7 МБ) уже в точке входа для разработки — путь к более лёгкой поставке намечен.

На практике

Первый релиз в npm — 0.3.1; до 1.0 API ещё может меняться. Имеет смысл прогнать свой набор фото, а не копировать чужие проценты.

  1. Установите react-native-glyph-ocr и react-native-nitro-modules; на iOS выполните pod install. Нужна «новая архитектура» (New Architecture), iOS 16+, Android 7+ (сканер камеры — Android 10+).
  2. В Expo добавьте плагин в app.json и соберите сборку для разработки; опция embedPacks (например ["eslav"]) вшивает модели в APK, чтобы не качать их при первом запуске.
  3. Задайте языки один раз через createOcr({ languages: ['ru', 'en'] }), вызовите prepare, затем recognize с roi, если состав занимает только часть кадра — так на Android заметно быстрее.
  4. Для живой камеры подключите VisionCamera 5 и useTextScanner: не распознавайте каждый кадр из onFrame напрямую — секунда на Android заблокирует поток кадров.
  5. Если сейчас на @react-native-ml-kit/text-recognition, откройте руководство по переходу в репозитории: форма блоков и строк совместима по идее, меняется движок и подготовка моделей.
  6. Сверьте слабые места на своих данных: коды E читаются хуже (~60%), набор автора — 32 фото этикеток; на другом типе текста цифры будут другими.
  7. Следите за сообщениями об ошибках и сравнительными тестами в docs/benchmarks.md: автор планирует замер на бюджетном Android, калибровку порогов сканера по реальным кадрам и возможный переход на ExecuTorch по умолчанию.

Итог

react-native-glyph-ocr закрывает дыру, которую ML Kit оставляет на кириллице: Vision на iOS, PaddleOCR на Android, один результат для JS и пакет уже в npm.

Если приложение читает русские этикетки на устройстве, сравните свой набор фото с обёрткой над ML Kit — разрыв в разы чаще важнее, чем лишние мегабайты нативной среды выполнения.

Комментарии

Загрузка комментариев…