В этом примере показано, как разработать приложение CUDA ® на основе модели Simulink ®, которое выполняет обнаружение полосы движения и транспортного средства с использованием сверточных нейронных сетей (CNN). В этом примере в качестве входных данных берутся кадры видео движения, выводятся две границы полосы движения, которые соответствуют левой и правой полосам движения эго-транспортного средства, и обнаруживаются транспортные средства в кадре. В этом примере используется предварительно обученная сеть обнаружения полосы из примера оптимизированного обнаружения полосы с кодером GPU Toolbox™ кодера GPU. Дополнительные сведения см. в разделе Определение полосы движения, оптимизированное с помощью кодера графического процессора. В этом примере также используется предварительно обученная сеть обнаружения транспортного средства из примера «Обнаружение объектов с помощью глубокого обучения YOLO v2» toolbox™ компьютерного зрения. Дополнительные сведения см. в разделе Обнаружение объектов с помощью глубокого обучения YOLO v2 (Computer Vision Toolbox).
Этот пример иллюстрирует следующие концепции:
Моделирование приложения обнаружения полосы движения в Simulink. Сначала видео трафика предварительно обрабатывается путем изменения размера до 227x227x3 и умножения на постоянный коэффициент 255. Впоследствии он обрабатывается предварительно подготовленной сетью, загруженной в Predict блок из Toolbox™ глубокого обучения. Наконец, если обнаруживаются левая и правая границы полосы, получают параболические коэффициенты для моделирования траекторий границ полосы.
Смоделировать приложение для обнаружения транспортного средства в Simulink. Видео трафика обрабатывается предварительно обученным детектором YOLO v2. Эта сеть обнаруживает транспортные средства в видео и выводит координаты ограничивающих прямоугольников для этих транспортных средств и их оценку достоверности.
Сконфигурируйте модель для создания кода.
Создайте исполняемый файл CUDA для модели Simulink.
Графический процессор NVIDIA с поддержкой CUDA.
Набор инструментов и драйвер NVIDIA CUDA.
Библиотека NVIDIA cuDNN.
Переменные среды для компиляторов и библиотек. Дополнительные сведения см. в разделах Аппаратное обеспечение сторонних производителей и Настройка необходимых продуктов.
Чтобы убедиться, что компиляторы и библиотеки, необходимые для выполнения этого примера, настроены правильно, используйте coder.checkGpuInstall функция.
envCfg = coder.gpuEnvConfig('host'); envCfg.DeepLibTarget = 'cudnn'; envCfg.DeepCodegen = 1; envCfg.Quiet = 1; coder.checkGpuInstall(envCfg);
Показана блок-схема алгоритмического рабочего процесса модели Simulink.

if ~exist('./caltech_washington1.avi', 'file') url = 'https://www.mathworks.com/supportfiles/gpucoder/media/caltech_washington1.avi'; websave('caltech_washington1.avi', url); end
Показана модель Simulink для выполнения обнаружения полосы движения и транспортного средства на видео движения. При запуске модели Video Viewer блок отображает видео движения с аннотациями полосы движения и транспортного средства.
open_system('laneAndVehicleDetection');

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

Здесь y - боковое смещение, а x - продольное расстояние от транспортного средства. Сеть выводит три параметра a, b и c для каждой полосы. Сетевая архитектура аналогична AlexNet за исключением того, что последние несколько слоев заменены меньшим полностью соединенным слоем и выходным слоем регрессии. LaneDetectionCoordinates Функциональный блок MATLAB определяет функцию lane_detection_coordinates который принимает выходные данные из блока прогнозирования и выводит три параметра, а именно: laneFound, ltPts и rtPts. Пороговое значение используется для определения наличия как левой, так и правой границ полосы движения. Если найдены оба, laneFound имеет значение true, и траектории границ вычисляются и сохраняются в ltPts и rtPts соответственно.
type lane_detection_coordinates
function [laneFound,ltPts,rtPts] = lane_detection_coordinates(laneNetOut)
% Copyright 2020 The MathWorks, Inc.
persistent laneCoeffMeans;
if isempty(laneCoeffMeans)
laneCoeffMeans = [-0.0002 0.0002 1.4740 -0.0002 0.0045 -1.3787];
end
persistent laneCoeffStds;
if isempty(laneCoeffStds)
laneCoeffStds = [0.0030 0.0766 0.6313 0.0026 0.0736 0.9846];
end
params = laneNetOut .* laneCoeffStds + laneCoeffMeans;
isRightLaneFound = abs(params(6)) > 0.5; %c should be more than 0.5 for it to be a right lane
isLeftLaneFound = abs(params(3)) > 0.5;
persistent vehicleXPoints;
if isempty(vehicleXPoints)
vehicleXPoints = 3:30; %meters, ahead of the sensor
end
ltPts = coder.nullcopy(zeros(28,2,'single'));
rtPts = coder.nullcopy(zeros(28,2,'single'));
if isRightLaneFound && isLeftLaneFound
rtBoundary = params(4:6);
rt_y = computeBoundaryModel(rtBoundary, vehicleXPoints);
ltBoundary = params(1:3);
lt_y = computeBoundaryModel(ltBoundary, vehicleXPoints);
% Visualize lane boundaries of the ego vehicle
tform = get_tformToImage;
% map vehicle to image coordinates
ltPts = tform.transformPointsInverse([vehicleXPoints', lt_y']);
rtPts = tform.transformPointsInverse([vehicleXPoints', rt_y']);
laneFound = true;
else
laneFound = false;
end
end
Сеть обнаружения объектов YOLO v2 состоит из двух подсетей: сети извлечения признаков, за которой следует сеть обнаружения. Эта предварительно обученная сеть использует ResNet-50 для извлечения элемента. Подсеть обнаружения является небольшим CNN по сравнению с сетью извлечения признаков и состоит из нескольких сверточных слоев и слоев, специфичных для YOLO v2. VehicleDetectionYOLOv2 Функциональный блок MATLAB определяет функцию vehicle_detection_yolo_v2 который загружает предварительно обученный детектор объекта YOLO v2. Эта сеть принимает изображение в качестве входных данных и выводит координаты ограничивающей рамки вместе с показателями достоверности для транспортных средств в изображении для последующей аннотации.
type vehicle_detection_yolo_v2
function [bboxes,scores] = vehicle_detection_yolo_v2(In)
% Copyright 2020 The MathWorks, Inc.
persistent yolodetector;
if isempty(yolodetector)
yolodetector = coder.loadDeepLearningNetwork('yolov2ResNet50VehicleExample.mat');
end
[bboxes,scores,~] = yolodetector.detect(In, 'threshold', .2);
end
LaneVehicleAnnotation Функциональный блок MATLAB определяет функцию lane_vehicle_annotation который аннотирует ограничивающие боксы транспортного средства вместе с показателями достоверности. Также, если laneFound true, то левая и правая границы полосы сохраняются в ltPts и rtPts аннотированы в видео трафика.
type lane_vehicle_annotation
function In = lane_vehicle_annotation(laneFound, ltPts, rtPts, bboxes, scores, In)
% Copyright 2020 The MathWorks, Inc.
if ~isempty(bboxes)
In = insertObjectAnnotation(In, 'rectangle', bboxes, scores);
end
pts = coder.nullcopy(zeros(28, 4, 'single'));
if laneFound
prevpt = [ltPts(1,1) ltPts(1,2)];
for k = 2:1:28
pts(k,1:4) = [prevpt ltPts(k,1) ltPts(k,2)];
prevpt = [ltPts(k,1) ltPts(k,2)];
end
In = insertShape(In, 'Line', pts, 'LineWidth', 2);
prevpt = [rtPts(1,1) rtPts(1,2)];
for k = 2:1:28
pts(k,1:4) = [prevpt rtPts(k,1) rtPts(k,2)];
prevpt = [rtPts(k,1) rtPts(k,2)];
end
In = insertShape(In, 'Line', pts, 'LineWidth', 2);
In = insertMarker(In, ltPts);
In = insertMarker(In, rtPts);
end
end
Функция загружает trainedLaneNet.mat и yolov2ResNet50VehicleExample.mat если они еще не присутствуют.
getVehicleDetectionAndLaneDetectionNetworks()
Downloading pretrained lane detection network (143 MB)... Downloading pretrained vehicle detection network (98 MB)...
Откройте диалоговое окно «Параметры конфигурации».
На панели «Цель моделирования» выберите ускорение графического процессора. В группе Глубокое обучение выберите целевую библиотеку как cuDNN.
set_param(bdroot,'GPUAcceleration','on'); set_param(bdroot,'SimDLTargetLibrary','cudnn'); set_param(bdroot,'DLTargetLibrary','cudnn');
Для проверки алгоритмов обнаружения полосы движения и транспортного средства, а также отображения траекторий полосы движения, ограничивающих коробок транспортных средств и оценок для видео движения, загруженного в модель Simulink, выполните моделирование.
set_param('laneAndVehicleDetection', 'SimulationMode', 'Normal'); sim('laneAndVehicleDetection');

На панели «Создание кода» выберите язык C++ и включите функцию «Генерировать код графического процессора».
set_param(bdroot,'TargetLang','C++'); set_param(bdroot,'GenerateGPUCode','CUDA');

В подкатегории «Библиотеки» панели «Создание кода» > «Код графического процессора» включите cuBLAS, cuSOLVER и cuFFT.
set_param(bdroot,'GPUcuBLAS','on'); set_param(bdroot,'GPUcuSOLVER','on'); set_param(bdroot,'GPUcuFFT','on');
Создание и построение модели Simulink на главном графическом процессоре с помощью slbuild команда. Генератор кода помещает файлы в папку построения, подпапку с именем laneAndVehicleDetection_ert_rtw в текущей рабочей папке.
status = evalc("slbuild('laneAndVehicleDetection')");
Вложенная папка с именем laneAndVehicleDetection_ert_rtw содержит сгенерированные коды C++, соответствующие различным блокам в модели Simulink и конкретным операциям, выполняемым в этих блоках. Например, файл trainedLaneNet0_laneAndVehicleDetection0.h содержит класс C++, который содержит атрибуты и функции-члены, представляющие предварительно обученную сеть обнаружения полосы движения.
Аналогично, файл yolov2ResNet50VehicleExample0_laneAndVehicleDetection0.h содержит класс C++, представляющий предварительно обученную сеть обнаружения YOLO v2.
Закройте модель Simulink.
close_system('laneAndVehicleDetection/Lane and Vehicle Detection Output'); close_system('laneAndVehicleDetection');
bdclose (Simulink) | close_system (Simulink) | get_param (Simulink) | load_system (Simulink) | open_system (Simulink) | save_system (Simulink) | set_param (Simulink) | sim (Simulink) | slbuild (Симулинк)