Обнаружение документа на отсканированном изображении OpenCV

Я использую OpenCV для предварительной обработки изображений. Мне нужно вырезать только отсканированное фото, без белой области. Я использую алгоритм:

  • image_canny ‹- применить детектор краев к этому каналу
  • для порога в bundle_of_increasing_thresholds:
  • image_thresholds[threshold] ‹- применить порог к этому каналу для каждого контура, найденного в {image_canny} U image_thresholds:
  • Примерный контур с многоугольниками
  • если аппроксимация имеет четыре угла и углы близки к 90 градусам, найдите прямоугольный объект на отсканированном изображении. Но этот пример не сработает, если я положу свое изображение в угол сканера!

Кто-нибудь может подсказать, как мне найти это фото на отсканированном изображении? есть примеры, методы?


person viton-zizu    schedule 23.09.2014    source источник
comment
было бы лучше, если бы вы поделились некоторыми образцами изображений или другим соответствующим изображением.   -  person Balaji R    schedule 24.09.2014
comment
Спасибо за редактирование! Образцы конечно прикрепляю: sample1, пример2   -  person viton-zizu    schedule 25.09.2014


Ответы (1)


Есть несколько способов достичь своей цели. Я приведу код для OpenCvSharp, он будет аналогичен простому C++.

  1. Попробуйте добавить нейтральную границу вокруг вашего изображения. Например, вы можете просто добавить 10-20 пикселей белого цвета вокруг исходного изображения. Это может создать ложные контуры, но ваша целевая часть изображения все равно больше не будет находиться в углу.

    Mat img = Cv2.ImRead("test.jpg");
    Mat imgExtended = new Mat(new OpenCvSharp.Size(img.Size().Width + 40, img.Size().Height + 40), MatType.CV_8UC3, Scalar.White);
    OpenCvSharp.Rect roi = new OpenCvSharp.Rect(new OpenCvSharp.Point(20, 20), img.Size());
    img.CopyTo(imgExtended.SubMat(roi));
    img = imgExtended;
    Mat coloredImage = img.Clone();
    Cv2.CvtColor(img, img, ColorConversionCodes.BGR2GRAY);
    OpenCvSharp.Point[][] contours;
    HierarchyIndex[] hierarchy;
    Cv2.Canny(img, result, 80, 150);
    Cv2.FindContours(result, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxSimple);
    
  2. У вас есть объект и практически белый фон. Вы можете выполнить любую операцию порогового значения, а затем взять самый большой двоичный объект.

Обновление. В обоих случаях темная линия в верхней части изображения и темная область в левом углу все еще могут быть проблемой. В этом случае можно выбрать контур с наибольшей площадью по функции

double Cv2.ContourArea(Point[] Contour);

А затем попробуйте создать ограничивающую рамку, которая минимизирует ошибку.

person Melnikov Sergei    schedule 28.07.2017