exponenta event banner

Автоматизируйте маркировку истинности земли для обнаружения транспортных средств с помощью StartStolps

В этом примере показано, как автоматизировать обнаружение транспортных средств в облаке точек с помощью предварительно обученной сети обнаружения объектов в Lidar Labeler. В этом примере используется AutomationAlgorithm интерфейс для автоматизации маркировки в приложении Lidar Labeler.

Приложение Lidar Labeler

Для разработки автоматизированных алгоритмов вождения и оценки производительности необходимы достоверные данные. Однако создание и поддержание разнообразного, высококачественного и маркированного набора данных требует значительных усилий. Приложение Lidar Labeler предоставляет инфраструктуру для автоматизации процесса маркировки с помощью AutomationAlgorithm интерфейс. Можно создать пользовательский алгоритм и использовать его в приложении для маркировки всего набора данных. Можно также отредактировать результаты для учета сложных сценариев, пропущенных алгоритмом.

В этом примере выполняется следующее:

  • Для обнаружения объектов класса используйте предварительно обученную сеть обнаружения объектов, предназначенную для (или) 'vehicle'.

  • Создайте алгоритм автоматизации, который можно использовать в приложении Lidar Labeler, чтобы автоматически маркировать транспортные средства в облаке точек с помощью сети StartStolps.

Обнаружение транспортных средств с помощью сети, работающей под управлением,

Обнаруживайте транспортные средства в облаке точек с помощью предварительно обученной сети обнаружения объектов StartPills. Эта сеть обучена обнаружению транспортных средств в облаке точек. Дополнительные сведения о том, как самостоятельно обучить сеть, см. в разделе Обнаружение объектов Lidar 3-D с помощью Deep Learning. Производительность сети зависит от ее универсальности. Сеть может работать неправильно, если она применяется к невидимым данным. Итеративное внедрение пользовательских данных обучения в процесс обучения может повысить производительность аналогичных наборов данных.

Загрузите сеть, которая обучается на наборе данных WPI.

pretrainedNetURL = 'https://ssd.mathworks.com/supportfiles/lidar/data/trainedPointPillars.zip';
preTrainedMATFile = fullfile(tempdir,'trainedPointPillarsNet.mat');
preTrainedZipFile = fullfile(tempdir,'trainedPointPillars.zip');
    
if ~exist(preTrainedMATFile,'file')
    if ~exist(preTrainedZipFile,'file')
        disp('Downloading pretrained detector (8.3 MB)...');
        websave(preTrainedZipFile, pretrainedNetURL);
    end
    unzip(preTrainedZipFile, tempdir);   
end

В зависимости от подключения к Интернету процесс загрузки может занять некоторое время. Код приостанавливает выполнение MATLAB ® до завершения процесса загрузки. Можно также загрузить набор данных на локальный диск с помощью веб-браузера и извлечь файл.

Используйте сеть для обнаружения транспортных средств в облаке точек, выполнив следующие действия.

  • Добавьте папку, содержащую вспомогательные функции, в путь поиска.

  • Чтение облака точек из lidardata.

  • Задайте ящики привязки, которые являются стандартными ограничивающими прямоугольниками в формате {длина, ширина, высота, z-центр, угол рыскания}.

  • Задайте параметры сетки для обрезки облака точек полного вида до вида спереди в формате {{xMin, yMin, zMin}, {xMax, yMax, zMax}, {xStep, yStep, dsFactor}, {Xn, Yn}}, где Xn = скругление (((xMax - xMin )/xStep)) и Y

  • Укажите имя метки для обнаруженного объекта.

  • Укажите порог достоверности для использования только обнаружений с показателями достоверности выше этого значения.

  • Укажите порог перекрытия для удаления перекрывающихся обнаружений.

  • Выберите видные столбы (P) на основе количества точек на столб (N).

  • Набор executionEnvironment.

  • Используйте helperCropFrontViewFromLidarData вспомогательная функция, присоединенная к этому примеру в качестве вспомогательного файла, для кадрирования облака точек.

  • Используйте generatePointPillarDetections вспомогательная функция из добавленного пути поиска, чтобы получить ограничивающие рамки.

  • Отображение облака точек с ограничивающими прямоугольниками.

% Add folder to path.
addpath(fullfile(matlabroot,'examples','deeplearning_shared','main'));
    
% Load the pretrained network.
pretrainedNet = load(preTrainedMATFile);

% Load a point cloud.
ptCloud = pcread(fullfile(toolboxdir('lidar'),'lidardata','highwayScene.pcd'));

% Anchor boxes.
anchorBoxes = {{3.9, 1.6, 1.56, -3.6, 0}, {3.9, 1.6, 1.56, -3.6, pi/2}};

% Cropping parameters.
gridParams = {{0.0,-39.68,-5.0},{69.12,39.68,5.0},{0.16,0.16,2.0},{432,496}};

% Label name for detected object.
classNames = {'vehicle'};

% Confidence threshold. 
confidenceThreshold = 0.45;

% Overlap threshold. 
overlapThreshold = 0.1;

% Number of prominent pillars.
P = 12000;

% Number of points per pillar.
N = 100;

% Set the execution environment.
executionEnvironment = "auto";

% Crop the front view of the point cloud. 
processedPointCloud = helperCropFrontViewFromLidarData(ptCloud, gridParams);

% Detect the bounding boxes.
[box, ~, ~] = generatePointPillarDetections(pretrainedNet.net, processedPointCloud, ...
                      anchorBoxes, gridParams, classNames, confidenceThreshold, ...
                      overlapThreshold, P, N, executionEnvironment);

% Display the detections on the point cloud.
figure
ax = pcshow(processedPointCloud.Location);
showShape('cuboid',box,'Parent',ax,'Opacity',0.1,'Color','red','LineWidth',0.5)
hold on
zoom(ax, 1.5)
title("Detected Vehicle on Point Cloud")

Подготовка класса автоматизации Lidar Vehicle Detector

Создайте класс автоматизации для алгоритма детектора лидарного транспортного средства. Класс наследует от vision.labeler.AutomationAlgorithm абстрактный базовый класс. Базовый класс определяет свойства и сигнатуры для методов, используемых приложением для настройки и запуска пользовательского алгоритма. Приложение Lidar Labeler предоставляет начальный шаблон класса автоматизации. Дополнительные сведения см. в разделе Создание алгоритма автоматизации для маркировки. LidarVehicleDetector основан на этом шаблоне и предоставляет готовый к использованию класс автоматизации для обнаружения транспортных средств в облаке точек. Комментарии класса описывают основные шаги, необходимые для реализации каждого вызова API.

Свойства алгоритма

Шаг 1 содержит свойства, определяющие имя и описание алгоритма и направления использования алгоритма.

    % ----------------------------------------------------------------------
    % Step 1: Define the required properties describing the algorithm. This
    % includes Name, Description, and UserDirections.
    properties(Constant)
        
        % Name Algorithm Name
        %   Character vector specifying the name of the algorithm.
        Name = 'Lidar Vehicle Detector';
        
        % Description Algorithm Description
        %   Character vector specifying the short description of the algorithm.
        Description = 'Detect vehicles in point cloud using PointPillars network';
        
        % UserDirections Algorithm Usage Directions
        %   Cell array of character vectors specifying directions for
        %   algorithm users to follow to use the algorithm.
        UserDirections = {['ROI Label Definition Selection: select one of ' ...
            'the ROI definitions to be labeled'], ...
            ['Run: Press RUN to run the automation algorithm. '], ...
            ['Review and Modify: Review automated labels over the interval ', ...
            'using playback controls. Modify/delete/add ROIs that were not ' ...
            'satisfactorily automated at this stage. If the results are ' ...
            'satisfactory, click Accept to accept the automated labels.'], ...
            ['Change Settings and Rerun: If automated results are not ' ...
            'satisfactory, you can try to re-run the algorithm with ' ...
            'different settings. To do so, click Undo Run to undo ' ...
            'current automation run, click Settings, make changes to Settings,' ...
            'and press Run again.'], ...
            ['Accept/Cancel: If the results of automation are satisfactory, ' ...
            'click Accept to accept all automated labels and return to ' ...
            'manual labeling. If the results of automation are not ' ...
            'satisfactory, click Cancel to return to manual labeling ' ...
            'without saving the automated labels.']};
    end

Пользовательские свойства

Шаг 2 содержит пользовательские свойства, необходимые для основного алгоритма.

    % ---------------------------------------------------------------------
    % Step 2: Define properties you want to use during the algorithm
    % execution.
    properties
        
        % SelectedLabelName 
        %   Name of the selected label. Vehicles detected by the algorithm 
        %   are assigned this variable name.
        SelectedLabelName
        
        % PretrainedNetwork
        %   PretrainedNetwork saves the pretrained PointPillars dlnetwork.
        PretrainedNetwork
        
        %   Range of point clouds along x,y,and z-axis used to crop
        %   full-view point clouds to front-view point clouds.
        %   These parameters guide the calculation of the size of the 
        %   input [xn,yn] passed to the network.

        %   xMin = 0.0;     % Minimum value along X-axis.
        %   yMin = -39.68;  % Minimum value along Y-axis.
        %   zMin = -5.0;    % Minimum value along Z-axis.
        %   xMax = 69.12    % Maximum value along X-axis.
        %   yMax = 39.68;   % Maximum value along Y-axis.
        %   zMax = 5.0;     % Maximum value along Z-axis.
        %   xStep = 0.16;   % Resolution along X-axis.
        %   yStep = 0.16;   % Resolution along Y-axis.
        %   dsFactor = 2.0; % Downsampling factor.
        
        %  Dimensions for the pseudo-image calculated as 
        %  round(((xMax - xMin) / xStep));.
        %  Xn = 432;
        %  Yn = 496;
        
        % GridParams 
        %  Parameter used to crop full-view point cloud to front-view,
        %  defined as {{xMin,yMin,zMin}, {xMax,yMax,zMax},
        %  {xStep,yStep,dsFactor}, {Xn,Yn}};
        GridParams = {{0.0,-39.68,-5.0}, {69.12,39.68,5.0}, {0.16,0.16,2.0}, {432,496}}
        
        % AnchorBoxes 
        %  Predefined bounding box dimensions based on the classes to
        %  detect, defined in the format {length, width, height,
        %  z-center, yaw angle}
        AnchorBoxes = {{3.9, 1.6, 1.56, -1.78, 0}, {3.9, 1.6, 1.56, -1.78, pi/2}};
        
        % P
        %  Number of prominent pillars.
        P = 12000;
        
        % N
        %  Number of points per pillar.
        N = 100;
        
        % ExecutionEnvironment
        %  Set the execution environment.
        ExecutionEnvironment = "auto";
        
        % ConfidenceThreshold
        %  Specify the confidence threshold to use only detections with 
        %  confidence scores above this value.
        ConfidenceThreshold = 0.45;
        
        % OverlapThreshold
        %  Specify the overlap threshold to remove overlapping detections.
        OverlapThreshold = 0.1;            
        
    end

Определения функций

На шаге 3 рассматриваются определения функций.

checkSignalType функция проверяет, поддерживаются ли данные сигнала для автоматизации. Лидарный детектор транспортного средства поддерживает сигналы типа PointCloud.

        function isValid = checkSignalType(signalType)            
            % Only point cloud signal data is valid for the Lidar Vehicle
            % detector algorithm.
            isValid = (signalType == vision.labeler.loading.SignalType.PointCloud);           
        end

checkLabelDefinition функция проверяет, является ли определение метки подходящим типом для автоматизации. Лидарный детектор транспортного средства требует Cuboid тип метки.

        function isValid = checkLabelDefinition(~, labelDef)            
            % Only cuboid ROI label definitions are valid for the Lidar
            % vehicle detector algorithm.
            isValid = labelDef.Type == labelType.Cuboid;
        end

checkSetup функция проверяет, выбрано ли определение метки ROI для автоматизации.

        function isReady = checkSetup(algObj)            
            % Is there one selected ROI Label definition to automate.
            isReady = ~isempty(algObj.SelectedLabelDefinitions);
        end

settingsDialog функция получает и модифицирует свойства, определенные на этапе 2. Этот вызов API позволяет создать диалоговое окно, которое открывается при нажатии значка «Параметры» на вкладке «Автоматизация». Чтобы создать это диалоговое окно, используйте dialog функция для быстрого создания простого модального окна для необязательного изменения пороговых значений достоверности и перекрытия. lidarVehicleDetectorSettings содержит код для настроек и шагов проверки ввода.

        function settingsDialog(algObj)
            % Invoke dialog with options for modifying the 
            % threshold and confidence threshold. 
            lidarVehicleDetectorSettings(algObj)
        end

Функции выполнения

Шаг 4 определяет функции выполнения. initialize заполняет начальное состояние алгоритма на основе существующих меток в приложении. В этом примере initialize функция выполняет следующие шаги:

  • Сохранение имени выбранного определения метки.

  • Добавьте папку, содержащую вспомогательные функции, в путь поиска.

  • Загрузите предварительно обученную сеть обнаружения объекта PointPillars от tempdir и сохраните его в PretrainedNetwork собственность.

        function initialize(algObj,~)           
            % Store the name of the selected label definition. Use this
            % name to label the detected vehicles.
            algObj.SelectedLabelName = algObj.SelectedLabelDefinitions.Name;
            
            % Add the folder containing helper functions to the search path.
            addpath(fullfile(matlabroot,'examples','deeplearning_shared','main'))

            % Point to tempdir, where pretrainedNet was downloaded.
            preTrainedMATFile = fullfile(tempdir,'trainedPointPillarsNet.mat');
            assert(exist(preTrainedMATFile,'file'), ...
                sprintf(['File : %s does not exists \n Download Pretrained PointPillars ' ...
                'network with the link provided in the example'],preTrainedMATFile));
            pretrainedNet = load(preTrainedMATFile);
            algObj.PretrainedNetwork = pretrainedNet.net;           
        end

run функция определяет алгоритм основного лидарного детектора транспортного средства данного класса автоматизации. run функция вызывается для каждого кадра последовательности облаков точек и ожидает, что класс автоматизации вернет набор меток. Алгоритм можно распространить на любую категорию, в которой обучается сеть. Для целей этого примера ограничьте сеть для обнаружения объектов класса 'Vehicle'.

        function autoLabels = run(algObj, pointCloud)
            bBoxes = [];
            for i = 1:2           
                if i == 2
                    % Rotate the point cloud by 180 degrees.
                    thetha = pi;
                    rot = [cos(thetha) sin(thetha) 0; ...
                        -sin(thetha) cos(thetha) 0; ...
                        0  0  1];
                    trans = [0, 0, 0];
                    tform = rigid3d(rot, trans);
                    pointCloud = pctransform(pointCloud, tform);
                end
                
                % Crop the front view of the point clouds.
                processedPointCloud = helperCropFrontViewFromLidarData(pointCloud, ...
                    algObj.GridParams);
                
                % Detect vehicles using the PointPillars network.
                [box, ~, ~] = generatePointPillarDetections(algObj.PretrainedNetwork,  ...
                    processedPointCloud, algObj.AnchorBoxes, algObj.GridParams, ...
                    {algObj.SelectedLabelName}, algObj.ConfidenceThreshold, ...
                    algObj.OverlapThreshold, algObj.P, algObj.N, algObj.ExecutionEnvironment);

                if ~isempty(box)
                    if i == 2
                        box(:,1) = -box(:,1);
                        box(:,2) = -box(:,2);
                        box(:,9) = -box(:,9);
                    end
                    bBoxes = [bBoxes;box];
                end
            end
            if ~isempty(bBoxes)
                % Add automated labels at bounding box locations detected
                % by the vehicle detector, of type Cuboid and with the name
                % of the selected label.
                autoLabels.Name     = algObj.SelectedLabelName;
                autoLabels.Type     = labelType.Cuboid;
                autoLabels.Position = bBoxes;
            else
                autoLabels = [];
            end
        end

terminate функция обрабатывает любую очистку или разрыв, необходимые после выполнения автоматизации. Этот алгоритм не требует никакой очистки, поэтому функция пуста.

Использовать класс автоматизации Lidar Vehicle Detector в приложении

Свойства и методы, описанные в предыдущем разделе, реализованы в LidarVehicleDetector файл класса алгоритма автоматизации. Используйте класс в приложении.

Сначала создайте структуру папок +vision/+labeler требуется в текущей папке и скопируйте в нее класс автоматизации.

    mkdir('+vision/+labeler');
    copyfile(fullfile(matlabroot,'examples','lidar','main','LidarVehicleDetector.m'), ...
        '+vision/+labeler');

Загрузите последовательность облаков точек (PCD) и последовательность изображений. В целях иллюстрации этот пример использует данные о лидаре WPI, собранные по шоссе от Изгнания датчик лидара OS1. Выполните следующий блок кода для загрузки и сохранения данных лидара во временной папке. В зависимости от подключения к Интернету процесс загрузки может занять некоторое время. Код приостанавливает выполнение MATLAB ® до завершения процесса загрузки. Можно также загрузить набор данных на локальный диск с помощью веб-браузера и извлечь файл.

Загрузите последовательность облаков точек во временное место.

    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

Приложение Lidar 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 + "lidarData";
    if ~exist(pcdDataFolder, 'dir')
        mkdir(fullfile(lidarDataFolder,'lidarData'));
    end

    disp('Saving WPI Lidar driving data to PCD files ...');
    for i = 920:940
        filename = strcat(fullfile(lidarDataFolder,'lidarData',filesep), ...
            num2str(i,'%06.0f'),'.pcd');
        pcwrite(lidarData{i}, filename);
    end

Откройте приложение Lidar Labeler и загрузите последовательность облаков точек.

    pointCloudDir = fullfile(lidarDataFolder, 'lidarData');
    lidarLabeler(pointCloudDir);

На вкладке «Метки окупаемости инвестиций» на левой панели нажмите «Метка». Определение метки окупаемости инвестиций с именем Vehicle и Cuboid. При необходимости можно выбрать цвет. Нажмите кнопку ОК.

В разделе Выбрать алгоритм (Select Algorithm) выберите Обновить (Refresh). Затем выберите Алгоритм > Лидар Детектор транспортного средства. Если этот параметр не отображается, убедитесь, что текущая рабочая папка содержит папку с именем +vision/+labeler, с именем файла LidarVehicleDetector.m в этом.

Щелкните Автоматизировать (Automate). Приложение открывает сеанс автоматизации для выбранных сигналов и отображает направления использования алгоритма.

Щелкните Настройки (Settings) и в открывшемся диалоговом окне при необходимости измените параметры и нажмите кнопку ОК.

Щелкните Выполнить (Run). Созданный алгоритм выполняется на каждом кадре последовательности и обнаруживает транспортные средства с помощью Vehicle тип метки. После того как приложение завершит запуск автоматизации, используйте ползунок или клавиши со стрелками для прокрутки последовательности, чтобы найти кадр, где алгоритм автоматизации помечен неправильно. Используйте параметры зумирования, панорамирования и поворота 3-D для просмотра и поворота облака точек. Вручную сдвиньте результаты, настроив обнаруженные ограничивающие рамки или добавив новые ограничивающие рамки.

Если обнаруженные ограничивающие рамки транспортного средства для всей последовательности удовлетворены, щелкните Принять (Accept). После этого можно вручную скорректировать метки или экспортировать помеченную истинность грунта в рабочее пространство MATLAB.

Концепции, описанные в этом примере, можно использовать для создания собственных алгоритмов автоматизации и расширения функциональных возможностей приложения.

Вспомогательные функции

helperCropFrontViewFromLidarData

function processedData = helperCropFrontViewFromLidarData(ptCloud, gridParams)
% Function to crop the front view of the point clouds
   % Set the limits for the point cloud.
   [row, column] = find(ptCloud.Location(:,:,1) < gridParams{1,2}{1} ...
       & ptCloud.Location(:,:,1) > gridParams{1,1}{1} ...
       & ptCloud.Location(:,:,2) < gridParams{1,2}{2} ...
       & ptCloud.Location(:,:,2) > gridParams{1,1}{2} ...
       & ptCloud.Location(:,:,3) < gridParams{1,2}{3} ...
       & ptCloud.Location(:,:,3) > gridParams{1,1}{3});
   ptCloud = select(ptCloud, row, column, 'OutputSize', 'full');
   finalPC = removeInvalidPoints(ptCloud);
   processedData = finalPC;           
end