Реалізація сканування документів через камеру мобільного застосунку
Користувач тримає телефон над контрактом, застосунок автоматично знаходить краї, виправляє перспективу і видає чистий PDF. Це не просто «сфотографувати і обрізати» — тут внутрішній детектор контурів, гомографічна трансформація та пост-обробка. Кожен крок може привести до помилки.
Найчастіші проблеми
Детектор краї не працює на відблисках та тінях
VNDetectRectanglesRequest (iOS Vision) повертає VNRectangleObservation з чотирма corner points у нормалізованих координатах. Проблема: на глянцевому папері під прямим світлом алгоритм плутає відблиск з краєм аркуша. Рішення — перед детекцією застосовуємо CIFilter з CIColorControls (зменшуємо inputSaturation) і CIHighlightShadowAdjust. Це прибирає відблиски як артефакти кольору.
На Android Vision API (com.google.android.gms:play-services-mlkit-document-scanner) краще справляється з тінями, але вимагає Google Play Services. Альтернатива без залежності від GMS — OpenCV findContours + approxPolyDP з фільтром за площею та співвідношенням сторін. Поріг minArea = 30% від площі кадру відсікає фонові об'єкти.
Коректування перспективи
Після отримання чотирьох точок застосовуємо perspective transform. iOS: CIPerspectiveCorrection з явною передачею inputTopLeft, inputTopRight, inputBottomLeft, inputBottomRight у координатах зображення (не превью). Частої ошибки — використовувати координати превью-шару напряму без перерахунку через VNImagePointForNormalizedPoint.
Android: getPerspectiveTransform + warpPerspective з OpenCV або матрична трансформація через android.graphics.Matrix.setPolyToPoly. Другий варіант працює без OpenCV, але обмежений афінними перетвореннями — для сильного перспективного спотворення не підходить.
Flutter: пакет cunning_document_scanner (обгортка над нативними SDK) або власна реалізація через image + ручний розрахунок гомографії на Dart. Останнє трудомістке, краще нативний channel.
Пост-обробка: читабельність важливіша за красу
Після вирівнювання документ потрібно обробити для читабельності при друку або OCR:
-
Адаптивна бінаризація —
cv::adaptiveThresholdз методом Gaussian краще за Otsu на документах з нерівномірною підсвіткою - Deskew — якщо документ повернутий на 1–2° після трансформації, Hough Lines знаходять нахил текстових рядків і коригують
-
Різкість —
CISharpenLuminance(iOS) абоSharpnessfilter (Android) з помірною величиною (0.4–0.6), не більше
Дайте користувачеві вибір кольорових режимів: «Авто», «Документ» (чорно-білий), «Фото» (повний колір). У режимі «Документ» — бінаризація. У «Авто» — аналіз гістограми: якщо документ містить <5% насичених пікселів, застосовуємо монохромну обробку.
Багатосторінкове сканування та 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) → інтеграція превью з оверлеєм → коректування + пост-обробка → експорт PDF → тестування на 10+ типів документів (паспорт, контракт, квитанція, книжковий розворот).
Терміни: від 3 до 5 робочих днів залежно від платформи та вимог якості. Якщо потрібна інтеграція з OCR-розпізнаванням — додаємо 2–3 дні.







