Обнаружение изогнутой полосы
История
Введение
В любом сценарии движения полосы движения являются важным компонентом, указывающим транспортный поток и направление движения транспортного средства. Это также хорошая отправная точка при разработке беспилотного автомобиля! Основываясь на моем предыдущем проекте по обнаружению полос движения, я внедрил систему обнаружения изогнутых полос, которая работает намного лучше и более надежна в сложных условиях.
Система обнаружения полос была написана на Python с использованием библиотеки OpenCV. Вот текущий конвейер обработки изображений:
- Коррекция искажений
- Искажение перспективы
- Фильтрация Собеля
- Обнаружение пика гистограммы
- Поиск в скользящем окне
- Аппроксимация кривой
- Переулок, обнаруженный наложением
- Применить к видео
Ограничения предыдущей системы
В моем предыдущем проекте по обнаружению полос я разработал очень простую систему обнаружения полос, которая могла обнаруживать прямые полосы на изображении. Он работал прилично в идеальных условиях, однако не мог точно определять изогнутые полосы и не был устойчив к препятствиям и теням. В этой версии улучшены оба этих ограничения.
Коррекция искажений
Линзы камеры искажают падающий свет, чтобы сфокусировать его на датчике камеры. Хотя это очень полезно, позволяя нам делать снимки окружающей нас среды, они часто в конечном итоге искажают свет немного неточно. Это может привести к неточным измерениям в приложениях компьютерного зрения. Однако мы можем легко исправить это искажение.
Как бы вы это сделали? Вы можете откалибровать свое изображение по известному объекту и создать модель искажения, которая учитывает искажения объектива.
Этот объект часто представляет собой асимметричную шахматную доску, подобную показанной ниже:
Калибровочная шахматная доска (OpenCV Docs)
Камера, использованная в тестовом видео, использовалась, чтобы сделать 20 снимков шахматной доски, которые использовались для создания модели искажения. Мы начинаем с преобразования изображения в оттенки серого, а затем применяем функцию cv2.findChessboardCorners (). Мы уже знаем, что эта шахматная доска представляет собой двухмерный объект с исключительно прямыми линиями, поэтому мы можем применить некоторые преобразования к обнаруженным углам, чтобы правильно выровнять их. Я использовал cv2.CalibrateCamera (), чтобы получить коэффициенты искажения и матрицу камеры. Камера откалибрована!
Затем вы можете использовать cv2.undistort () для исправления остальных ваших входных данных. Вы можете увидеть разницу между исходным изображением шахматной доски и исправленным изображением ниже:
Исправление искажений, примененное к изображению, содержащему калибровочную шахматную доску.
Вот точный код, который я использовал для этого:
def undistort_img ():
# Подготовить точки объекта 0,0,0… 8,5,0
obj_pts =np.zeros ((6 * 9,3), np.float32)
obj_pts [:,:2] =np.mgrid [0:9, 0:6] .T.reshape (-1,2)
# Сохраняет все точки объекта и точки img со всех изображений
objpoints =[]
imgpoints =[]
# Получить каталог для всех калибровочных изображений
images =glob.glob ('camera_cal / *. jpg')
для indx, fname in enumerate (изображения):
img =cv2.imread (fname)
gray =cv2.cvtColor (img, cv2.COLOR_BGR2GRAY)
ret, corners =cv2.findChessboardCorners (серый, (9,6 ), None)
if ret ==True:
objpoints.append (obj_pts)
imgpoints.append (corners)
# Проверить отсутствие искажений на img
img_size =( img.shape [1], img.shape [0])
# Калибровка камеры
ret, mtx, dist, rvecs, tvecs =cv2.calibrateCamera (objpoints, imgpoints, img_size, None, None)
dst =cv2.undistort (img, mtx, dist, None, mtx)
# Сохранить калибровку камеры для дальнейшего использования
dist_pickle ={}
dist_pickle ['mtx'] =mtx
dist_pickle ['расстояние' ] =dist
pickle.dump (dist_pickle, open ('camera_cal / cal_pickle.p', 'wb'))
def undistort (img, cal_dir ='camera_cal / cal_pickle.p'):
#cv2.imwrite('camera_cal/test_cal.jpg ', dst)
с open (cal_dir, mode =' rb ') как f:
file =pickle.load (f) mtx =file ['mtx']
dist =file ['dist']
dst =cv2.undistort (img, mtx, dist, None, mtx)
return dst
undistort_img ()
img =cv2.imread ('camera_cal / Calibration1.jpg')
dst =undistort (img) # Неискаженное изображение
Используемые для них функции также можно найти в Блокноте Jupyter в разделе Код . раздел.
Вот коррекция искажения, примененная к изображению дороги. Возможно, вы не заметите небольшую разницу, но она может оказать огромное влияние на обработку изображений.
Коррекция искажений, примененная к сцене вождения
Искажение перспективы
Обнаружить изогнутые полосы в пространстве камеры не очень просто. Что, если бы мы могли увидеть переулки с высоты птичьего полета? Это можно сделать, применив к изображению перспективное преобразование. Вот как это выглядит:
Искаженное изображение в перспективе
Заметили что-нибудь? Предполагая, что полоса дороги расположена на плоской 2D-поверхности, мы можем подобрать полином, который может точно представить полосу движения в пространстве полосы движения! Разве это не круто?
Вы можете применить эти преобразования к любому изображению, используя функцию cv2.getPerspectiveTransform (), чтобы получить матрицу преобразования, и cv2.warpPerspective (), чтобы применить ее к изображению. Вот код, который я использовал для этого:
def перспектива_вара (img,
dst_size =(1280,720),
src =np.float32 ([(0.43,0.65), (0.58,0.65), (0.1,1), (1,1 )]),
dst =np.float32 ([(0,0), (1, 0), (0,1), (1,1)])):
img_size =np. float32 ([(img.shape [1], img.shape [0])])
src =src * img_size
# Для точек назначения я произвольно выбираю некоторые точки, которые будут
# хорошо подходит для отображения нашего искаженного результата
# опять же, не точно, но достаточно близко для наших целей
dst =dst * np.float32 (dst_size)
# Указанные src и dst точки , вычислить матрицу преобразования перспективы
M =cv2.getPerspectiveTransform (src, dst)
# Деформировать изображение с помощью OpenCV warpPerspective ()
warped =cv2.warpPerspective (img, M, dst_size)
возврат деформирован
Фильтрация Собеля
В предыдущей версии я отфильтровал линии полос с помощью цвета. Однако это не всегда лучший вариант. Если вместо асфальта используется светлый бетон, дорога легко проходит через цветной фильтр, и трубопровод воспринимает ее как белую полосу движения. Не очень хорошо.
Вместо этого мы можем использовать метод, аналогичный нашему детектору края, на этот раз для фильтрации дороги. Линии полосы движения обычно сильно контрастируют с дорогой, поэтому мы можем использовать это в своих интересах. Canny детектор кромок, ранее использовавшийся в версии 1, использует Оператор Собеля чтобы получить градиент функции изображения. В документации OpenCV есть фантастическое объяснение того, как это работает. Мы будем использовать это, чтобы обнаруживать области с высокой контрастностью, фильтровать разметку полос и игнорировать дорогу.
Мы по-прежнему будем использовать HLS Colorspace снова, на этот раз для обнаружения изменений в насыщенности и яркости. К этим двум каналам применяются операторы Собела, и мы извлекаем градиент по оси x и добавляем пиксели, которые проходят наш порог градиента, в двоичную матрицу, представляющую пиксели в нашем изображении. Вот как это выглядит в пространстве камеры и полосы движения:
Обратите внимание, что части изображения, находящиеся дальше от камеры, не очень хорошо сохраняют свое качество. Из-за ограничений разрешения камеры данные от удаленных объектов сильно размыты и зашумлены. Нам не нужно сосредотачиваться на всем изображении, поэтому мы можем просто использовать его часть. Вот как будет выглядеть изображение, которое мы будем использовать:
Обнаружение пика гистограммы
Мы будем применять специальный алгоритм под названием Скольжение Окно Алгоритм чтобы обнаружить наши полосы движения. Однако, прежде чем мы сможем применить его, нам нужно определить хорошую отправную точку для алгоритма. Он работает хорошо, если он начинается в месте, где присутствуют пиксели полосы движения, но как мы можем определить местоположение этих пикселей полосы движения в первую очередь? На самом деле это действительно просто!
Мы получим гистограмму изображения относительно оси X. Каждая часть гистограммы ниже показывает, сколько белых пикселей находится в каждом столбце изображения. Затем мы берем самые высокие пики с каждой стороны изображения, по одному для каждой линии полосы движения. Вот как выглядит гистограмма рядом с двоичным изображением:
Поиск в скользящем окне
Алгоритм скользящего окна будет использоваться для различения левой и правой границ полосы движения, чтобы мы могли подогнать две разные кривые, представляющие границы полосы движения.
Подробнее:обнаружение изогнутых полос
Производственный процесс
- Схема ультразвукового обнаружения объектов на базе микроконтроллера 8051
- Базовая система обнаружения вторжений
- Фотоэлектрические датчики увеличивают расстояние обнаружения времени пролета
- Датчик ToF обеспечивает быстрое 3D-обнаружение
- Технология Lidar поддерживает обнаружение на большом расстоянии
- Система сигнализации обнаружения движения
- Ферма:робот для обнаружения болезней растений
- ОБНАРУЖЕНИЕ ЧЕЛОВЕКА РОБОТА SONBI С ИСПОЛЬЗОВАНИЕМ KINECT И МАЛИНЫ PI
- Блог:обнаружение генов с помощью микрочипа
- Технология фрезерования с ЧПУ для криволинейных поверхностей