Pull to refresh

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

Reading time 3 min
Views 9.6K

Введение

Моя первая статья на Хабре, не судите строго, надеюсь содержание будет как минимум интересным!

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

Не так давно, ко мне в руки, попала модель радиоуправляемого катера Avanti от производителя Thunder Tiger, сердцем которого является мощный бесколлекторный двигатель Ripper OBL 29/19 с водяным охлаждением. Производитель обещает скорость до 60 км/ч! Быстро наигравшись, как в далеком детстве, полез смотреть на начинку игрушки.

Thunder Tiger Avanti
Thunder Tiger Avanti

Устройство предельно простое для любого, кто сталкивался с RC моделями:

  • трансивер на 2,4 ГГц

  • блок управления двигателем (регулятор оборотов)

  • сервомашинка для управления рулем

  • отсек для LiPo аккумулятора

Первое, что пришло в голову: подключить вместо трансивера - микрокомпьютер Raspberry Pi. Пусть катер получит зачатки интеллекта и самостоятельно отправится в плавание!

Вот что получилось. Хорошо, что Raspberry Pi не занимает много места.
Вот что получилось. Хорошо, что Raspberry Pi не занимает много места.

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

Все получилось, если бы не...

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

В робототехнике часто используют ультразвуковые датчики сближения (в более продвинутых системах - LiDAR). А как быть если препятствие находится прямо в воде и не может быть обнаружено сонаром?

Многие видели, как алгоритмы компьютерного зрения определяют и классифицируют визуальные объекты в реальном времени. Для этого нужны значительные по объему базы данных классификаторов и немалая производительность. А что если мы заранее не знаем, что встретим на своем пути? Если объект будет произвольной формы, цвета и размера?

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

Робото-мировозрение

Для Raspberry Pi существует отличная библиотека OpenCV с огромным набором функций. Мне казалось, что должно существовать готовое решения обнаружения абстрактного препятствия и сопровождение его в реальном времени. И вроде времени я потратил немало, но готовых решений не нашел. Значит будем решать задачу самостоятельно. За образец я взял видео с GoPro установленной на катере во время тестового заплыва по координатам. Не забывайте, на тот момент дрон был еще "незрячий".

Для определения препятствий уместно использовать алгоритм edges, предварительно убрав цветность.

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 100, 300)
Вот так алгоритм детектирует палку на воде
Вот так алгоритм детектирует палку на воде
А вот небольшие пучки водорослей
А вот небольшие пучки водорослей

Теперь сведем полученный результат и исходное изображение.

Уже хорошо, но нужно определить вектор движения и границы "опасных" объектов, чтобы отдавать команды на руль беспилотника.

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

Вроде уже все здорово и можно доработать скрипт управления судном, если бы не одно жирное НО: такие идеальные условия бывают очень редко. За все время запусков такое случились только один раз.

А вот как выглядит обычный выход на воду:

Этот "шалтай-балтай" совсем не похож на эталонный заплыв "в ванной"...

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

Что дальше...

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

  • Стабилизация изображения

  • Обнаружение абстрактных препятствий

  • "Трекинг" обнаруженных препятствий

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

Tags:
Hubs:
+42
Comments 71
Comments Comments 71

Articles