В этом примере показано, как обучить сеть PointPillars для обнаружения объектов в облаках точек.
Данные об облаке точек лидара могут быть получены множеством датчиков лидара, включая Velodyne®, Pandar и датчики Изгнания. Эти датчики получают 3-D информацию о положении об объектах в сцене, которая полезна для многих приложений в автономном управлении автомобилем и дополненной реальности. Однако учебные устойчивые детекторы с данными об облаке точек сложны из-за разреженности данных на объект, объектные поглощения газов и шум датчика. Методы глубокого обучения, как показывали, обратились ко многим из этих проблем путем изучения устойчивых представлений функции непосредственно от данных об облаке точек. Один метод глубокого обучения для 3-D обнаружения объектов является PointPillars [1]. Используя подобную архитектуру к PointNet, извлечения сети PointPillars плотные, устойчивые функции от разреженных облаков точек вызвали столбы, затем используют 2D нейронную сеть для глубокого обучения с модифицированной сетью обнаружения объектов SSD, чтобы оценить объединенные 3-D ограничительные рамки, ориентации и предсказания класса.
Этот пример использует набор данных PandaSet [2] от Hesai и Scale. PandaSet содержит 8 240 неорганизованных сканов облака точек лидара различных городских сцен, полученных с помощью датчика Pandar64. Набор данных обеспечивает 3-D метки ограничительной рамки для 18 различных классов объектов, включая автомобиль, грузовик и пешехода.
Этот пример использует подмножество PandaSet, который содержит 2 560 предварительно обработанных организованных облаков точек. Каждое облако точек покрытия из представления, и задан как 64 1856 матрица. Облака точек хранятся в формате PCD, и их соответствующие достоверные данные хранится в PandaSetLidarGroundTruth.mat
файл. Файл содержит 3-D информацию об ограничительной рамке для трех классов, которые являются автомобилем, грузовиком и пешеходом. Размер набора данных составляет 5,2 Гбайт.
Загрузите набор данных Pandaset с данного URL с помощью helperDownloadPandasetData
функция помощника, заданная в конце этого примера.
doTraining = false; outputFolder = fullfile(tempdir,'Pandaset'); lidarURL = ['https://ssd.mathworks.com/supportfiles/lidar/data/' ... 'Pandaset_LidarData.tar.gz']; helperDownloadPandasetData(outputFolder,lidarURL);
В зависимости от вашего Интернет-соединения может занять время процесс загрузки. Код приостанавливает выполнение MATLAB®, пока процесс загрузки не завершен. В качестве альтернативы можно загрузить набор данных на локальный диск с помощью веб-браузера и извлечь файл. Если вы делаете так, изменяете outputFolder
переменная в коде к местоположению загруженного файла.
Создайте datastore файла, чтобы загрузить файлы PCD от заданного пути с помощью pcread
функция.
path = fullfile(outputFolder,'Lidar'); lidarData = fileDatastore(path,'ReadFcn',@(x) pcread(x));
Загрузите 3-D метки ограничительной рамки объектов автомобиля и грузовика.
gtPath = fullfile(outputFolder,'Cuboids','PandaSetLidarGroundTruth.mat'); data = load(gtPath,'lidarGtLabels'); Labels = timetable2table(data.lidarGtLabels); boxLabels = Labels(:,2:3);
Отобразите облако полной точки наблюдения.
figure ptCld = read(lidarData); ax = pcshow(ptCld.Location); set(ax,'XLim',[-50 50],'YLim',[-40 40]); zoom(ax,2.5); axis off;
reset(lidarData);
Данные PandaSet состоят из облаков полной точки наблюдения. В данном примере обрежьте облака полной точки наблюдения к облакам точек вида спереди с помощью стандартных параметров [1]. Эти параметры решают, что размер входа передал сети. Выбирание меньшей области значений облаков точек вдоль x, y, и оси z помогает обнаружить объекты, которые более близки началу координат, и также уменьшает полное учебное время сети.
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. % Calculate the dimensions for the pseudo-image. Xn = round(((xMax - xMin) / xStep)); Yn = round(((yMax - yMin) / yStep)); % Define point cloud parameters. pointCloudRange = [xMin,xMax,yMin,yMax,zMin,zMax]; voxelSize = [xStep,yStep];
Используйте cropFrontViewFromLidarData
функция помощника, присоединенная к этому примеру как вспомогательный файл, к:
Обрежьте вид спереди от входного облака полной точки наблюдения.
Выберите метки поля, которые являются в ROI, заданном gridParams
.
[croppedPointCloudObj,processedLabels] = cropFrontViewFromLidarData(...
lidarData,boxLabels,pointCloudRange);
Processing data 100% complete
Отобразите обрезанное облако точек и метки основного блока истинности с помощью helperDisplay3DBoxesOverlaidPointCloud
функция, определяемая помощника в конце примера.
pc = croppedPointCloudObj{1,1}; gtLabelsCar = processedLabels.Car{1}; gtLabelsTruck = processedLabels.Truck{1}; helperDisplay3DBoxesOverlaidPointCloud(pc.Location,gtLabelsCar,... 'green',gtLabelsTruck,'magenta','Cropped Point Cloud');
reset(lidarData);
Разделите набор данных в наборы обучающих данных и наборы тестов. Выберите 70% данных для того, чтобы обучить сеть и остальных для оценки.
rng(1); shuffledIndices = randperm(size(processedLabels,1)); idx = floor(0.7 * length(shuffledIndices)); trainData = croppedPointCloudObj(shuffledIndices(1:idx),:); testData = croppedPointCloudObj(shuffledIndices(idx+1:end),:); trainLabels = processedLabels(shuffledIndices(1:idx),:); testLabels = processedLabels(shuffledIndices(idx+1:end),:);
Так, чтобы можно было легко получить доступ к хранилищам данных, сохраните обучающие данные как файлы PCD при помощи saveptCldToPCD
функция помощника, присоединенная к этому примеру как вспомогательный файл. Можно установить writeFiles
к "false"
если ваши обучающие данные сохраняются в папке и поддерживаются pcread
функция.
writeFiles = true; dataLocation = fullfile(outputFolder,'InputData'); [trainData,trainLabels] = saveptCldToPCD(trainData,trainLabels,... dataLocation,writeFiles);
Processing data 100% complete
Создайте datastore файла с помощью fileDatastore
загружать файлы PCD с помощью pcread
функция.
lds = fileDatastore(dataLocation,'ReadFcn',@(x) pcread(x));
Поле Createa помечает datastore с помощью boxLabelDatastore
для загрузки 3-D меток ограничительной рамки.
bds = boxLabelDatastore(trainLabels);
Используйте combine
функционируйте, чтобы объединить облака точек и 3-D метки ограничительной рамки в один datastore для обучения.
cds = combine(lds,bds);
Этот пример использует увеличение достоверных данных и несколько других методов увеличения глобальных данных, чтобы добавить больше разнообразия в обучающие данные и соответствующие поля. Для получения дополнительной информации о типичных методах увеличения данных, используемых в 3-D рабочих процессах обнаружения объектов с данными о лидаре, смотрите Увеличения Данных для Обнаружения объектов Лидара Используя Глубокое обучение.
Считайте и отобразите облако точек перед увеличением с помощью helperDisplay3DBoxesOverlaidPointCloud
функция помощника, заданная в конце примера..
augData = read(cds); augptCld = augData{1,1}; augLabels = augData{1,2}; augClass = augData{1,3}; labelsCar = augLabels(augClass=='Car',:); labelsTruck = augLabels(augClass=='Truck',:); helperDisplay3DBoxesOverlaidPointCloud(augptCld.Location,labelsCar,'green',... labelsTruck,'magenta','Before Data Augmentation');
reset(cds);
Используйте sampleGroundTruthObjectsFromLidarData
функция помощника, присоединенная к этому примеру как вспомогательный файл, чтобы извлечь все ограничительные рамки основной истины из обучающих данных.
classNames = {'Car','Truck'}; sampleLocation = fullfile(tempdir,'GTsamples'); [sampledGTData,indices] = sampleGroundTruthObjectsFromLidarData(cds,classNames,... 'MinPoints',20,'sampleLocation',sampleLocation);
Используйте augmentGroundTruthObjectsToLidarData
функция помощника, присоединенная к этому примеру как вспомогательный файл, чтобы случайным образом добавить постоянное число объектов класса автомобиля и грузовика к каждому облаку точек. Используйте transform
функция, чтобы применить основную истину и пользовательские увеличения данных к обучающим данным.
numObjects = [10,10];
cdsAugmented = transform(cds,@(x) augmentGroundTruthObjectsToLidarData(x,...
sampledGTData,indices,classNames,numObjects));
Кроме того, примените следующие увеличения данных к каждому облаку точек.
Случайное зеркальное отражение вдоль оси X
Случайное масштабирование на 5 процентов
Случайное вращение вдоль оси z от [-pi/4, пи/4]
Случайный перевод [0.2, 0.2, 0.1] метры вдоль x-, y-, и ось z соответственно
cdsAugmented = transform(cdsAugmented,@(x) augmentData(x));
Отобразитесь увеличенное облако точек наряду с основной истиной увеличило поля с помощью helperDisplay3DBoxesOverlaidPointCloud
функция помощника, заданная в конце примера.
augData = read(cdsAugmented); augptCld = augData{1,1}; augLabels = augData{1,2}; augClass = augData{1,3}; labelsCar = augLabels(augClass=='Car',:); labelsTruck = augLabels(augClass=='Truck',:); helperDisplay3DBoxesOverlaidPointCloud(augptCld.Location,labelsCar,'green',... labelsTruck,'magenta','After Data Augmentation');
reset(cdsAugmented);
Используйте pointPillarsObjectDetector
функция, чтобы автоматически создать сеть обнаружения объектов PointPillars. Сеть PointPillars использует упрощенную версию сети PointNet, которая берет функции столба в качестве входа. Для каждой функции столба сеть применяет линейный слой, сопровождаемый слоями ReLU и нормализацией партии. Наконец, сеть применяет макс. объединяющую операцию по каналам, чтобы получить высокоуровневые закодированные функции. Эти закодированные функции рассеиваются назад к исходным местоположениям столба, чтобы создать псевдоизображение. Сеть затем обрабатывает псевдоизображение с 2D сверточной магистралью, сопровождаемой различными головами обнаружения SSD, чтобы предсказать 3-D ограничительные рамки наряду с его классами.
Сеть PointPillars, существующая в детекторе PointPillars, проиллюстрирована в следующей схеме.
Можно использовать Deep Network Designer (Deep Learning Toolbox), чтобы создать сеть, показанную в схеме.
pointPillarsObjectDetector
функция требует, чтобы вы задали несколько входных параметров, которые параметрируют сеть PointPillars:
Имена классов
Поля привязки
Область значений облака точек
Размер вокселя
Количество видных столбов
Число точек на столб
% Define number of prominent pillars. P = 12000; % Define number of points per pillar. N = 100; % Estimate anchor boxes from training data. anchorBoxes = calculateAnchorsPointPillars(trainLabels); classNames = trainLabels.Properties.VariableNames; % Define the PointPillars detector. detector = pointPillarsObjectDetector(pointCloudRange,classNames,anchorBoxes,... 'VoxelSize',voxelSize,'NumPillars',P,'NumPointsPerPillar',N);
Если больше управления требуется по архитектуре сети PointPillars, можно спроектировать сеть вручную. Для получения дополнительной информации см. Проект Сеть PointPillars.
Задайте сетевые параметры обучения с помощью trainingOptions
. Установите 'CheckpointPath'
к временному местоположению, чтобы позволить сохранить частично обученных детекторов во время учебного процесса. Если обучение прервано, можно возобновить обучение с сохраненной контрольной точки.
Обучите детектор с помощью центрального процессора или графического процессора. Используя графический процессор требует Parallel Computing Toolbox™, и CUDA® включил NVIDIA® графический процессор. Для получения дополнительной информации смотрите Поддержку графического процессора Релизом (Parallel Computing Toolbox). Чтобы автоматически обнаружить, если вы имеете графический процессор в наличии, установите executionEnvironment
к "auto"
. Если вы не имеете графического процессора или не хотите использовать один для обучения, устанавливать executionEnvironment
к "cpu"
. Чтобы гарантировать использование графического процессора для обучения, установите executionEnvironment
к "gpu"
.
executionEnvironment = "auto"; if canUseParallelPool dispatchInBackground = true; else dispatchInBackground = false; end options = trainingOptions('adam',... 'Plots',"none",... 'MaxEpochs',60,... 'MiniBatchSize',3,... 'GradientDecayFactor',0.9,... 'SquaredGradientDecayFactor',0.999,... 'LearnRateSchedule',"piecewise",... 'InitialLearnRate',0.0002,... 'LearnRateDropPeriod',15,... 'LearnRateDropFactor',0.8,... 'ExecutionEnvironment',executionEnvironment,... 'DispatchInBackground',dispatchInBackground,... 'BatchNormalizationStatistics','moving',... 'ResetInputNormalization',false,... 'CheckpointPath',tempdir);
Используйте trainPointPillarsObjectDetector
функция, чтобы обучить детектор объектов PointPillars, если doTraining
верно. В противном случае загрузите предварительно обученный детектор.
if doTraining [detector,info] = trainPointPillarsObjectDetector(cdsAugmented,detector,options); else pretrainedDetector = load('pretrainedPointPillarsDetector.mat','detector'); detector = pretrainedDetector.detector; end
Используйте обучивший сеть, чтобы обнаружить объекты в тестовых данных:
Считайте облако точек из тестовых данных.
Запустите детектор в облаке тестовой точки, чтобы получить предсказанные ограничительные рамки и оценки достоверности.
Отобразите облако точек с ограничительными рамками с помощью helperDisplay3DBoxesOverlaidPointCloud
функция помощника, заданная в конце примера.
ptCloud = testData{45,1}; gtLabels = testLabels(45,:); % Specify the confidence threshold to use only detections with % confidence scores above this value. confidenceThreshold = 0.5; [box,score,labels] = detect(detector,ptCloud,'Threshold',confidenceThreshold); boxlabelsCar = box(labels'=='Car',:); boxlabelsTruck = box(labels'=='Truck',:); % Display the predictions on the point cloud. helperDisplay3DBoxesOverlaidPointCloud(ptCloud.Location,boxlabelsCar,'green',... boxlabelsTruck,'magenta','Predicted Bounding Boxes');
Оцените обученный детектор объектов на большом наборе данных об облаке точек, чтобы измерить уровень.
numInputs = 50; % Generate rotated rectangles from the cuboid labels. bds = boxLabelDatastore(testLabels(1:numInputs,:)); groundTruthData = transform(bds,@(x) createRotRect(x)); % Set the threshold values. nmsPositiveIoUThreshold = 0.5; confidenceThreshold = 0.25; detectionResults = detect(detector,testData(1:numInputs,:),... 'Threshold',confidenceThreshold); % Convert to rotated rectangles format for calculating metrics for i = 1:height(detectionResults) box = detectionResults.Boxes{i}; detectionResults.Boxes{i} = box(:,[1,2,4,5,7]); end metrics = evaluateDetectionAOS(detectionResults,groundTruthData,... nmsPositiveIoUThreshold); disp(metrics(:,1:2))
AOS AP _______ _______ Car 0.89735 0.89735 Truck 0.758 0.758
function helperDownloadPandasetData(outputFolder,lidarURL) % Download the data set from the given URL to the output folder. lidarDataTarFile = fullfile(outputFolder,'Pandaset_LidarData.tar.gz'); if ~exist(lidarDataTarFile,'file') mkdir(outputFolder); disp('Downloading PandaSet Lidar driving data (5.2 GB)...'); websave(lidarDataTarFile,lidarURL); untar(lidarDataTarFile,outputFolder); end % Extract the file. if (~exist(fullfile(outputFolder,'Lidar'),'dir'))... &&(~exist(fullfile(outputFolder,'Cuboids'),'dir')) untar(lidarDataTarFile,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] Ленг, Алекс Х., Sourabh Vora, Хольгер Цезарь, Лубин Чжоу, Цзюн Ян и Оскар Бейджбом. "PointPillars: Быстрые Энкодеры для Обнаружения объектов От Облаков точек". На 2019 Конференциях IEEE/CVF по Компьютерному зрению и Распознаванию образов (CVPR), 12689-12697. Лонг-Бич, CA, США: IEEE, 2019. https://doi.org/10.1109/CVPR.2019.01298.
[2] Hesai и Scale. PandaSet. https://scale.com/open-datasets/pandaset.