Pull to refresh

Обнаружение препятствий на OpenCV. Часть 2

Reading time 4 min
Views 4.9K

С момента последней статьи прошел почти год. Спасибо читателям за комментарии, они здорово помогли, отдельная благодарность @Meklonза идею с фильтрами и в целом за участие в дискуссии. Сама эта идея за весь период времени из головы благополучно вылетела, но видимо не совсем. :) Об этом чуть позже.

Произошло немало событий, времени на мое хобби с автономным катером нашлось откровенно мало. :/

Но идея обнаружения абстрактных препятствий не давала мне покоя. Постоянно казалось, что до результата рукой подать.

Аппаратная часть.

Цены уползли вверх и теперь я не могу позволить легкомысленно утопить аппаратуру катера. Как я рассуждал раньше: "Ну что там Raspberry Pi и несколько датчиков. Всегда можно взять новую "малинку", восстановить образ из бэкапа и продолжить испытания."

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

Поэтому, я спроектировал и распечатал на 3d принтере новый герметичный корпус с аккумуляторным отсеком.

Герметичный бокс для электронной начинки.
Герметичный бокс для электронной начинки.

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

Начало сборки новой конфигурации катера.
Начало сборки новой конфигурации катера.

Трудно не заметить - на катере появилась камера на мачте. Этому есть объяснение: чем выше точка обзора, тем раньше мы сможем увидеть препятствие, а значит у нас будет больше времени для принятия решения. Другими словами - мы отодвигаем границу "видимого горизонта".

Картинка из Википедии.
Картинка из Википедии.

После сборки получаем новую компоновку:

Катер с новой компоновкой.
Катер с новой компоновкой.

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

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

Сравните размеры штатного водозаборника и нового пластикового.
Сравните размеры штатного водозаборника и нового пластикового.

Программная часть - самое простое! ...или нет?

Уже потираю руки - аппаратура надежно защищена, алгоритм давно придуман и проверен!

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

Слева - было, справа - стало.
Слева - было, справа - стало.

Включаем, понеслось...

Это просто ад какой-то!

Абсолютно неожиданно: в воде, в хорошую погоду, могут отражаться облака, деревья или любые другие объекты над водой. А еще, алгоритм поиска граней неплохо обнаруживает рябь и волны на поверхности. Все это накладывается друг на друга и превращается в одно хаотичное пятно. Алгоритм адаптивный, при увеличении числа помех я понижаю порог чувствительности и катер просто перестает видеть материальные препятствия на пути.

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

Вывод: ничего не получилось! ...или нет?

Я продел немалую работу: спроектировал и собрал техничку, провел тюнинг игрушечного катера, допилил ПО и все для того, чтобы столкнуться с фундаментальной проблемой - отражения на воде.

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

Так я видел работу автопилота изначально.
Так я видел работу автопилота изначально.

Ну не получилось и не получилось, не может отличить и что ж теперь? В лепешку расшибиться?! Зато я весело провел время!

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

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

С чистого листа.

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

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

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

Во время изысканий, настоящим откровением стал "фильтр Собеля". Метод находит градиент каждого пикселя (или заданной области пикселей). Причем направление градиента можно выбирать. Нашел я его во время опытов и только потом узнал, что он используется как простейший метод нахождения края объекта.

Пример фильтра Собеля из Википедии
Пример фильтра Собеля из Википедии

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

Сравнение старого и нового метода обнаружения препятствий:

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

Canny Edges слева, Sobel справа
Canny Edges слева, Sobel справа

А как на практике?

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

Погонял автопилот на других видео и убедился, что алгоритм отлично справляется с нашей задачей.

"Пока суть да дело - лето пролетело."

Лезть в холодную р.Волгу уже не так охота как при +30°, а значит снова придется ждать лета! Остается надеяться, что сюрпризов больше не будет и я смогу представить вам полный обзор самостоятельного путешествия катера с автопилотом и компьютерным зрением на Raspberry Pi.

Спасибо, что прочитали статью!

Tags:
Hubs:
+22
Comments 29
Comments Comments 29

Articles