Если не указано иное требование, я просто преобразовал бы ваше цветное изображение в оттенки серого и работал бы только с этим (нет необходимости работать с 3 каналами, контрастность уже слишком высока). Кроме того, если нет какой-либо конкретной проблемы с изменением размера, я бы работал с уменьшенной версией ваших изображений, так как они относительно велики и размер ничего не добавляет к решаемой проблеме. Затем, наконец, ваша проблема решается с помощью медианного фильтра, некоторых основных морфологических инструментов и статистики (в основном для порога Оцу, что уже сделано для вас).
Вот то, что я получаю с вашим образцом и другим изображением с листом бумаги, который я нашел вокруг:
Медианный фильтр используется для удаления мелких деталей с изображения, теперь серого. Это, возможно, удалит тонкие линии внутри беловатой бумаги, что хорошо, потому что тогда вы закончите с крошечными соединенными компонентами, которые легко выбросить. После медианы примените морфологический градиент (просто dilation
- erosion
) и оцифруйте результат по Оцу. Морфологический градиент - это хороший способ сохранить сильные края, его следует использовать чаще. Затем, поскольку этот градиент увеличит ширину контура, примените морфологическое истончение. Теперь вы можете отказаться от мелких компонентов.
На данный момент, вот что мы имеем с правым изображением выше (до рисования синего многоугольника), левый не показан, потому что единственный оставшийся компонент - это тот, который описывает статью:
Учитывая примеры, теперь единственной проблемой остается различие между компонентами, которые выглядят как прямоугольники, и компонентами, которые не выглядят. Это вопрос определения соотношения между площадью выпуклой оболочки, содержащей форму, и площадью ее ограничительной рамки; соотношение 0,7 прекрасно работает для этих примеров. Возможно, вам также придется отказаться от компонентов, которые находятся внутри документа, но не в этих примерах с помощью этого метода (тем не менее, выполнение этого шага должно быть очень легким, особенно потому, что это можно сделать напрямую через OpenCV).
Для справки, вот пример кода в Mathematica:
f = Import["http://thwartedglamour.files.wordpress.com/2010/06/my-coffee-table-1-sa.jpg"]
f = ImageResize[f, ImageDimensions[f][[1]]/4]
g = MedianFilter[ColorConvert[f, "Grayscale"], 2]
h = DeleteSmallComponents[Thinning[
Binarize[ImageSubtract[Dilation[g, 1], Erosion[g, 1]]]]]
convexvert = ComponentMeasurements[SelectComponents[
h, {"ConvexArea", "BoundingBoxArea"}, #1 / #2 > 0.7 &],
"ConvexVertices"][[All, 2]]
(* To visualize the blue polygons above: *)
Show[f, Graphics[{EdgeForm[{Blue, Thick}], RGBColor[0, 0, 1, 0.5],
Polygon @@ convexvert}]]
Если есть более разнообразные ситуации, когда прямоугольник бумаги не так хорошо определен, или подход смешивает его с другими формами - эти ситуации могут возникать по разным причинам, но общей причиной является плохое получение изображения - тогда попробуйте объединение этапов предварительной обработки с работой, описанной в статье «Обнаружение прямоугольника на основе оконного преобразования Хафа».