Разработка мобильного приложения для сканера визиток
Задача выглядит просто: сфотографировал визитку — получил контакт в адресной книге. На практике между снимком и правильно заполненным CNContact — цепочка, в которой ломается всё, что может сломаться: плохое освещение, нестандартные шрифты, двуязычные визитки, вертикальная ориентация текста на японских карточках.
Распознавание текста: Vision vs ML Kit vs облако
На iOS первый выбор — Vision framework с VNRecognizeTextRequest. С iOS 16 точность распознавания выросла, поддерживается 18 языков, работает полностью offline. Для большинства задач достаточно.
let request = VNRecognizeTextRequest { request, error in
guard let observations = request.results as? [VNRecognizedTextObservation] else { return }
let strings = observations.compactMap { $0.topCandidates(1).first?.string }
self.parseBusinessCard(lines: strings)
}
request.recognitionLevel = .accurate
request.usesLanguageCorrection = true
request.recognitionLanguages = ["ru-RU", "en-US"]
let handler = VNImageRequestHandler(cgImage: image, options: [:])
try? handler.perform([request])
На Android — ML Kit Text Recognition v2. Он поддерживает латиницу, кириллицу, китайский, японский, корейский прямо из коробки без дополнительной загрузки моделей. Важный нюанс: TextRecognizer нужно закрывать через close() после использования, иначе — утечка нативных ресурсов.
Когда нужна максимальная точность или поддержка экзотических шрифтов — подключаем Google Cloud Vision API или AWS Textract. Облачные варианты дают структурированный вывод с разделением на блоки, строки, слова с bounding box.
Парсинг распознанного текста в поля контакта
OCR даёт массив строк. Превратить его в {имя: "Иванов Иван", телефон: "+7 999 123-45-67", email: "[email protected]", должность: "CTO"} — отдельная задача.
Регулярные выражения покрывают телефоны и email надёжно. Имена и должности — сложнее. Хороший подход: NER (Named Entity Recognition) через CoreML-модель или лёгкий on-device NLP. Apple NaturalLanguage framework с NLTagger для определения типа токенов (personalName, organizationName) работает неплохо для английского и русского.
Типичная проблема: имя и должность стоят рядом без явных разделителей. Контекст важен — если строка содержит слово из словаря должностей (CEO, директор, менеджер), она, скорее всего, должность.
Для двуязычных визиток (часто встречаются в B2B в СНГ: русский на одной стороне, английский на другой) нужно определять язык каждой строки отдельно через NLLanguageRecognizer / LanguageIdentification из ML Kit и применять соответствующие правила парсинга.
Качество захвата изображения
Финальная точность OCR напрямую зависит от качества снимка. Несколько вещей, которые реально влияют:
-
Перспективная коррекция — визитку держат под углом, нужно выпрямлять. На iOS
CIPerspectiveCorrection+VNDetectRectanglesRequestдля нахождения границ карточки. На Android —OpenCVили ML KitObjectDetector. -
Улучшение контраста —
CIColorControlsс повышенным контрастом и снижением насыщенности помогает при сером тексте на белом фоне. -
Автоматический захват — детектировать карточку в кадре через
VNDetectRectanglesRequestи делать снимок автоматически, когда карточка занимает >60% кадра и стабильна 0.5 секунды. Ручной «нажмите кнопку» ухудшает качество из-за дрожания рук.
Процесс работы
Аудит: целевые языки карточек, нужен ли офлайн-режим, интеграция с CRM или только с контактами устройства.
Реализация: захват с авто-детектом → коррекция перспективы → OCR → парсинг полей → ручное редактирование перед сохранением (обязательно — OCR ошибается).
Тестирование: набор из 100+ реальных визиток разного качества и форматов.
Ориентиры по срокам
Сканер с Vision/ML Kit, базовым парсингом и сохранением в контакты — 2–3 недели. С облачным OCR, NER, поддержкой нескольких языков и интеграцией с CRM — 5–7 недель.







