Часть 3. Попытка заставить его ехать
Предыдущие посты из этой серии можно найти здесь.
Предварительная обработка изображений с использованием OpenCV
Я был немного разочарован — другие блоги, которые я читал, казались почти готовыми к работе. По общему признанию, у меня есть еще немного пользовательского кода, но я подумал, что он должен работать лучше.
После некоторых проверок гистограмм движения:
Казалось, все в порядке, поэтому моей следующей мыслью было то, что в других видео люди имеют большие комнаты и более чистые дороги. Моя дорога была малярной лентой на отражающем деревянном полу и в маленьком пространстве с большим количеством мебели. Возможно, модель путалась, и поэтому я подумал, что некоторая предварительная обработка изображения поможет.
Изображения HSV и обнаружение краев
Пространства Hue, Saturation, Value полезны для извлечения определенных цветов. В моем случае мне нужны белые линии краев дороги. OpenCV предоставляет для этого много полезных функций, но проблема заключалась в том, что в моей настройке иногда края дороги были слишком темными. Вот набор изображений, где я сначала преобразовал в цветовое пространство HSV, извлек «белый», размыл его и замаскировал, чтобы сделать края ярче.
К сожалению, он не улавливает правый край, но обнаружение края будет. Здесь я использовал детектор краев Canny, а затем нашел контуры и попытался заполнить любые меньшие пробелы, прежде чем ограничить интересующую область дорогой ближе к машине:
Поиск переулка
Мы можем немного поразвлечься и попытаться найти плоскую область, которая является фактической дорожкой. Сначала мы удаляем перспективу, проецируя изображение с помощью функций getPerspectiveTransform и warpPerspective.
Если наши края дороги достаточно сильные, мы можем использовать гистограмму интенсивности изображения вдоль оси x рядом с автомобилем, чтобы найти начальные точки для каждого края. Затем, исследуя прямоугольники и перемещаясь вверх по изображению, мы можем следить за краями и в каждой «строке» сохранять центральные точки краев. Кривая затем может быть подогнана к каждому и заполнена.
Получив их, мы можем взять обратную перспективу и наложить полосу на исходное изображение. Это работает достаточно хорошо некоторое время, но хрупко в этой среде.
Учитывая крутые повороты, это может эффектно провалиться!
Обучение с предварительно обработанными изображениями
Первоначально я думал, что могу использовать поиск полосы движения, чтобы «раскрасить» реальную дорогу и, следовательно, получить гораздо более сильные функции для машинного обучения, но это было недостаточно последовательно, поэтому я отказался от этого, но сохранил обработку изображения. Я пропустил все записанные изображения через конвейер предварительной обработки и сохранил их для обучения, что привело к гораздо меньшим потерям.
Ошибки
Но машина все равно не едет! Именно тогда я начал думать, что что-то еще не так, и приступил к отладке кода DonkeyCar. Изучив тайминги цикла вождения, я обнаружил, что цикл логического вывода занимает около 200 мс, что просто недостаточно для того, чтобы автомобиль мог двигаться сам по себе. После вопроса на дискурс-канале DonkeyCar выяснилось, что возникла проблема https://github.com/autorope/donkeycar/pull/861.
Применение этих изменений сократило цикл логического вывода до 25–30 мс, и машина смогла двигаться самостоятельно!
В следующий раз
В следующей статье я представлю более крупную и быструю машину, у которой есть свои проблемы! Мы будем использовать TensorFlow Lite, режим максимальной производительности, RC-контроллеры, и в итоге у нас будет автомобиль, который выезжает на улицу.