Поиск ребер на карте высот

Я хочу найти острые края на изображении карты высот, игнорируя мелкие края.

OpenCV предлагает несколько подходов к поиску границ в 2D-изображении: Кэнни, Собел, и т. д..

Однако все эти подходы работают путем сравнения значений интенсивности с обеих сторон края. Если 2D-изображение представляет собой карту высот 3D-объекта, это приводит к странному поведению.

На карте высот высота 3D-объекта в заданной координате X/Y представлена ​​как интенсивность 2D-пикселя в этой координате X/Y:

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

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

На краю A наблюдается большая разница в интенсивности между пикселями на левой стороне края и справа, даже если это всего лишь небольшой угол.

Таким образом, для Кэнни или Собеля не существует порога, который бы сохранял острый край, но отфильтровывал поверхностный край.

(В приведенном выше примере ребро B имеет одну сторону с восходящим уклоном и одну сторону с нисходящим уклоном. Я мог бы отфильтровать этот объект, но при этом также были бы удалены ребра C и D)

Как получить бинарное изображение ребра, содержащее только ребра выше определенного угла? (например, ребро B, C и D, но не A)

Или, альтернативно, как я могу получить производное изображение градиента, где интенсивность каждого пикселя пропорциональна углу края в этом пикселе?


person HugoRune    schedule 05.02.2017    source источник
comment
вы можете проверить угол явно.   -  person Micka    schedule 05.02.2017


Ответы (3)


Вероятно, вы захотите использовать вторую производную вместо первой для этой задачи.

Вот моя интуиция: взятие производной высоты (интенсивности в вашем случае) в каждой позиции на равномерно распределенной сетке будет пропорционально арктангенсу наклона поверхности между точками выборки (или в точках выборки, если вы используете аппроксимация двусторонней производной). Но так как вы хотите обнаружить острые края - вы ищете производную наклона в точках выборки. Это означает, что вы можете установить порог производной арктангенса от производной интенсивности для достижения своей цели (к счастью, нет «нужности идти глубже» :))

Вам нужно быть особенно осторожным с получением производной от «углов наклона», которые вы получите - в зависимости от системы координат вы можете столкнуться с неоднозначностью разности углов (есть 2 способа перейти от одного угла к другому, которые в общем случае разные; вы ищете «более короткий»). Вы можете найти возможное решение здесь

person alexisrozhkov    schedule 05.02.2017

У меня есть довольно простой подход, с которым я столкнулся, читая сообщение в блоге.

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

  • ниже: max(0, (1.0 - 0.33) * v)
  • верхний: min(255, (1.0 + 0.33) * v)

Теперь передайте эти два значения в качестве параметров функции cv2.Canny().

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

person Jeru Luke    schedule 14.02.2017

Если я правильно понял ваш вопрос, «вам нужен в основном угол с высокими значениями интенсивности». Если это так, то ищите угловой детектор Харриса, который поможет вам найти точки с большим изменением градиента в обоих направлениях. http://docs.opencv.org/2.4/doc/tutorials/features2d/trackingmotion/harris_detector/harris_detector.html

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

person Aparajuli    schedule 07.02.2017