Автономное Вождение По Тротуару С Использованием Opencv И Tensorflow

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

Самый старый и самый известный курс был онлайн-диплом от Udacity .

Так, в автономных автомобилях существует очень модный подход — Behavioral Cloning, суть которого в том, что компьютер учится вести себя как человек (вождение), опираясь только на записанные входные и выходные данные.

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

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

Этот подход основан на статья от Нвидиа .

Существует множество реализаций, выполненных в основном студентами Udacity:

Еще интереснее применение в реальных проектах.

Например, пишущая машинка Осел Автомобиль управляется специально обученным нейронная сеть .

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

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

Осталось только научить танк ездить по тротуару в парке.

Так что же такое тротуар с точки зрения компьютера? Какая-то область на изображении отличается по цвету от других областей.

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

(Под самым серым мы подразумеваем наименьшую разницу между значениями RGB.) Это свойство серого будет ключевым при распознавании тротуара.

Еще один важный параметр серого — яркость.

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



Автономное вождение по тротуару с использованием OpenCV и Tensorflow

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

  • возьмите среднюю яркость (в формате HSV)
  • или среднее значение RGB фрагмента, гарантированно состоящего из дороги (в этом случае это будет левый нижний угол).

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



Автономное вождение по тротуару с использованием OpenCV и Tensorflow

Следующий шаг — привести неуклюжее место в действие — идите прямо или поверните направо или налево.

Едем прямо, если виден правый край и угол меньше 45 градусов от вертикали.

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

Поворачиваем направо, если не видим правого края.

Правый край корявого пятна — решение этой задачи с помощью геометрии довольно неудачное.

Лучше пусть искусственный интеллект ищет закономерности в этих обрывках.

Здесь на помощь приходят нейронные сети.

Размываем исходные изображения, сжимаем и обрезаем их, выделяем серый тротуар и получаем черно-белые маски размером 64x64. Раскладываем эти маски в 3 стопки — Левую, Правую, Прямую и обучаем на них классификатор нейросети.

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

Вот образцы масок: Левый:

Автономное вождение по тротуару с использованием OpenCV и Tensorflow

Верно:

Автономное вождение по тротуару с использованием OpenCV и Tensorflow

Напрямую:

Автономное вождение по тротуару с использованием OpenCV и Tensorflow

Для работы с нейросетью я использовал Keras + Tensorflow. Сначала была идея взять структуру нейросети от Nvidia, но, очевидно, она предназначена для несколько других задач и плохо справляется с классификацией.

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

   

model = Sequential() activation = "relu" model.add(Conv2D(20, 5, padding="same", input_shape=input_shape)) model.add(Activation(activation)) model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2))) model.add(Conv2D(50, 5, padding="same")) model.add(Activation(activation)) model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2))) model.add(Flatten()) model.add(Dense(500)) model.add(Activation(activation)) model.add(Dense(cls_n)) opt = SGD(lr=0.01) model.add(Activation("softmax")) model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"])

Обучив первую версию сети, я столкнулся с ее несовместимостью с Raspberry Pi. До этого я использовал Tensorflow версии 1.1, собранный шаманством.

один очень умный человек .

К сожалению, эта версия устарела и не могла читать модели из Кераса.

Однако недавно люди из Google наконец соизволили и собрали TF для Raspberry Pi, правда, для новой версии Raspbian — Stretch. Stretch был хорош для всех, но год назад я не смог получить для него OpenCV, поэтому танк запускал Jessie. Теперь, под давлением перемен, мне пришлось переключиться на Stretch. Tensorflow установился без проблем (хотя и заняло несколько часов).

OpenCV тоже не стоял на месте уже год и уже вышла версия 4.0. Так что нам удалось собрать его для Stretch, поэтому препятствий для миграции больше не было.

Были сомнения, как Raspberry справится с таким монстром, как Tensorflow, в реальном времени, но все оказалось в целом приемлемо — несмотря на начальную загрузку сети около нескольких секунд, сама классификация способна запускаться несколько раз в секунду без значительных потребление памяти и процессора.

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

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

С обновленной прошивкой танк прорезает парк.

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



Автономное вождение по тротуару с использованием OpenCV и Tensorflow

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

Ссылки:

Теги: #Машинное обучение #роботы #Raspberry Pi #Разработка Raspberry Pi #Робототехника #искусственный интеллект #Обработка изображений #OpenCV #компьютерное зрение #TensorFlow
Вместе с данным постом часто просматривают: