Реалізація OCR (розпізнавання тексту) через камеру мобільного застосунку
Користувач наводить камеру на ціник, чек, договір або табличку — і застосунок миттєво розпізнає текст. Розрив між «працює в демо» та «працює в production» тут величезний: реальні умови — це погане освітлення, нахилений текст, рукописні елементи та різні мови в одному кадрі.
Рідні OCR-фреймворки без зовнішніх залежностей
iOS: Vision + VNRecognizeTextRequest
З iOS 13 фреймворк Vision умів розпізнавати текст без інтернету. VNRecognizeTextRequest підтримує два режими: .fast (приблизно, миттєво) та .accurate (повільніше, але значно точніше для складних шрифтів).
func recognizeText(in image: UIImage) {
guard let cgImage = image.cgImage else { return }
let request = VNRecognizeTextRequest { [weak self] request, error in
guard let observations = request.results as? [VNRecognizedTextObservation] else { return }
let text = observations.compactMap { $0.topCandidates(1).first?.string }.joined(separator: "\n")
DispatchQueue.main.async { self?.handleRecognized(text: text) }
}
request.recognitionLevel = .accurate
request.usesLanguageCorrection = true
request.recognitionLanguages = ["ru-RU", "en-US"] // порядок = пріоритет
let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
try? handler.perform([request])
}
usesLanguageCorrection допомагає з опечатками, але іноді «виправляє» скорочення та коди артикулів — для технічних документів краще відключити.
Android: ML Kit Text Recognition v2
com.google.mlkit:text-recognition підтримує латиницю, кирилицю, китайську, японську, корейську через окремі модулі. Завантажується при першому використанні (~5 МБ для латиниці).
val recognizer = TextRecognition.getClient(
TextRecognizerOptions.DEFAULT_OPTIONS // або RussianTextRecognizerOptions
)
val image = InputImage.fromBitmap(bitmap, 0)
recognizer.process(image)
.addOnSuccessListener { visionText ->
val fullText = visionText.textBlocks
.joinToString("\n") { block -> block.text }
handleRecognized(fullText)
}
.addOnFailureListener { e -> handleError(e) }
ML Kit також повертає bounding boxes для кожного текстового блоку — корисно для підсвітлення розпізнаних областей в UI.
Live-режим: текст у реальному часі з відеопотоку
Для live-overlay (текст підсвічується прямо в відеопотоці) на iOS використовуємо AVCaptureSession + CMSampleBuffer:
// Метод делегата AVCaptureVideoDataOutput
func captureOutput(_ output: AVCaptureOutput,
didOutput sampleBuffer: CMSampleBuffer,
from connection: AVCaptureConnection) {
guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
// Не запускаємо новий запит, якщо попередній ще не завершив
guard !isProcessing else { return }
isProcessing = true
let request = VNRecognizeTextRequest { [weak self] request, _ in
defer { self?.isProcessing = false }
// обробка результатів...
}
request.recognitionLevel = .fast // для live важлива швидкість
try? VNImageRequestHandler(cvPixelBuffer: pixelBuffer, options: [:]).perform([request])
}
Флаг isProcessing обов'язковий — без нього при 30 FPS накопичується черга запитів та пам'ять зростає до краху.
На Android — CameraX + ImageAnalysis.Analyzer. ML Kit оптимізований для роботи з ImageProxy безпосередньо без конвертації в Bitmap.
Постобробка: від «сирого» тексту до структурованих даних
Голий OCR-результат — це потік рядків. Для більшості завдань потрібна структуризація:
- Чеки: виділяємо рядки з цінами за regex, парсимо підсумкову суму
-
Візитки:
NSDataDetector(iOS) абоPatterns(Android) для телефонів, email, адрес - Паспорти/документи: MRZ-зона читається за стандартом ICAO 9303, є готові парсери
- Номерні знаки: окреме завдання — краще спеціалізована модель (OpenALPR, PlateRecognizer API)
Для кирилічного тексту з поганою якістю іноді допомагає передпрограма зображення: збільшення контрастності через vImageContrastStretch, переведення в grayscale, Sharpen CIFilter перед передачею в OCR.
Процес роботи
Визначення сценаріїв використання: тип документів, мови, потрібен ли live-режим або тільки статичне фото.
Реалізація захоплення зображення (камера + галерея), передпрограма.
Інтеграція OCR: рідні Vision/ML Kit або хмара (Google Vision API, AWS Textract) якщо потрібна вища точність для складних документів.
Постобробка під конкретну задачу: структурування даних, regex, NER.
Тестування на реальних зразках у різних умовах освітлення.
Орієнтири за часом
Базове розпізнавання статичного тексту через рідний фреймворк — 2–3 дні. Live-режим з overlay + структурування даних під конкретний тип документа — 1–2 тижні.







