Pull to refresh

Comments 71

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

По сути, у нас два пути — пытаться выделить объект в Lightness канале или в Hue. Второй даст неплохой эффект для пакетов и всякого яркого мусора. А вот с зеленоватыми корягами непонятно что делать.

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

Наверное эта проблема может быть решена в купе с использованием мини эхолота.

Думал об этом, но увидит ли эхолот пакет на поверхности воды? На данном этапе актуально обнаружить видимые глазу препятствия. Скрытые препятствия это уже отдельная тема.

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

"Островок" растительности хорошо различим визуально, по опыту испытаний могу сказать.

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

UFO just landed and posted this here

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

UFO just landed and posted this here

Спасибо! Изучу сей девайс.

Полтора вата, но цена 100$ - для таких проектов дороговато.

UFO just landed and posted this here

RaspberryPi 4 model B брал за 40$ на али. Но это было до ванханалии с ценами.

UFO just landed and posted this here

Нет, не заоблачно.

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

Я даже думал вторую малинку воткнуть при необходимости.

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

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

Отдельно спасибо за ваш развернутый комментарий на мою первую статью!

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

В итоге, камера в видимом спектре и камера в ИК, которая дёргает кадры с низким фреймрейтом синхронно со вспышками прожектора. Это даст экономию энергии.

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

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

А может быть над катером будет летать дрон. Он будет лучше видеть панораму. Разведчик.

Конечно, крупные препятствия он увидит раньше. Но сразу снижается автономность, отказоустойчивость всего комплекса в сумме, чувствительность к погодным условиям(дождь, ветер)...

На катер можно поставить солнечные панели, с квадракоптером это проблема.

Катер может отплывать на значительные расстояния: десятки километров. Квадрокоптер привязан к оператору и дальности приёма сигнала.

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

Детектирование оптического потока происходит (условно) при опоре частотного фильтра (детектора контуров и пятен) на несколько кадров или точек обзора (чтобы было понятно, куда сместилась граница). Цвета-оттенки там не особо нужны, навигационные алгоритмы человеков и роботов опираются на более абстрактные статистические характеристики движущейся картинки (что-то типа "движение плотности энтропии"). В общем, задачу нужно решать (гуглить) где-то вокруг этого словосочетания - Оптический Поток :).

Я больше со статикой работал)

Да, то что надо! Интересно, что я интуитивно решал эту же задачу по нахождению оптического потока :)

Гауссовское размытие и весовые коэффициенты у меня как раз используются!

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

Тогда подскажу ещё одно словосочетание, которое, возможно, пригодится - Фильтр Калмана (хотя велика вероятность, что словосочетание и без меня известное :)). Я сварщик ненастоящий, моделек с компьютерным зрением сам не строил, но навскидку кажется, что при использовании в управляющей цепи этого фильтра с соответствующими параметрами можно будет даже выбросить этап стабилизации картинки (вся раскачка входных данных усреднится этим фильтром).

Очень интересно. А говорите ненастоящий сварщик. :) Возможно, быстрее меня бы построили. Я только открываю для себя все эти алгоритмы.

Оказывается есть такой интересный инструментарий, неужели никто не реализовывал их на практике(в области компьютерного зрения: обнаружения и трекинга)? Или просто не публиковали результаты?

Большое спасибо!

Ещё раз перечитал комментарии. :)

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

Тогда тут уже надо с параллаксом играться. Сложно.

Да, нужно считать с учетом перспективы. Я это уже делал. Все что смог вытянуть - угол смещения объекта. В принципе с одной камерой больше не получится, как ни старайся.

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


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


P.S. Если решите экспериментировать со стерео — учтите, что камеры должны поддерживать синхронную съёмку.

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

На практике, погрешности просто дикие. При разрешении 640x480, чем ближе к линии горизонта, тем больше метров(десятков и даже сотен метров) на пиксель.

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

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


На практике, погрешности просто дикие. При разрешении 640x480, чем ближе к линии горизонта, тем больше метров(десятков и даже сотен метров) на пиксель.

Величина погрешности пропорциональна расстоянию, да. А на более близких препятствиях приемлемой точности не выйдет?

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

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

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

Интересно...

А что будет быстрее увеличиваться: большое препятствие или малое?

Например, спичечный коробок или огромный лайнер. Как можно посчитать скорость сближения? Для простоты примем нашу скорость за 0. Пусть препятствие на нас движется. Вот этот момент меня смущает. Мы же не знаем размер объекта на горизонте. Почему он увеличивается на экране быстрее: он крупный или быстрый?

Линейное наращивание размеров проекции будет одинаковым у препятствий любых размеров (потренируйтесь на листике в клеточку). Но, в целом, все эти промежуточные рассчёты не нужны, предлагаю просто разделить экран на чувствительные зоны на манер парктроника, только вместо писка при пересечении оптическим потоком этих линий вертеть рулём.

Типо головка самонаведения, только отведения в этом случае.

Я как раз упражнялся с этим. У меня другие результаты получались с размерами. Представьте плывущую баржу и бутылку рядом с ней. На горизонте баржа будет в виде пикселя 1x1, бутылку не видно ещё: 0x0

Теперь мы сблизились с ними максимально, скорость по отношению к ним у нас одна и та же. Баржа занимает весь экран: 640x480, бутылка пусть например: 4x5

Размер в проекции экрана нарастал нелинейно, или я вас неправильно понял?

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

И ещё было упражнение у меня такое. Разместил камеру на высоте корпуса катера, а перед ней рулетку растянул и сделал фото. И результат был, что-то вроде такого: первые 50-60 см хорошо укладываются в пиксели, 1-1,5 м ещё туда-сюда, все что свыше уже сливается в одну линию на экране.

Гуглится что-то подобное:

https://razbotics.wordpress.com/2019/12/17/optical-flow-based-navigation-using-picam/amp/

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

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

Мне нравится с вами дискутировать, вижу, что здорово разбираетесь в вопросе.

Вы стремитесь решить задачу восстановления 3Д-сцены перед катером по картинке с одной камеры в общем виде, это серьёзная задача, но она для управления катером, кажется, не требуется. Кажется, достаточно просто разметить в картинке с камеры "на воде" пару зон, появление объектов в которых (не важно, на каком расстоянии от камеры, главное, что они попали в проекцию) будет вызывать отклонение руля в противоположную сторону. Если же вы хотите, чтобы автопилот принимал более серьёзные решения (например, по изображению заранее планировал маршруты объезда препятстви, восстанавливал курс после объезда, следовал за объектами и т.д.), то, наверное, придётся лезть в нервосетки. Вот к примеру: https://github.com/gengshan-y/expansion . Но тут уже возникнет другой вопрос - как обработать эти полученные 3Д-данные, как превратить их таки в управляющие (и, вероятно, вы поверх всей этой так сложно восстановленной 3Д-сцены проведёте те самые пару полосок, и получите ту же самую схему "парктроника").

Тут сложно уже на словах прикинуть, какая схема сработает и насколько хорошо, надо пробовать, экспериментировать, подтюнивать и подшаманивать. И прочувствовать боль Илона Маска с его Теслой, который не за один год прошёл путь от лидаров до "голых" камер в своём автопилоте, и не одну тыщу километров накатал для обучения всего этого :).

Честно говоря, именно это я пытался сделать изначально: построить 3д сцену. Искал характеристики камеры, вводил near, far, FOV...

Все что смог посчитать: угол. Понял, что с одной камерой больше не получится ничего сделать. Хотя мне очень, очень хотелось узнать расстояние и скорость объекта на экране.

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

Вообще, ваша аналогия с парктроником очень точная.

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

Безумно интересно узнать о дальнейших развития этого проекта.

Спасибо вам за поддержку. Мне самому интересно посмотреть к чему это приведет, потому как времени потрачено немало и бросать это уже неспортивно.

Спасибо. Нормальная такая статья. Тоже обратите внимание, с чб изображением работают.

Само по себе определение препятствий у меня уже работает. Отдельно был вопрос оптимизации, алгоритм должен быть шустрым.

Тоже читал разные статьи. Вот по определению линии горизонта только 3-4 солидных таких же видел. На практике они не сработали. При одном ракурсе камеры есть горизонт, на другом уже не видит.

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

Все верно, именно так и будет.

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

UFO just landed and posted this here

Спасибо за поддержку! :)

Вас интересует код детектирования препятствий, стабилизации видео или как происходит трекинг обнаруженных объектов?

Все это часть одного проекта беспилотного катера. Код планирую публиковать когда проведу испытания на "открытой воде" и буду уверен, что все работает как надо.

UFO just landed and posted this here

Про производительность:

Какое расширение видео использовали?

Какую модель Raspberry pi?

Если собирали библиотеку сами, то можно было при сборке включить использование openMP — библиотеку распараллеливания.

Попробуйте написать на C++. Там использование функций и классов openCV почти такое же, но есть возможность скомпилировать с максимальной оптимизацией.

Видео у меня пока - это фрагменты записи с GoPro в формате mp4

Малинка: Raspberry Pi 4 Model B с 4 Гб

За подсказки благодарю! :)

UFO just landed and posted this here

Благодарю! Не думал, что такая специфичная область заинтересует столько людей. Хотя вот меня затянула чуть больше чем полностью. :)

Если интересно, именно по запуску катера, можете посмотреть мой же видео отчет: https://m.youtube.com/watch?v=5ZUPO3FEQQ0

Это не реклама, канал без монетизации, чисто любительский. В конце видео есть подбивка: около 300$ весь проект. При том, что вы можете снять Raspberry Pi и у вас снова будет та же самая игрушка из магазина.

Тоже были сомнения, получится ли детектировать препятствия. Но... пока получается. :) Raspberry Pi 4 достаточно мощный девайс, а библиотека OpenCV неплохо оптимизирована.

Но в любом случае, или все получится, или провалится. И я напишу по какой причине не получилось. :)

UFO just landed and posted this here

Солидарен с вами, читать удобнее. Так уж получилось, что сначала это была просто rc игрушка, потом подключил raspberry только из любопытства: разобраться с управлением. Камеру поставил, опять же из любопытства, посмотреть "глазами" капитана этого судна. :) дальше решил научиться монтировать видео, чтобы оставить его себе на память.

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

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

Советами не пренебрегаю, за все идеи читателям благодарен! Значит не зря писал. А все комментарии мотивируют довести дело до конца, появилась ответственность перед вами.

Есть подозрение что ИИ не нужен. Ведь задача обходить ВСЕ препятствия, а не определить какие из них опасные.
По идее достаточно отделить «шум» на поверхности воды и трекать его.
Интересно как в итоге вы решите задачу.

Вы все верно поняли.

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

В список задач нужно еще один пункт добавить, коррекцию сферических искажений. а то горизонт дугой изгибается, рано или поздно этот фактор начнет критически влияеть на результат.
Вот попалась статья, наглядно показывает о чем речь.
https://habr.com/ru/post/341160/

Это видео с GoPro. Она в широком формате даёт эффект "рыбьего глаза". Пока не уверен мешает он мне или можно пренебречь. Скоро узнаем, надеюсь!

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

Для всего что ниже горизонта можно сделать нормализацию. Возможно нелинейную.

Определение мусора. Пробегаемся граф-сегментатором. Например таким

https://www.cc.gatech.edu/cpl/projects/videosegmentation/

Граф-сегментаторы очень хорошо реагируют на трешхолд.

Пробуем определить вектор движения сегмента и его размер. Или используем более сложные ии классификаторы.

Что бы не гонять классификатор на каждом фрейме используем оптимизацию на подобее описаной в моем патенте https://patents.google.com/patent/US9002056B2 но с учётом того что мы движемся в 3D пространстве.

Если не хватает производительности, смело уменьшайте разрешение для тяжёлых участков. Вплоть до 320х240. На такой скорости фреймрейт важне.

Спасибо. Дайте время изучить.

Пока могу сказать по предварительным результатам:

1. фрейм рейт действительно важен

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

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

Спасибо за идею!

В первой версии будет стоять самая обычная камера для raspberry pi:

Не совсем понял как за объективом поставить? Или с такой не получится?

Фильтр между объективом и матрицей.

Поковыряйте.. )

А, понял. Фильтр уже стоит, его надо снять. Камеру жалко скальпировать, она у меня одна :/ а руки - крюки...

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

Ещё, кстати, забыл написать про возможность использовать стерео пару ( 2 камеры сразу) Она может дать глубину всей сцены. Видел, правда, примеры, выглядели они, мягко говоря, убого. Вряд ли получится точно определять расстояние до объекта.

UFO just landed and posted this here

Там же радиус действия единицами метров измеряется.

По умолчанию ближний ИК фильтруется. Если убрать hot mirror, то можно ловить этот спектр.

А не могли бы вы поделиться исходниками к данной статье?!

Код на python для "посвечивания" объектов:

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 100, 300)
dilated = cv2.dilate(edges, np.ones((2, 2), 'uint8'), iterations=2)
contours, hierarchy = cv2.findContours(dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

for cnt in contours:
    cv2.drawContours(frame, [cnt], -1, (0, 255, 0), 1)

frame это картинка, которая может быть текущим фреймом вашего видео или просто статичной картинкой

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

Sign up to leave a comment.

Articles