← Усі статті

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 — розрив у рази частіше важливіший за зайві мегабайти нативного середовища виконання.

Коментарі

Завантаження коментарів…