Генерация кода для обнаружения объектов лидар с использованием глубокого обучения PointPillars

В этом примере показано, как сгенерировать CUDA ® MEX для детектора объектов PointPillars с пользовательскими слоями. Для получения дополнительной информации смотрите Лидар 3-D Обнаружение объектов Используя пример PointPillars Deep Learning из Lidar Toolbox™.

Необходимые условия для третьих лиц

Необходимый

  • CUDA включает графический процессор NVIDIA ® и совместимый драйвер.

Дополнительный

Для сборок, не относящихся к не-MEX, таких как статические и динамические библиотеки или исполняемые файлы, этот пример имеет следующие дополнительные требования.

Проверьте окружение GPU

Чтобы убедиться, что компиляторы и библиотеки для выполнения этого примера настроены правильно, используйте coder.checkGpuInstall (GPU Coder) функцию.

envCfg = coder.gpuEnvConfig('host');
envCfg.DeepLibTarget = 'cudnn';
envCfg.DeepCodegen = 1;
envCfg.Quiet = 1;
coder.checkGpuInstall(envCfg);

Предварительно обученная сеть PointPillars

Загрузите сеть PointPillars, обученную в Lidar 3-D Обнаружение объектов с помощью примера PointPillars Deep Learning. Чтобы обучить сеть самостоятельно, смотрите Лидар 3-D Обнаружений объектов с использованием PointPillars Глубокого обучения.

outputFolder = fullfile(tempdir, 'Pandaset');
pretrainedNetURL = 'https://ssd.mathworks.com/supportfiles/lidar/data/trainedPointPillarsPandasetNet.zip';
matFile = helperDownloadPretrainedPointPillarsNet(outputFolder, pretrainedNetURL);
load(matFile,'net');

pointpillarsDetect Функция точки входа

The pointpillarsDetect функция точки входа принимает функции столба и индексы столба как входные и передает их в обученную сеть для предсказания через pointpillarPredict функция. The pointpillarsDetect функция загружает сетевой объект из файла MAT в постоянную переменную и повторно использует постоянный объект для последующих вызовов предсказания. В частности, функция использует dlnetwork представление сети, обученной в Lidar 3-D Object Detection с использованием PointPillars Deep Learning.

type('pointpillarsDetect.m')
function [bboxes,scores,labels] = pointpillarsDetect(matFile, pillarFeatures, pillarIndices, gridParams, numOutputs, confidenceThreshold, overlapThreshold, classNames)
% The pointpillarsDetect function detects the bounding boxes, scores, and
% labels in the point cloud.

coder.extrinsic('helpergeneratePointPillarDetections');

% Define Anchor Boxes
anchorBoxes = {{1.92, 4.5, 1.69, -1.78, 0}, {1.92, 4.5, 1.69, -1.78, pi/2}, {2.1575, 6.0081, 2.3811, -1.78, 0}, {2.1575, 6.0081, 2.3811, -1.78, pi/2}};

% Predict the output
predictions = pointpillarPredict(matFile,pillarFeatures,pillarIndices,numOutputs);

% Generate Detections
[bboxes,scores,labels] = helpergeneratePointPillarDetections(predictions,gridParams,pillarIndices,...
                         anchorBoxes,confidenceThreshold,overlapThreshold,classNames);

end

function YPredCell = pointpillarPredict(matFile,pillarFeatures,pillarIndices,numOutputs)
% Predict the output of network and extract the following confidence,
% x, y, z, l, w, h, yaw and class.

% load the deep learning network for prediction
persistent net;

if isempty(net)
    net = coder.loadDeepLearningNetwork(matFile);
end

YPredCell = cell(1,numOutputs);
[YPredCell{:}] = predict(net,pillarIndices,pillarFeatures);
end

Вычислите функцию точки входа для обнаружения объектов

Оцените функцию точки входа в облаке точек.

  • Задайте параметры сетки и параметры извлечения столбов.

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

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

  • Установите порог перекрытия равным 0,1, чтобы удалить перекрывающиеся обнаружения.

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

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

Задайте параметры сетки.

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.

Вычислите размерности псевдоизображения.

Xn = round(((xMax - xMin) / xStep));
Yn = round(((yMax - yMin) / yStep));
gridParams = {{xMin,yMin,zMin},{xMax,yMax,zMax},{xStep,yStep,dsFactor},{Xn,Yn}};

Задайте параметры извлечения столба.

P = 12000; % Define number of prominent pillars.
N = 100;   % Define number of points per pillar.

Вычислим количество выходов сети.

networkOutputs = numel(net.OutputNames);

Считайте облако точек из набора данных Pandaset [2] и преобразуйте его в M-by-4 формат.

pc = pcread('pandasetDrivingData.pcd');
ptCloud = cat(2,pc.Location,pc.Intensity);

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

processedPtCloud = createPillars({ptCloud,'',''}, gridParams,P,N);

Извлеките функции стойки и индексы стойки.

pillarFeatures = dlarray(single(processedPtCloud{1,1}),'SSCB');
pillarIndices = dlarray(single(processedPtCloud{1,2}),'SSCB');

Задайте имена классов.

classNames = {'car','truck'};

Задайте желаемые пороги.

confidenceThreshold = 0.5;
overlapThreshold = 0.1;

Используйте метод обнаружения в сети PointPillars и отобразите результаты.

[bboxes,~,labels] = pointpillarsDetect(matFile, pillarFeatures, pillarIndices, gridParams, networkOutputs, confidenceThreshold, overlapThreshold, classNames);
bboxesCar = bboxes(labels == 'car',:);
bboxesTruck = bboxes(labels == 'truck',:);

Отображение обнаружений в облаке точек.

helperDisplay3DBoxesOverlaidPointCloud(pc.Location, bboxesCar, 'green', bboxesTruck, 'magenta', 'Predicted bounding boxes');

Сгенерируйте CUDA MEX

Чтобы сгенерировать код CUDA ® для pointpillarsDetect функция точки входа, создайте объект строения кода GPU для цели MEX и установите целевой язык на C++. Используйте coder.DeepLearningConfig (GPU Coder) для создания объекта строения глубокого обучения cuDNN и назначения его DeepLearningConfig свойство объекта строения кода GPU.

cfg = coder.gpuConfig('mex');
cfg.TargetLang = 'C++';
cfg.DeepLearningConfig = coder.DeepLearningConfig(TargetLibrary='cudnn');

args = {coder.Constant(matFile), pillarFeatures, pillarIndices, gridParams, coder.Constant(networkOutputs), ...
        confidenceThreshold, overlapThreshold, classNames};

codegen -config cfg pointpillarsDetect -args args -report
Code generation successful: View report

Запуск сгенерированного MEX

Вызовите сгенерированный MEX CUDA с теми же функциями и индексами стойки, что и ранее. Отображение результатов.

[bboxes, ~, labels] = pointpillarsDetect_mex(matFile, pillarFeatures, pillarIndices, gridParams,...
                                    networkOutputs, confidenceThreshold, overlapThreshold, classNames);
bboxesCar = bboxes(labels == 'car',:);
bboxesTruck = bboxes(labels == 'truck',:);

helperDisplay3DBoxesOverlaidPointCloud(pc.Location, bboxesCar, 'green', bboxesTruck, 'magenta', 'Predicted bounding boxes');

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

function preTrainedMATFile = helperDownloadPretrainedPointPillarsNet(outputFolder, pretrainedNetURL)
% Download the pretrained PointPillars network.    
    if ~exist(outputFolder,'dir')
        mkdir(outputFolder);
    end
    preTrainedZipFile = fullfile(outputFolder,'trainedPointPillarsPandasetNet.zip');  
    preTrainedMATFile = fullfile(outputFolder,'trainedPointPillarsPandasetNet.mat');
    if ~exist(preTrainedMATFile,'file')
        if ~exist(preTrainedZipFile,'file')
            disp('Downloading pretrained detector (8.4 MB)...');
            websave(preTrainedZipFile, pretrainedNetURL);
        end
        unzip(preTrainedZipFile, outputFolder);   
    end   
end

function helperDisplay3DBoxesOverlaidPointCloud(ptCld, labelsCar, carColor, labelsTruck, truckColor, titleForFigure)
% Display the point cloud with different colored bounding boxes for different
% classes
    figure;
    ax = pcshow(ptCld);
    showShape('cuboid', labelsCar, 'Parent', ax, 'Opacity', 0.1, 'Color', carColor, 'LineWidth', 0.5);
    hold on;
    showShape('cuboid', labelsTruck, 'Parent', ax, 'Opacity', 0.1, 'Color', truckColor, 'LineWidth', 0.5);
    title(titleForFigure);
    zoom(ax,1.5);
end

Ссылки

[1] Lang, Alex H., Sourabh Vora, Holger Caesar, Lubing Zhou, Jiong Yang, and Oscar Beijbom. «PointPillars: быстрые энкодеры для обнаружения объектов из облаков точек». В 2019 году IEEE/CVF Conference on Компьютерное Зрение and Pattern Recognition (CVPR), 12689-12697. Лонг Бич, Калифорния, США: IEEE, 2019. https://doi.org/10.1109/CVPR.2019.01298.

[2] Хесаи и шкала. PandaSet. https://scale.com/open-datasets/pandaset.