В этом примере показано, как разработать алгоритм автоматической разметки контуров маршрута в приложении Ground Truth Labeler.
Хорошие достоверные данные имеют решающее значение для разработки алгоритмов вождения и оценки их характеристик. Однако создание богатого и разнообразного набора аннотированных приводных данных требует значительных времени и ресурсов. Приложение Ground Truth Labeler делает этот процесс эффективным. Вы можете использовать это приложение как полностью ручной инструмент аннотации для маркировки контуров маршрута, ограничивающих рамок транспортного средства и других объектов, представляющих интерес для системы зрения. Однако ручная маркировка требует значительного количества времени и ресурсов. Это приложение также предоставляет среду для создания алгоритмов для расширения и автоматизации процесса маркировки. Можно использовать алгоритмы, которые вы создаете, чтобы быстро пометить целые наборы данных, а затем следовать им с более эффективным, более коротким шагом ручной верификации. Можно также отредактировать результаты шага автоматизации, чтобы учесть сложные сценарии, которые алгоритм автоматизации мог пропустить. Этот пример описывает, как вставить алгоритм обнаружения маршрута в рабочий процесс автоматизации приложения.
Сначала создайте алгоритм обнаружения маршрута. Пример визуального восприятия с использованием монокулярной камеры описывает процесс обнаружения контуров маршрута и helperMonoSensor
пакеты классов, которые алгоритмируются в один, переиспользуемый класс. Попробуйте алгоритм на одном видеокадре, чтобы обнаружить контур левой эго-полосы.
configData = load('birdsEyeConfig'); sensor = configData.birdsEyeConfig.Sensor; monoSensor = helperMonoSensor(sensor); I = imread('road.png'); sensorOut = processFrame(monoSensor, I); lb = sensorOut.leftEgoBoundary; figure IwithLane = insertLaneBoundary(I, lb, sensor, [3 30], 'Color', 'blue'); imshow(IwithLane); title('Detected Left Lane Boundary Model');
Маршрут, обнаруженный на предыдущем шаге, является моделью и должен быть преобразован в набор дискретных точек. Эти точки аналогичны тому, что пользователь может поместить на изображение вручную. В поле зрения камеры части маршрута, контур ближе к транспортному средству (нижняя часть изображения камеры), будут охватывать больше пикселей, чем последующие части. Следовательно, пользователь будет размещать больше точек с более высоким доверием в нижних частях изображения камеры. Чтобы повторить это поведение, определите местоположения контуров маршрута из контура более плотно в точках ближе к транспортному средству.
ROI = [3 30]; xPoints = [3 3.5 4 5 7 12 30]'; % More dense closer to the vehicle yPoints = lb.computeBoundaryModel(xPoints); % Find corresponding image locations boundaryPointsOnImage = vehicleToImage(sensor, [xPoints, yPoints]); imshow(I) hold on plot(boundaryPointsOnImage(:,1), boundaryPointsOnImage(:,2),... 'o',... 'MarkerEdgeColor','b',... 'MarkerFaceColor','b',... 'MarkerSize',10) title('Automatically Marked Lane Boundary Points'); hold off
Чтобы включить этот алгоритм обнаружения маршрута в рабочий процесс автоматизации приложения, создайте класс, который наследует от абстрактного базового класса vision.labeler.AutomationAlgorithm
. Этот базовый класс определяет свойства и сигнатуры для методов, которые приложение использует для настройки и выполнения пользовательского алгоритма. Приложение Ground Truth Labeler предоставляет удобный способ получить исходный шаблон класса автоматизации. Для получения дополнительной информации смотрите Создать Алгоритм Автоматизации для Маркировки. The AutoLaneMarking
класс основан на этом шаблоне и предоставляет вам готовый к использованию класс автоматизации для обнаружения маршрута. Комментарии класса описывают основные шаги, необходимые для реализации каждого вызова API.
Шаг 1 содержит свойства, которые определяют имя и описание алгоритма, и направления использования алгоритма.
%---------------------------------------------------------------------- % Step 1: Define required properties describing the algorithm. This % includes Name, Description, and UserDirections. properties(Constant)
% Name: Give a name for your algorithm. Name = 'Lane Detector';
% Description: Provide a one-line description for your algorithm. Description = 'Automatically detect lane-like features';
% UserDirections: Provide a set of directions that are displayed % when this algorithm is invoked. The directions % are to be provided as a cell array of character % vectors, with each element of the cell array % representing a step in the list of directions. UserDirections = {... 'Load a MonoCamera configuration object from the workspace using the settings panel',... 'Specify additional parameters in the settings panel',... 'Run the algorithm',... 'Manually inspect and modify results if needed'}; end
Шаг 2 содержит пользовательские свойства, необходимые для основного алгоритма. Необходимые свойства определялись с помощью секции обнаружения маршрута и создания точек маршрута выше.
%--------------------------------------------------------------------- % Step 2: Define properties to be used during the algorithm. These are % user-defined properties that can be defined to manage algorithm % execution. properties %MonoCamera % The monoCamera object associated with this video MonoCamera = []; %MonoCameraVarname % The workspace variable name of the monoCamera object MonoCameraVarname = ''; %BirdsEyeConfig % The birdsEyeView object needed to create the bird's-eye view BirdsEyeConfig = []; %MaxNumLanes % The maximum number of lanes the algorithm tries to annotate MaxNumLanes = 2; %ROI % The region of interest around the vehicle used to search for % lanes ROI = [3, 30, -3, 3]; %LaneMaskSensitivity % The sensitivity parameter used in the segmentLaneMarkerRidge function LaneMaskSensitivity = 0.25; %LaneBoundaryWidth % The lane boundary width, used in findParabolicLaneBoundaries LaneBoundaryWidth = 0.6; %XPoints % The x-axis points along which to mark the lane boundaries XPoints = [3 3.5 4 4.5 5 6 7 10 30]; end
Шаг 3 посвящен определениям функций. Первая функция, checkLabelDefinition
, гарантирует, что для автоматизации включены только метки соответствующего типа. Для обнаружения маршрута необходимо убедиться, что только метки типа Line
включены, поэтому эта версия функции проверяет Type
из меток:
function TF = checkLabelDefinition(~, labelDef) % Lane detection only works with Line type labels TF = labelDef.Type == labelType.Line; end
Следующая функция checkSetup
. Обратите внимание, что этот алгоритм требует monoCamera
строение датчика, которая будет доступна. Все другие свойства имеют допустимые значения по умолчанию.
function TF = checkSetup(algObj, ~) % This is the only required input TF = ~isempty(algObj.MonoCamera); end
Далее, settingsDialog
функция получает и изменяет свойства, заданные в шаге 2. Этот вызов API позволяет вам создать диалоговое окно, которое открывается при нажатии пользователем кнопки Настройки на вкладке Автоматизация. Чтобы создать это диалоговое окно, используйте inputdlg
функция, чтобы быстро создать простое модальное окно, чтобы попросить пользователя задать monoCamera
объект. Следующий фрагмент кода описывает основной синтаксис. Полная AutoLaneMarking
код расширяет эту логику, а также добавляет входные шаги валидации.
% Describe the inputs prompt = {... 'Enter the MonoCamera variable name',... 'Maximum number of Lanes',... }; defaultAnswer = {... '',... num2str(2),... };
% Create an input dialog name = 'Settings for lane detection'; numLines = 1; options.Resize = 'on'; options.WindowStyle = 'normal'; options.Interpreter = 'none'; answer = inputdlg(prompt,name,numLines,defaultAnswer,options);
% Obtain the inputs monoCameraVarname = answer{1}; maxNumberOfLanes = answer{2};
Шаг 4 задает функции выполнения. Некоторым алгоритмам автоматизации необходимо реализовать initialize
стандартная программа для заполнения начального состояния алгоритма на основе существующих меток в приложении. Этот алгоритм обнаружения маршрута работает на каждой системе координат независимо, поэтому версия шаблона по умолчанию была обрезана, чтобы не предпринимать никаких действий.
function initialize(~, ~, ~) end
Далее, run
функция задает основной алгоритм обнаружения маршрута для этого класса автоматизации. run
вызывается для каждого видеокадра и ожидает, что класс автоматизации вернет набор меток. The run
функция в AutoLaneMarking
содержит логику, введенную ранее для обнаружения маршрута и преобразования в точки. Код из helperMonoSensor
также был свернут для более компактной ссылки.
function autoLabels = run(algObj, I) Ig = im2gray(I); birdsEyeViewImage = transformImage(algObj.BirdsEyeConfig, Ig); birdsEyeViewBW = segmentLaneMarkerRidge(birdsEyeViewImage, ... algObj.BirdsEyeConfig, algObj.LaneBoundaryWidth, ... 'Sensitivity', algObj.LaneMaskSensitivity);
% Obtain lane candidate points in world coordinates [imageX, imageY] = find(birdsEyeViewBW); boundaryPointsxy = imageToVehicle(algObj.BirdsEyeConfig, [imageY, imageX]);
% Fit requested number of boundaries to it lbs = findParabolicLaneBoundaries(... boundaryPointsxy,algObj.LaneBoundaryWidth, ... 'MaxNumBoundaries',algObj.MaxNumLanes); numDetectedLanes = numel(lbs);
% Convert the model to discrete set of points at the specified % x coordinates boundaryPoints = cell(1,numDetectedLanes); xPoints = algObj.XPoints'; for ind = 1:numel(lbs) yPoints = lbs(ind).computeBoundaryModel(xPoints); boundaryPoints{ind} = vehicleToImage(algObj.MonoCamera, [xPoints, yPoints]); end
% Package up the results in a table autoLabels = table(... boundaryPoints',... repmat(labelType.Line, [numDetectedLanes,1]),... repmat(algObj.SelectedLabelDefinitions.Name, [numDetectedLanes,1])); autoLabels.Properties.VariableNames = {'Position','Type','Name'}; end
Наконец, terminate
функция обрабатывает любую очистку или отключения, необходимые после завершения автоматизации. Этот алгоритм не требует никакой очистки, поэтому функция пуста.
function terminate(~) end
Упакованная версия алгоритма обнаружения маршрута теперь готова к использованию в AutoLaneMarking
класс. Чтобы использовать этот класс в приложении:
Создайте структуру папки, необходимую для текущей папки, и скопируйте в нее класс автоматизации.
mkdir('+vision/+labeler'); copyfile(fullfile(matlabroot,'toolbox','driving','drivingdemos','AutoLaneMarking.m'),'+vision/+labeler');
Загрузите monoCamera
информацию в рабочую область.
configData = load('birdsEyeConfig'); sensor = configData.birdsEyeConfig.Sensor;
Откройте приложение Ground Truth Labeler.
groundTruthLabeler caltech_cordova1.avi
На левой панели нажмите кнопку Задать новую метку ROI и определите стиль информации только для чтения. Затем нажмите кнопку ОК.
Щелкните Алгоритм > Выбрать Алгоритм > Обновить список.
Выберите «Алгоритм» > «Автоматическое обнаружение маршрута». Если вы не видите эту опцию, убедитесь, что в текущей рабочей папке есть папка с именем +vision/+labeler
, с файлом с именем AutoLaneMarking.m
в этом.
Щелкните Автоматизировать (Automate). Откроется новая вкладка, отображающая направления для использования алгоритма.
Нажмите Settings, и в открывшемся диалоговом окне введите sensor
в первом текстовом поле. При необходимости измените другие параметры перед нажатием кнопки ОК.
Нажмите Запуск. Алгоритм обнаружения маршрута прогрессирует на видео. Заметьте, что результаты не удовлетворительны в некоторых системах координат.
После завершения запуска Используйте клавиши slider или стрелу для прокрутки видео, чтобы найти системы координат, в которой не удалось выполнить алгоритм.
Вручную сдвиньте результаты путем перемещения точек контура маршрута или удаления целых контуров.
После того, как вы удовлетворены контурами маршрута для всего видео, нажмите Принять.
Часть автоматического обнаружения маршрута маркировки видео завершена. Можно продолжить маркировку других интересующих объектов, сохранить сеанс или экспортировать результаты этого запуска маркировки.
Этот пример показал шаги, чтобы включить алгоритм обнаружения маршрута в приложение Ground Truth Labeler. Вы можете распространить эту концепцию на другие пользовательские алгоритмы, чтобы упростить и расширить функциональность приложения.