В этом примере показано, как автоматизировать маркировку нескольких сигналов одновременно с помощью приложения Ground Truth Labeler и AutomationAlgorithm
интерфейс. Алгоритм автоматизации, используемый в этом примере, оценивает положения меток транспортных средств в системах координат облака точек на основе положений меток транспортных средств в соответствующих системах координат изображений, используя параметры калибровки камера-лидар.
Хорошие достоверные данные имеют решающее значение для разработки алгоритмов вождения и оценки их характеристик. Однако создание богатого и разнообразного набора аннотированных приводных данных требует значительных времени и ресурсов. Приложение Ground Truth Labeler делает этот процесс эффективным. Вы можете использовать это приложение как полностью ручной инструмент аннотации для маркировки контуров маршрута, ограничивающих рамок транспортного средства и других объектов, представляющих интерес для системы зрения. Однако ручная маркировка требует значительного количества времени и ресурсов. Это приложение также предоставляет среду для создания алгоритмов для расширения и автоматизации процесса маркировки. Можно создать и использовать алгоритмы, чтобы быстро пометить целые наборы данных, а затем последовать за ними с более эффективным, более коротким шагом ручной верификации. Можно также отредактировать результаты шага автоматизации, чтобы учесть сложные сценарии, которые алгоритм автоматизации мог пропустить.
Этот пример описывает создание алгоритма, который может использоваться в приложении Ground Truth Labeler для автоматического обнаружения транспортных средств на изображении и оценки их позиций в соответствующем облаке точек с помощью параметров калибровки камера-лидар.
Чтобы обнаружить транспортные средства в изображениях, алгоритм автоматизации использует предварительно обученный агрегированный детектор функций канала (ACF) транспортного средства, vehicleDetectorACF
. Предварительный просмотр работы алгоритма путем загрузки изображения образца и детектора автомобиля ACF, обнаружения транспортных средств на изображении и вставки 2-D ограничительных коробок вокруг транспортных средств на изображении.
% Load the data from the MAT file and extract the image. data = load(fullfile(toolboxdir('lidar'),'lidardata','lcc','bboxGT.mat')); I = data.im; % Load the pretrained detector for vehicles. detector = vehicleDetectorACF('front-rear-view'); % Detect vehicles and show the bounding boxes. [imBboxes,~] = detect(detector, I); Iout = insertShape(I,'rectangle',imBboxes,'LineWidth',4); figure imshow(Iout) title('Detected Vehicles')
Если у вас есть доступная информация о калибровке камеры, можно улучшить этот детектор, отфильтровав ложные срабатывания от обнаружений. Пример Visual Perception Using Monocular Camera описывает, как создать предварительно обученный детектор транспортного средства и сконфигурировать его, чтобы обнаружить транспортное средство ограничительные коробки с помощью калиброванной монокулярным строением камеры.
Чтобы оценить автомобили в системах координат облака точек из соответствующих обнаруженных транспортных средств в системах координат изображений, алгоритм использует bboxCameraToLidar
(Lidar Toolbox) функция. Эта функция использует параметры калибровки лидара к камере, чтобы оценить 3-D ограничивающие рамки на основе 2-D ограничивающих коробок. Чтобы оценить ограничительные рамки, функция принимает в качестве входов собственные параметры камеры, cameraIntrinsics
и твердое преобразование камеры в лидар, rigid3d
.
Предварительный просмотр работы алгоритма путем загрузки облака точек, соответствующего изображению, оценки 3-D ограничивающих рамок транспортных средств в облаке точек и вставки ограничивающих рамок вокруг транспортных средств в облаке точек.
% Extract the point cloud. ptCloud = data.pc; % Extract the intrinsic camera parameters. intrinsics = data.cameraParams; % Extract the camera-to-lidar rigid transformation. tform = data.camToLidar; % Estimate the bounding boxes in the point cloud. pcBboxes = bboxCameraToLidar(imBboxes, ptCloud, intrinsics, tform); % Display bounding boxes in the point cloud. figure ax = pcshow(ptCloud.Location); showShape('cuboid',pcBboxes,'Parent',ax,'Opacity',0.1,'Color',[0.06 1.00 1.00],'LineWidth',0.5) hold on zoom(ax,1.5) title('Estimated Bounding Box in Point Cloud') hold off
Чтобы включить алгоритм мультисигнального детектора транспортных средств в рабочий процесс автоматизации приложения Ground Truth Labeler, создайте класс, который наследует от абстрактного базового класса, vision.labeler.AutomationAlgorithm
. Этот базовый класс определяет свойства и сигнатуры для методов, которые приложение использует для настройки и выполнения пользовательского алгоритма. Приложение Ground Truth Labeler предоставляет удобный способ получить исходный шаблон класса автоматизации. Для получения дополнительной информации смотрите Создать Алгоритм Автоматизации для Маркировки. Класс MultiSignalVehicleDetector основан на этом шаблоне и предоставляет вам готовый к использованию класс автоматизации для обнаружения транспортного средства в изображении и оценке ограничивающего прямоугольника транспортного средства в облаке точек. Комментарии класса описывают основные шаги, необходимые для реализации каждого вызова API.
Шаг 1 содержит свойства, которые определяют имя и описание алгоритма и направления использования алгоритма.
% ---------------------------------------------------------------------- % Step 1: Define the properties required for describing the algorithm, % which include Name, Description, and UserDirections. properties(Constant) % Name Algorithm name % Character vector specifying the name of the algorithm. Name = 'Multisignal Vehicle Detector'; % Description Algorithm description % Character vector specifying the short description of the algorithm. Description = ['Detect vehicles using ACF Vehicle Detector in ' ... 'image and estimate them in point cloud.']; % UserDirections Algorithm usage directions % Cell array of character vectors specifying directions for % algorithm users to follow. UserDirections = {['Select one of the rectangle ROI labels to ' ... 'label objects as Vehicle.'], ... ['Click Settings and on the Lidar Camera Calibration ' ... 'Parameters tab, load the cameraIntrinsics and rigid3d ' ... 'objects from the workspace.'], ... ['Specify additional parameters under Settings.'], ... ['Click Run to detect vehicles in each image and point cloud.'], ... ['Review automated labels manually. You can modify, delete ', ... 'and add new labels.'], ... ['If you are not satisfied with the results, click Undo ' ... 'Run. Click Settings to modify algorithm settings and click ', ... 'Run again.'] ... ['When you are satisfied with the results, click Accept and ', ... 'return to manual labeling.']}; end
Шаг 2 содержит пользовательские свойства для основного алгоритма.
% --------------------------------------------------------------------- % Step 2: Define properties to be used to manage algorithm execution. properties % SelectedLabelName Selected label name % Name of the selected label. Vehicles detected by the algorithm will % be assigned this variable name. SelectedLabelName % Detector Detector % Pretrained vehicle detector, an object of class % acfObjectDetector. Detector % VehicleModelName Vehicle detector model name % Name of pretrained vehicle detector model. VehicleModelName = 'full-view'; % OverlapThreshold Overlap threshold % Threshold value used to eliminate overlapping bounding boxes % around the reference bounding box, between 0 and 1. The % bounding box overlap ratio denominator, 'RatioType', is set to % 'Min'. OverlapThreshold = 0.45; % ScoreThreshold Classification score threshold % Threshold value used to reject detections with low detection % scores. ScoreThreshold = 20; % ConfigureDetector Detection configuration flag % Boolean value that determines whether the detector is % configured using monoCamera sensor. ConfigureDetector = false; % SensorObj monoCamera sensor % Monocular camera sensor object, monoCamera, used to configure % the detector. A configured detector runs faster and can % potentially result in better detections. SensorObj = []; % SensorStr monoCamera sensor variable name % Character vector specifying the monoCamera object variable name % used to configure the detector. SensorStr = ''; % VehicleWidth Vehicle width % Vehicle width used to configure the detector, specified as % [minWidth, maxWidth], which describes the approximate width of the % object in world units. VehicleWidth = [1.5 2.5]; % VehicleLength Vehicle length % Vehicle length used to configure the detector, specified as % [minLength, maxLength] vector, which describes the approximate % length of the object in world units. VehicleLength = []; % IntrinsicsObj Camera intrinsics % cameraIntrinsics object, which represents a projective % transformation from camera to image coordinates. IntrinsicsObj = []; % IntrinsicsStr cameraIntrinsics variable name % cameraIntrinsics object variable name. IntrinsicsStr = ''; % ExtrinsicsObj Camera-to-lidar rigid transformation % rigid3d object representing the 3-D rigid geometric transformation % from the camera to the lidar. ExtrinsicsObj = []; % ExtrinsicsStr rigid3d variable name % Camera-to-lidar rigid3d object variable name. ExtrinsicsStr = ''; % ClusterThreshold Clustering threshold for two adjacent points % Threshold specifying the maximum distance between two adjacent points % for those points to belong to the same cluster. ClusterThreshold = 1; end
Шаг 3 посвящен определениям функций.
Первая функция, supportsMultisignalAutomation
,
проверяет, что алгоритм поддерживает несколько сигналов. Для мультисигнального детектора транспортных средств вы загружаете сигналы как изображения, так и облака точек, так success
установлено в true
.
function success = supportsMultisignalAutomation(~) % Supports MultiSignal. success = true; end
Следующая функция, checkSignalType
,
проверяет, что для автоматизации поддерживаются только сигналы соответствующего типа. Мультисигнальный детектор транспортного средства должен поддерживать сигналы типа Image
и PointCloud
, поэтому эта версия функции проверяет оба типа сигналов.
function isValid = checkSignalType(signalType) % Only video/image sequence and point cloud signal data % is valid. isValid = any(signalType == vision.labeler.loading.SignalType.Image) && ... any(signalType == vision.labeler.loading.SignalType.PointCloud); end
Следующая функция, checkLabelDefinition
проверяет, что для автоматизации включены только метки соответствующего типа. Для обнаружения транспортного средства в изображениях и сигналах облака точек, вы проверяете, что только метки типа Rectangle
/ Cuboid
включены, поэтому эта версия функции проверяет Type
меток.
function isValid = checkLabelDefinition(~, labelDef) % Only Rectangular/Cuboid ROI Label definitions are valid for the % Vehicle Detector. isValid = (labelDef.Type == labelType.Cuboid || labelDef.Type == labelType.Rectangle); end
Следующая функция, checkSetup
проверяет, что для автоматизации выбрано только одно определение метки информация только для чтения.
function isReady = checkSetup(algObj, ~) % Is there one selected ROI Label definition to automate? isReady = ~isempty(algObj.SelectedLabelDefinitions); end
Далее, settingsDialog
функция получает и изменяет свойства, заданные на шаге 2. Этот вызов API позволяет вам создать диалоговое окно, которое открывается при нажатии пользователем кнопки Настройки на вкладке Автоматизация. Чтобы создать это диалоговое окно, используйте dialog
функция для создания модального окна, чтобы попросить пользователя задать cameraIntrinsics
объект и rigid3d
объект. The multiSignalVehicleDetectorSettings
метод содержит код для настроек, а также добавляет входные шаги валидации.
function settingsDialog(algObj) % Invoke dialog box to input camera intrinsics and % camera-to-lidar rigid transformation and options for choosing % a pretrained model, overlap threshold, detection score % threshold, and clustering threshold. Optionally, input a % calibrated monoCamera sensor to configure the detector. multiSignalVehicleDetectorSettings(algObj); end
Шаг 4 задает функции выполнения. The initialize
функция заполняет начальное состояние алгоритма на основе существующих меток в приложении. В MultiSignalVehicleDetector
класс, initialize
функция была настроена, чтобы хранить имя выбранного определения метки и загрузить предварительно обученный детектор транспортного средства ACF и сохранить его в Detector
свойство.
function initialize(algObj, ~) % Store the name of the selected label definition. Use this % name to label the detected vehicles. algObj.SelectedLabelName = algObj.SelectedLabelDefinitions.Name; % Initialize the vehicle detector with a pretrained model. algObj.Detector = vehicleDetectorACF(algObj.VehicleModelName); end
Далее, run
функция определяет основной алгоритм обнаружения транспортных средств этого класса автоматизации. The run
функция вызывается для каждой системы координат последовательности изображений и облака точек и ожидает, что класс автоматизации вернет набор меток. The run
функция в MultiSignalVehicleDetector
содержит описанную ранее логику для обнаружения 2-D транспортных средств ограничивающих рамок в системах координат изображений и оценки 3-D транспортных средств ограничивающих рамок в системы координат облака точек.
function autoLabels = run(algObj, I) % autoLabels a cell array of length the same as the number of % signals. autoLabels = cell(size(I,1),1); % Get the index of Image and PointCloud frames. if isa(I{1,1},"pointCloud") pcIdx = 1; imIdx = 2; else imIdx = 1; pcIdx = 2; end % Detect bounding boxes on image frame. selectedBboxes = detectVehicle(algObj, I{imIdx,1}); % Estimate bounding boxes on point cloud frame. if ~isempty(selectedBboxes) % Store labels from the image. imageLabels = struct('Type', labelType.Rectangle, ... 'Name', algObj.SelectedLabelDefinitions.Name, ... 'Position', selectedBboxes); autoLabels{imIdx, 1} = imageLabels; % Remove the ground plane for the point cloud. groundPtsIndex = segmentGroundFromLidarData(I{pcIdx,1}, ... "ElevationAngleDelta", 15, "InitialElevationAngle", 10); nonGroundPts = select(I{pcIdx,1}, ~groundPtsIndex); % Predict 3-D bounding boxes. pcBboxes = bboxCameraToLidar(selectedBboxes, nonGroundPts, algObj.IntrinsicsObj, ... algObj.ExtrinsicsObj, "ClusterThreshold", algObj.ClusterThreshold); % Store labels from the point cloud. if(~isempty(pcBboxes)) pcLabels = struct('Type', labelType.Cuboid,... 'Name', algObj.SelectedLabelDefinitions.Name,... 'Position', pcBboxes); autoLabels{pcIdx, 1} = pcLabels; else autoLabels{pcIdx, 1} = {}; end else autoLabels{imIdx, 1} = {}; autoLabels{pcIdx, 1} = {}; end end
Наконец, terminate
функция обрабатывает любую очистку или отключения, необходимые после завершения автоматизации. Этот алгоритм не требует никакой очистки, поэтому функция пуста.
function terminate(~) end
Свойства и методы, описанные в предыдущем разделе, реализованы в MultiSignalVehicleDetector
файл класса алгоритма автоматизации. Чтобы использовать этот класс в приложении:
Создайте структуру папки +vision/+labeler
требуется в текущей папке и скопировать в нее класс автоматизации.
mkdir('+vision/+labeler'); copyfile(fullfile(matlabroot,'examples','driving','main','MultiSignalVehicleDetector.m'), ... '+vision/+labeler');
Загрузите последовательность облака точек (PCD) и последовательности изображений. В рисунок целях этот пример использует данные лидара WPI, собранные на шоссе с датчика Ouster OS1 лидара, и данные изображения WPI с фронтальной камеры, установленной на автомобиль , оборудованный датчиком. Выполните следующий блок кода, чтобы загрузить и сохранить данные лидара и изображения во временной папке. В зависимости от вашего подключения к Интернету процесс загрузки может занять некоторое время. Код приостанавливает выполнение MATLAB ® до завершения процесса загрузки. Также можно загрузить набор данных на локальный диск с помощью веб-браузера и извлечь файл.
Загрузите последовательность изображений во временное место.
imageURL = 'https://www.mathworks.com/supportfiles/lidar/data/WPI_ImageData.tar.gz'; imageDataFolder = fullfile(tempdir, 'WPI_ImageData',filesep); imageDataTarFile = imageDataFolder + "WPI_ImageData.tar.gz"; if ~exist(imageDataFolder,'dir') mkdir(imageDataFolder) end if ~exist(imageDataTarFile, 'file') disp('Downloading WPI Image driving data (225 MB)...'); websave(imageDataTarFile, imageURL); untar(imageDataTarFile, imageDataFolder); end % Check if image tar.gz file is downloaded, but not uncompressed. if ~exist(fullfile(imageDataFolder,'imageData'),'dir') untar(imageDataTarFile, imageDataFolder) end
В целях рисунка этот пример использует только подмножество последовательности изображений WPI из систем координат 920-940. Чтобы загрузить подмножество изображений в приложение, скопируйте изображения в папку.
% Create new folder and copy the images. imDataFolder = imageDataFolder + "imageDataSequence"; if ~exist(imDataFolder,'dir') mkdir(imDataFolder); end for i = 920 : 940 filename = strcat(num2str(i,'%06.0f'),'.jpg'); source = fullfile(imageDataFolder,'imageData',filename); destination = fullfile(imageDataFolder,'imageDataSequence',filename); copyfile(source,destination) end
Загрузите последовательность облака точек во временное место.
lidarURL = 'https://www.mathworks.com/supportfiles/lidar/data/WPI_LidarData.tar.gz'; lidarDataFolder = fullfile(tempdir,'WPI_LidarData',filesep); lidarDataTarFile = lidarDataFolder + "WPI_LidarData.tar.gz"; if ~exist(lidarDataFolder) mkdir(lidarDataFolder) end if ~exist(lidarDataTarFile, 'file') disp('Downloading WPI Lidar driving data (760 MB)...'); websave(lidarDataTarFile,lidarURL); untar(lidarDataTarFile,lidarDataFolder); end % Check if lidar tar.gz file is downloaded, but not uncompressed. if ~exist(fullfile(lidarDataFolder,'WPI_LidarData.mat'),'file') untar(lidarDataTarFile,lidarDataFolder); end
Приложение Ground Truth Labeler поддерживает загрузку последовательностей облака точек, состоящих из файлов PCD или PLY. Сохраните загруженные данные облака точек в PCD- файлов. В целях рисунка в этом примере вы сохраняете только подмножество данных облака точек WPI из систем координат 920-940.
% Load downloaded lidar data into the workspace. load(fullfile(lidarDataFolder,'WPI_LidarData.mat'),'lidarData'); lidarData = reshape(lidarData,size(lidarData,2),1); % Create new folder and write lidar data to PCD files. pcdDataFolder = lidarDataFolder + "lidarDataSequence"; if ~exist(pcdDataFolder, 'dir') mkdir(fullfile(lidarDataFolder,'lidarDataSequence')); end disp('Saving WPI Lidar driving data to PCD files ...'); for i = 920:940 filename = strcat(fullfile(lidarDataFolder,'lidarDataSequence',filesep), ... num2str(i,'%06.0f'),'.pcd'); pcwrite(lidarData{i},filename); end
Ожидается, что калибровочная информация будет иметь форму собственных и внешних (твердое преобразование) параметров, упомянутых в лидар и Camera Calibration (Lidar Toolbox). Загрузите признаки камеры, которые хранятся в cameraIntrinsics
объект и твердое преобразование камеры в лидар, которое сохранено в rigid3d
объект, в рабочую область. Данные WPI в этом примере калибруются, и внутренние и внешние (преобразование камеры в лидар) параметры сохраняются в файле MAT.
data = load(fullfile(toolboxdir('lidar'),'lidardata','lcc','bboxGT.mat')); cameraParams = data.cameraParams; camToLidar = data.camToLidar;
Откройте приложение Ground Truth Labeler.
imageDir = fullfile(tempdir, 'WPI_ImageData', 'imageDataSequence'); pointCloudDir = fullfile(tempdir, 'WPI_LidarData', 'lidarDataSequence'); groundTruthLabeler
На панели инструментов приложения выберите Импорт и затем Добавить сигналы. В окне Add/Remove Signal загрузите последовательность изображений.
Установите тип источника равным Image Sequence
.
Найдите папку последовательности изображений в расположении, заданном imageDir
переменная.
Используйте временные метки по умолчанию и нажмите Add Source. Папка последовательности изображений, imageDataSequence
, добавляется к таблице источников сигналов.
На панели инструментов приложения выберите Импорт и затем Добавить сигналы. В окне Add/Remove Signal загрузите последовательность облака точек.
Установите тип источника равным Point Cloud Sequence
.
Найдите папку последовательности облаков точек в расположении, заданном pointCloudDir
переменная.
Используйте временные метки по умолчанию и нажмите Add Source. Папка последовательности облаков точек, lidarDataSequence
, добавляется к таблице источников сигналов.
Нажмите OK, чтобы импортировать сигналы в приложение. Чтобы просмотреть сигналы один за другим, на вкладке Label, нажмите Display Grid и отобразите сигналы в сетке 1 на 2.
На вкладке информации только для чтения Labels в левой панели нажмите Label и задайте метку информации только для чтения с именем Vehicle
и тип Rectangle/Cuboid
, как показано здесь. Вы можете выбрать цвет и нажать кнопку ОК.
Выберите оба сигнала для автоматизации. На вкладке Label выберите Algorithm, а затем Select Signals, и выберите оба сигнала. Нажмите кнопку ОК.
В разделе Select Algorithm выберите Refresh list. Затем выберите Algorithm, а затем Multisignal Vehicle Detector. Если вы не видите эту опцию, проверьте, что текущая рабочая папка имеет папку с именем +vision/+labeler
, с файлом с именем MultiSignalVehicleDetector.m
в этом.
Щелкните Автоматизировать (Automate). Приложение открывает сеанс автоматизации для выбранных сигналов и отображает направления для использования алгоритма.
Загрузите параметры собственной камеры в сеанс автоматизации.
На вкладке Automate нажмите Settings.
На вкладке Lidar-to-Camera Calibration Parameters нажмите Import camera invinics from workspace.
Импорт собственных параметров камеры, cameraParams
, из рабочего пространства MATLAB. Нажмите кнопку ОК.
Загрузите преобразование камеры в лидар в сеанс автоматизации.
На вкладке Параметры калибровки лидара к камере щелкните Импорт преобразования камеры к лидару из рабочей области.
Импортируйте преобразование, camToLidar
, из рабочего пространства MATLAB. Нажмите кнопку ОК.
Измените дополнительные настройки детектора автомобиля по мере необходимости и нажатие кнопки OK. Затем на вкладке Automate нажмите Запуск. Созданный алгоритм выполняет на каждой системе координат последовательности и обнаруживает транспортные средства при помощи Vehicle
тип метки. После того, как приложение завершит запуск автоматизации, используйте ползунок или клавиши со стрелами для прокрутки последовательности, чтобы найти системы координат, где алгоритм автоматизации помечен неправильно. Вручную сдвиньте результаты путем корректировки обнаруженных ограничивающих рамок или добавления новых ограничивающих рамок.
После того, как вы будете удовлетворены обнаруженными ограничивающими рамками транспортного средства для всей последовательности, нажмите Accept. Затем можно продолжить ручную настройку меток или экспорт помеченной основной истины в рабочее пространство MATLAB.
Можно использовать концепции, описанные в этом примере, чтобы создать свои собственные пользовательские алгоритмы мультисигнальной автоматизации и расширить функциональность приложения.
bboxCameraToLidar
(Lidar Toolbox) | bboxLidarToCamera
(Lidar Toolbox)