Поиск разделения Sky/Ground в OpenCV

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

Следующее делает сложнее:

  • Горизонт редко является прямой линией в используемых изображениях (горные ландшафты), поэтому обнаружение края и преобразование линии Хау не будут работать.
  • Он должен работать во всех условиях освещения. Порог (например, порог Otsu) работает, но не работает хорошо в условиях низкой контрастности, таких как до восхода солнца. Порог фиксированного значения не работает, поскольку свет меняется слишком сильно в течение дня.

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

Я пишу код в Delphi XE8, используя оболочку OpenCV, но ответы или идеи на любом другом языке приветствуются!

Ответ 1

В моем понимании вы ищете горизонтальную линию - если вообще существует - отделять исключительно часть от остальных.

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

Он может быть основан даже на глобальном пороге или пользовательской функции "неба". Определите каким-то образом (интенсивность, оттенок), если пиксели небо или нет, и подсчитайте их в пределах строк сканирования.

Затем половину изображения по горизонтали, значения строк строк для обеих частей и определите, в каком направлении должна перемещаться ваша горизонтальная линия. Половина этой части тоже и продолжайте, пока не дойдете до правильной строки. При таком бинарном поиске вы сможете извлечь, какая строка отделяет небо от переднего плана. Если это первая строка: не небо, если последнее: все небо.

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

Ответ 2

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

Вы можете сделать это в OpenCV с iOS. Свяжите свой проект OpenCV с компасом, который находится в IPhone. Затем отделите небо от земли, как это сделал компас App.

См. http://imgur.com/bwLpaOC

Ответ 3

Вы можете попробовать сверточные глубокие нейронные сети, например http://mi.eng.cam.ac.uk/projects/segnet/, или обучить свою собственную аналогичную сеть.