Как сделать беспилотного робота с Raspberry Pi, компьютерным зрением и сверточной нейронной сетью.

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

Идея реализации была дана поведенческим клонированием. Это очень популярный подход для беспилотных транспортных средств, когда ИИ учится на предоставленных поведенческих входных и выходных данных, а затем принимает решения по новым входным данным. Есть статья от Nvidia, где они представили этот метод.

Эта идея описывается во многих хороших статьях:

  • "Один"
  • "Два"
  • "Три"

Еще более захватывающие реализации есть в реальной жизни. Лучший пример - DonkeyCar и его нейронная сеть.

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

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

Эта задача оказалась непростой. Фотографии в основном были серыми, и главный вопрос был в том, «какой серый цвет для дорожки». Наблюдения показали, что дорожка была похожа на «идеальный серый» - с минимальной разницей между ее значениями RGB.

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

Форма контура не была точной и зависела от параметров цветовой фильтрации.

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

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

Примеры левой, правой и прямой масок:

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

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.

Я использовал Raspbian 8 Jessie со старым Tensorflow, созданным Sam Abrahams и OpenCV 3.4 (мне пришлось собрать его самостоятельно). Эта версия Tensorflow была довольно старой и не могла работать с моделями Keras.

К счастью, недавно Google поддержал Raspberry Pi для Tensorflow, но для этого требуется Raspbian 9 Stretch и python 3. Поэтому мне пришлось перенести все прошивки роботов на новую платформу. OpenCV также развивался в течение того года, и мне пришлось собрать OpenCV 4.0.

Сложите все вместе - робот гуляет по парку.

Заключение

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

Ссылки

Репозиторий GitHub с полной прошивкой танка на python

Данные и код для нейронной сети

Предварительно созданные пакеты deb OpenCV для Raspbian

Инструкция по сборке цистерны

Подробнее о танке