opencv: использование контуров и преобразования Хафа при обнаружении прямоугольника

Я пытаюсь обнаружить белые прямоугольники на изображении в градациях серого, используя разные подходы: определение контура и преобразование Хафа. К сожалению, есть некоторые ограничения изображения, которое я обрабатываю, т.е.

  1. На изображении много функций, и прямоугольник - не единственные функции.
  2. Прямоугольник может быть объединен с другими объектами (например, один из краев прямоугольника может быть перекрыт длинной прямой линией)
  3. Прямоугольник может содержать некоторые другие функции (например, буквы, цифры или какой-либо логотип внутри прямоугольника).
  4. Некоторые функции выглядят как прямоугольник (например, символ «D» выглядит как прямоугольник с небольшой дугой в правом верхнем и правом нижнем углу; другой пример - трапеция вместо параллелограмма)
  5. Прямоугольник можно было вращать от 0 до 15 градусов как по часовой стрелке, так и против часовой стрелки.
  6. Возможно, что линии разбиваются на несколько строк в разных условиях освещения (например, с промежутком в 1 пиксель), поэтому минимальная длина строки для фильтрации линий должна быть небольшой (например, в преобразовании Хафа).
  7. Когда минимальная длина строки установлена ​​на маленькое значение, чаще можно увидеть повторяющиеся строки для одной и той же строки в разных ориентациях (т.е. необходимо объединить несколько строк)

Для контонурного подхода контуры некоторых изображений нарушены. Кроме того, изображение может содержать такие элементы, как прямоугольник (например, символ «D»). Я не уверен, что это хороший подход.

Я видел много статей/форумов, предлагающих использовать преобразование Хафа для обнаружения прямоугольника, как в следующем посте. К сожалению, я должен установить небольшое значение минимальной длины строки и видел повторяющиеся строки. Я понятия не имею, как работать с точками, упомянутыми выше (например, объединить все повторяющиеся линии и выбрать только одну линию для каждого края, как различать объекты, большая часть которых является линиями, но с небольшими дугами, такими как «D», и как выделить квадрат с одним краем, объединенным длинной прямой линией и т. д.).

Преобразование Hough против обнаружения контура для распознавания прямоугольника с перспективной проекцией < /а>

Любые предложения приветствуются!

РЕДАКТИРОВАТЬ: добавить несколько изображений

Персонаж D

Персонаж D

Прямой край слился с длинной прямой линией

Прямоугольник с логотипом и краями, объединенными длинной прямой линией

введите здесь описание изображения

Трапеция (с тенью вверху, образующей трапецию внизу)


person chesschi    schedule 06.05.2015    source источник
comment
Показ примера входного изображения поможет   -  person Antonio    schedule 06.05.2015
comment
@Antonio: изображения добавлены, спасибо :)   -  person chesschi    schedule 07.05.2015


Ответы (1)


Я предлагаю вам попробовать использовать бинарный порог (адаптивный или другой) на каждом изображении, это даст несколько четких линий для обнаружения контуров. Вы также можете размывать/расширять изображения, чтобы удалить шум (например, тонкие линии на втором изображении)

Затем используйте обнаружение контуров и подсчитайте контуры, найдя самый большой объект на изображении с четырьмя сторонами (вероятно, это будет ваш объект).

Сделайте копию изображения, прежде чем использовать бинарное/размытие, так что, как только вы получите интересующую область от обнаружения контура, вы можете обрезать копируемое изображение до этой области.

Извините, ссылки на примеры написаны на питоне, но я уверен, что как только вы поймете эту идею, портировать их на C++ будет легко.

Надеюсь это поможет.

ИЗМЕНИТЬ

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

Ниже см. результаты:

введите здесь описание изображения

Ограничивающая рамка вокруг самого большого набора контуров

введите здесь описание изображения

То же самое, нарисованное поверх исходных изображений

введите здесь описание изображения

person Aphire    schedule 07.05.2015
comment
Я сделал то же самое, как вы предложили в прошлом. Однако я обнаружил, что контуры прямоугольника могут быть разбиты на 2-3 половины в разных условиях освещения после бинарного порога. Мне кажется, преобразование Хафа дало лучшую линию. Я понимаю, что нам нужно найти точки пересечения, чтобы получить прямоугольник. Однако, если для каждого края имеется более одной линии с разной ориентацией, знаете ли вы, как я могу объединить линии в одну и найти пересечение? Для подхода контуров, я думаю, будет сложнее комбинировать контуры, чем линии Хафа. - person chesschi; 08.05.2015
comment
Если вы используете адаптивный порог (как видно по ссылке), вы должны обнаружить, что объект не разбит, так как порог рассчитывается в нескольких локальных областях, а не во всем изображении, это гарантирует, что условия освещения будут иметь гораздо меньший эффект. в бинарном файле, который вы получите в конце. Если вы обнаружите, что тонкие линии дают вам лучшие результаты, возможно, придерживайтесь этого, я считаю, что всегда проще адаптировать то, что вам удобно, для достижения ваших целей. Если вы можете получить XY или каждый конец линий, вы можете выбрать правильные линии на основе тех, которые его окружают. - person Aphire; 08.05.2015
comment
Я вспомнил, что также пробовал адаптивный порог, но он дал худшие результаты. Для преобразования Хафа существует ли обычная практика выбора правильной линии или объединения линий в одну для каждого ребра? - person chesschi; 08.05.2015
comment
Я бы посоветовал вам вернуться к пороговым значениям и контурам, я только что попробовал это, и это было довольно успешно, я использовал глобальный порог для получения бинарного изображения, затем обнаружил контуры и нарисовал ограничивающую рамку вокруг самого большого набора контуров, я отредактирует мой пост с изображениями для вас - person Aphire; 08.05.2015
comment
Большое спасибо за ваши усилия ... но основная цель - идентифицировать только прямоугольник (например, велосипед) и отфильтровать все другие прямоугольные объекты, такие как буква «D» и трапеция. Извините, если я не ясно выразился в вопросе. - person chesschi; 08.05.2015
comment
Ах да, извините, я думаю, что неправильно понял. В этом случае я бы все же посоветовал использовать двоичный порог, прежде чем пробовать свои линии, так как это делает изображение более чистым, надеюсь, эта статья может вам помочь: opencv-code.com/tutorials/ Удачи! - person Aphire; 08.05.2015
comment
Возможно, вы сможете использовать приведенную выше ссылку, чтобы найти средний угол, пройдя все ваши поперечные линии, запустив пример, чтобы найти угол на основе пересекающихся линий, а затем найти области, где пересекается наибольшее количество линий, если у вас слишком много поперечных линий, это может помочь определить правильные углы - person Aphire; 11.05.2015
comment
Интересный момент! Я просматривал этот пост раньше, но понятия не имел, как объединить линии Хафа. Итак, вы предлагаете не объединять линии, а затем находить пересечения, но вы предлагаете наоборот. Это правильно? Я не знаком с преобразованием Хафа. Является ли нахождение областей, в которых пересекается наибольшее количество линий, обычной практикой для поиска прямоугольника, когда линий много? Большое спасибо! - person chesschi; 11.05.2015
comment
Я должен признать, я не знаю, является ли это обычной практикой, но я бы сделал именно так: PI думаю, что если вы используете двоичный порог, а затем можете изменить изображение, это должно избавиться от большей части шума, учитывая ваши линии. если быть более точным, если вы все еще получаете много линий, то вы можете видеть, насколько точно работает средний угол :) - person Aphire; 12.05.2015