Реализация сканирования документов через камеру мобильного приложения
Мы — команда мобильных инженеров с 7+ летним опытом в компьютерном зрении на iOS и Android. За это время мы реализовали сканирование для паспортов, договоров, квитанций и книжных разворотов. Пользователь держит телефон над документом, приложение автоматически находит края листа, выравнивает перспективу и отдаёт чистый PDF. Это не «сфотографировать и обрезать» — внутри детектор контуров (Canny, Hough), гомографическая трансформация и пост-обработка для читаемости. Каждый шаг можно испортить, если не учесть особенности освещения и типы документов. Свяжитесь с нами, чтобы оценить ваш проект — мы поможем выбрать оптимальное решение.
Почему детектор краёв ломается на бликах и тенях
На iOS VNDetectRectanglesRequest (Vision) возвращает VNRectangleObservation с четырьмя corner points в нормализованных координатах. Проблема — на глянцевой бумаге под прямым светом алгоритм путает блик с краем листа. Решение: перед детекцией применяем CIFilter с CIColorControls (уменьшаем inputSaturation) и CIHighlightShadowAdjust. Это убирает блики как артефакты цвета. Дополнительно можно увеличить контраст (уровень 1.2-1.5) для улучшения разделения краёв.
На Android ML Kit Document Scanner (com.google.android.gms:play-services-mlkit-document-scanner) справляется лучше с тенями, но требует Google Play Services. Альтернатива без зависимости от GMS — OpenCV findContours + approxPolyDP с фильтром по площади и соотношению сторон. Порог minArea = 30% от площади кадра отсекает фоновые объекты. Подробнее об алгоритме — в документации OpenCV. Для Flutter мы используем нативный channel через cunning_document_scanner, который делегирует детекцию на платформу.
Как выбрать между нативным SDK и OpenCV?
Выбор зависит от экосистемы. Если приложение использует Google Play Services, ML Kit даёт готовый UI и хорошую точность. Для устройств без GMS (например, Huawei) — OpenCV. На iOS Vision — оптимальный выбор с 2017 года, поддерживает Live Photo и Metal acceleration. Однако OpenCV требует лицензионных оговорок (BSD) и больше кода. Производительность: на iPhone 13 детекция Vision занимает ~80 мс, OpenCV (~120 мс с оптимизацией NEON).
Как правильно выполнить коррекцию перспективы
После получения четырёх точек применяем perspective transform. iOS: CIPerspectiveCorrection с явной передачей inputTopLeft, inputTopRight, inputBottomLeft, inputBottomRight в координатах изображения (не превью). Частая ошибка — использовать координаты превью-слоя напрямую без пересчёта через VNImagePointForNormalizedPoint. Android: getPerspectiveTransform + warpPerspective из OpenCV или матричная трансформация через android.graphics.Matrix.setPolyToPoly. Второй вариант работает без OpenCV, но ограничен аффинными преобразованиями — для сильного перспективного искажения не подходит. На Flutter — ручной расчёт гомографии с помощью image пакета или нативный channel.
Техническая реализация коррекции перспективы
Для iOS: после получения точек из VNRectangleObservation, преобразуем их в координаты изображения через VNImagePointForNormalizedPoint. Затем передаём в CIPerspectiveCorrection. Для отладки рисуем контур на AVCaptureVideoPreviewLayer через CAShapeLayer с обновлением каждый 5 кадров. На Android: используем getPerspectiveTransform из OpenCV, но для не-OpenCV пути — setPolyToPoly с PST (perspective transform) через Matrix. Важно: при сильном искажении аффинные преобразования дают ошибку до 15% на краях.
Постобработка: читаемость важнее красоты
После выпрямления документ нужно обработать для читаемости при распечатке или OCR:
-
Адаптивная бинаризация —
cv::adaptiveThresholdс методом Gaussian лучше чем Otsu на документах с неравномерной подсветкой. - Deskew — если документ повёрнут на 1-2° после трансформации, Hough Lines находят наклон текстовых строк и корректируют.
-
Резкость —
CISharpenLuminance(iOS) илиSharpnessfilter (Android) с умеренным значением (0.4-0.6), не больше.
Цветовые режимы стоит дать пользователю: «Авто», «Документ» (чёрно-белый), «Фото» (полный цвет). В режиме «Документ» — бинаризация. В «Авто» — анализ гистограммы: если документ содержит <5% насыщенных пикселей, применяем монохромную обработку.
| Этап | iOS | Android | Flutter |
|---|---|---|---|
| Детекция | Vision (VNDetectRectanglesRequest) | ML Kit Document Scanner / OpenCV | cunning_document_scanner / channel |
| Трансформация | CIPerspectiveCorrection | OpenCV warpPerspective / Matrix.setPolyToPoly | Dart manual (image package) |
| Постобработка | CIFilters (Sharpen, Binarization) | OpenCV adaptiveThreshold + deskew | Platform channel / dart filters |
| Экспорт PDF | PDFKit (UIGraphicsPDFRenderer) | android.graphics.pdf.PdfDocument | pdf package (pub.dev) |
Обзор производительности на разных платформах
| Параметр | iOS (iPhone 13) | Android (Pixel 6) | Flutter (нативный channel) |
|---|---|---|---|
| Время детекции | ~80 мс | ~110 мс | ~150 мс (с bridge overhead) |
| Размер PDF (A4) | ~200 КБ | ~220 КБ | ~230 КБ |
| Частота превью | 30 FPS | 30 FPS | 24 FPS |
Многостраничный скан и PDF
Собираем UIImage[] / Bitmap[], экспортируем через PDFKit (iOS 11+) или android.graphics.pdf.PdfDocument. На Flutter — пакет pdf (pub.dev). Размер PDF оптимизируем: JPEG compression 85% достаточно для читаемости, при этом страница A4 занимает ~150-250 КБ против 2-4 МБ PNG. Превью в реальном времени: показываем контур поверх AVCaptureVideoPreviewLayer / PreviewView через CAShapeLayer / SurfaceView. Обновляем контур раз в 3-5 кадров (не на каждый) — иначе детектор съедает CPU и превью тормозит.
Что входит в работу по интеграции сканирования
- Аудит требований: анализ типов документов, условий съёмки, целевых платформ.
- Выбор SDK: нативные Vision/ML Kit vs OpenCV vs готовые решения.
- Интеграция превью с динамическим оверлеем контура.
- Реализация детекции, коррекции перспективы и постобработки.
- Экспорт в PDF с настройкой сжатия и цветовых режимов.
- Тестирование на 10+ типах документов: паспорт, договор, квитанция, книжный разворот.
- Документация по API и передача исходного кода.
Наш опыт: более 50 успешных проектов по сканированию, более 5 лет на рынке мобильной разработки. Мы гарантируем стабильную работу на современных устройствах. Закажите интеграцию сканирования документов в ваше приложение — свяжитесь с нами для оценки сроков и стоимости. Сроки: от 3 до 5 рабочих дней на одну платформу, с OCR — плюс 2-3 дня.
Дополнительная информация: гомографическая трансформация – ключевой элемент коррекции перспективы.







