主要内容

利用PointPillars深度学习的激光雷达三维目标检测

这个例子展示了如何训练point柱子网络来检测点云中的对象。

激光雷达点云数据可以通过各种激光雷达传感器获取,包括Velodyne®、Pandar和Ouster传感器。这些传感器捕获场景中物体的3d位置信息,这对于自动驾驶和增强现实中的许多应用非常有用。然而,由于每个对象的数据稀疏性、对象遮挡和传感器噪声,使用点云数据训练健壮的检测器具有挑战性。深度学习技术已被证明可以通过直接从点云数据中学习健壮的特征表示来解决许多这些挑战。一种用于三维对象检测的深度学习技术是PointPillars [1].PointPillars网络使用与PointNet类似的架构,从称为柱子的稀疏点云中提取密集、健壮的特征,然后使用带有改进的SSD对象检测网络的2-D深度学习网络来估计联合的3-D边界框、方向和类预测。

下载激光雷达数据集

这个例子使用了PandaSet的一个子集[2],包含2560个预处理过的有组织的点云。每个点云覆盖 360 o 视图,并指定为64 × 1856矩阵。点云以PCD格式存储,其对应的地面真实数据存储在PandaSetLidarGroundTruth.mat文件。该文件包含三个类别的3-D包围框信息,即汽车、卡车和行人。数据集的大小为5.2 GB。

方法从给定的URL下载Pandaset数据集helperDownloadPandasetDataHelper函数,在本例的末尾定义。

doTraining = false;outputFolder = fullfile(tempdir,“Pandaset”);lidarURL = [“https://ssd.mathworks.com/金宝appsupportfiles/lidar/data/”...“Pandaset_LidarData.tar.gz”];helperDownloadPandasetData (outputFolder lidarURL);

根据您的互联网连接,下载过程可能需要一些时间。该代码暂停MATLAB®执行,直到下载过程完成。或者,您可以使用web浏览器将数据集下载到本地磁盘并提取文件。如果这样做,请更改outputFolder变量中指定下载文件的位置。下载的文件包含激光雷达长方体而且semanticLabels分别存放点云、长方体标签和语义标签信息的文件夹

加载数据

方法创建一个文件数据存储以从指定路径加载PCD文件pcread函数。

path = fullfile(outputFolder,激光雷达的);lidarData = fileDatastore(路径,“ReadFcn”@ (x) pcread (x));

加载汽车和卡车对象的3-D包围框标签。

gtPath = fullfile(outputFolder,“长方体”“PandaSetLidarGroundTruth.mat”);data = load(gtPath,“lidarGtLabels”);标签= timeable2table (data.lidarGtLabels);boxLabels = Labels(:,2:3);

显示全视图点云。

figure ptCld = read(lidarData);ax = pcshow(ptCld.Location);集(ax,“XLim”50 [-50],“YLim”, 40 [-40]);变焦(ax, 2.5);轴

重置(lidarData);

数据进行预处理

PandaSet数据由全视图点云组成。对于本例,使用标准参数[将全视图点云裁剪为前视图点云[1].这些参数决定了传递到网络的输入的大小。沿着x、y和z轴选择一个较小的点云范围,以检测更接近原点的对象。这也减少了网络的整体训练时间。

xMin = 0.0;沿x轴的最小值。yMin = -39.68;y轴上的最小值。zMin = -5.0;z轴上的最小值。xMax = 69.12;沿x轴的最大值。yMax = 39.68;沿y轴的最大值。zMax = 5.0;沿z轴的最大值。xStep = 0.16;%沿x轴分辨率。yStep = 0.16;%分辨率沿y轴。dsFactor = 2.0;%下采样因子。计算伪图像的尺寸。Xn = round(((xMax - xMin)/xStep));Yn = round((yMax - yMin)/yStep));定义点云参数。pointCloudRange = [xMin xMax yMin yMax zMin zMax];voxelSize = [xStep yStep];

使用cropFrontViewFromLidarDataHelper函数,作为支持文件附加到本示例,用于:金宝app

  • 从输入的全视图点云中裁剪正面视图。

  • 所指定的ROI内的框标签gridParams

[croppedPointCloudObj, procsedlabels] = cropFrontViewFromLidarData(...lidarData、boxLabels pointCloudRange);
处理数据100%完成

控件显示裁剪后的点云和地面真值框标签helperDisplay3DBoxesOverlaidPointCloud在示例末尾定义的Helper函数。

pc = croppedPointCloudObj{1,1};gtLabelsCar = processedLabels.Car{1};gtLabelsTruck = processedLabels.Truck{1};helperDisplay3DBoxesOverlaidPointCloud (pc。位置、gtLabelsCar...“绿色”gtLabelsTruck,“红色”“裁剪点云”);

重置(lidarData);

创建用于培训的数据存储对象

将数据集分成训练集和测试集。选择70%的数据进行网络训练,其余数据进行评估。

rng (1);shuffledIndices = randperm(size(processedLabels,1));idx =地板(0.7 *长度(shuffledIndices));trainData = croppedPointCloudObj(shuffledIndices(1:idx),:);testData = croppedPointCloudObj(shuffledIndices(idx+1:end),:);trainLabels = processedLabels(shuffledIndices(1:idx),:);testLabels = processedLabels(shuffledIndices(idx+1:end),:);

,将训练数据保存为PCD文件,以便方便地访问数据存储saveptCldToPCDHelper函数,作为支持文件附加到本示例中。金宝app你可以设置writefile错误的”方法支持的文件夹中保存培训数据金宝apppcread函数。

writeFiles = true;dataLocation = fullfile(outputFolder,“InputData”);[trainData,trainLabels] = saveptCldToPCD(trainData,trainLabels,...dataLocation, writefile);
处理数据100%完成

创建文件数据存储使用fileDatastore来加载PCD文件pcread函数。

lds = fileDatastore(数据位置,“ReadFcn”@ (x) pcread (x));

创建一个框标签数据存储使用boxLabelDatastore用于加载三维包围框标签。

bds = boxLabelDatastore(trainLabels);

使用结合函数将点云和3-D包围框标签组合到单个数据存储中进行训练。

CDS = combine(lds,bds);

数据增加

本例使用地面真相数据增强和其他几种全局数据增强技术,为训练数据和相应框添加更多的多样性。有关在使用激光雷达数据的3-D对象检测工作流程中使用的典型数据增强技术的更多信息,请参阅基于深度学习的激光雷达目标检测数据增强

控件进行扩展之前,读取并显示点云helperDisplay3DBoxesOverlaidPointCloudHelper函数,定义在示例的末尾..

augData = read(cds);augptCld = augData{1,1};augLabels = augData{1,2};augClass = augData{1,3};labelsCar = augLabels(augClass==“汽车”:);labelsTruck = augLabels(augClass==“卡车”:);helperDisplay3DBoxesOverlaidPointCloud (augptCld。位置、labelsCar“绿色”...labelsTruck,“红色”“数据增强之前”);

重置(cds);

使用sampleLidarData函数从训练数据中对三维包围框及其对应点进行采样。

classNames = {“汽车”“卡车”};sampleLocation = fullfile(输出文件夹,“GTsamples”);[ldsSampled,bdsSampled] = sampleLidarData(cd,classNames, classNames,“MinPoints”, 20岁,...“详细”假的,“WriteLocation”, sampleLocation);cdsSampled = combine(ldsSampled,bdsSampled);

使用pcBboxOversample函数随机向每个点云添加固定数量的汽车和卡车类对象。使用变换函数将地面真相和自定义数据增强应用到训练数据。

numObjects = [10 10];cdsAugmented = transform(cds,@(x) pcbboxoverample (x,cdsSampled,classNames,numObjects));

将这些额外的数据增强技术应用于每个点云。

  • 沿着x轴随机翻转

  • 随机缩放5%

  • 沿z轴从[-pi/4, pi/4]开始随机旋转

  • 随机平移[0.2,0.2,0.1]米沿x-, y-和z轴分别

cdsAugmented = transform(cdsAugmented,@(x)augmentData(x));

控件显示增强点云和地面真相增强方框helperDisplay3DBoxesOverlaidPointCloudHelper函数,在示例的末尾定义。

augData = read(cdsAugmented);augptCld = augData{1,1};augLabels = augData{1,2};augClass = augData{1,3};labelsCar = augLabels(augClass==“汽车”:);labelsTruck = augLabels(augClass==“卡车”:);helperDisplay3DBoxesOverlaidPointCloud (augptCld。位置、labelsCar“绿色”...labelsTruck,“红色”“数据增强后”);

重置(cdsAugmented);

创建PointPillars对象检测器

使用pointPillarsObjectDetector函数来创建point柱子对象检测网络。有关point柱子网络的更多信息,请参见开始使用point柱子

该图显示了point柱子对象检测器的网络体系结构。您可以使用深度网络设计器(深度学习工具箱)应用程序创建PointPillars网络。

PPNetwork.png

pointPillarsObjectDetector函数要求您指定几个参数化point柱子网络的输入:

  • 类名

  • 锚箱

  • 点云范围

  • 体素的大小

  • 突出柱子数量

  • 每个支柱的点数

定义突出柱子的数量。P = 12000;定义每个支柱的点数。N = 100;

利用训练数据估计锚框calculateAnchorsPointPillarsHelper函数,作为支持文件附加到本示例中。金宝app

anchorBoxes = calculateAnchorsPointPillars(trainLabels);classNames = trainLabels.Properties.VariableNames;

定义PointPillars检测器。

检测器= pointPillarsObjectDetector(pointCloudRange,classNames,anchorBoxes,...“VoxelSize”voxelSize,“NumPillars”、磷、“NumPointsPerPillar”N);

训练顶点对象检测器

属性指定网络训练参数trainingOptions(深度学习工具箱)函数。集“CheckpointPath”到一个临时位置,以便在训练过程中保存部分训练过的检测器。如果训练中断,您可以从保存的检查点恢复训练。

使用CPU或GPU训练检测器。使用GPU需要并行计算工具箱™和支持CUDA®的NVIDIA®GPU。有关更多信息,请参见GPU计算要求(并行计算工具箱).若要自动检测是否有可用的GPU,请设置executionEnvironment“汽车”.如果您没有GPU,或者不想使用GPU进行训练,请设置executionEnvironment“cpu”.为确保使用图形处理器进行训练,请设置executionEnvironment“图形”

executionEnvironment =“汽车”如果canUseParallelPool dispatchInBackground = true;其他的dispatchInBackground = false;结束选项= trainingOptions(“亚当”...“阴谋”“没有”...“MaxEpochs”现年60岁的...“MiniBatchSize”3,...“GradientDecayFactor”, 0.9,...“SquaredGradientDecayFactor”, 0.999,...“LearnRateSchedule”“分段”...“InitialLearnRate”, 0.0002,...“LearnRateDropPeriod”15岁的...“LearnRateDropFactor”, 0.8,...“ExecutionEnvironment”executionEnvironment,...“DispatchInBackground”dispatchInBackground,...“BatchNormalizationStatistics”“移动”...“ResetInputNormalization”假的,...“CheckpointPath”, tempdir);

使用trainPointPillarsObjectDetector函数来训练PointPillars对象检测器doTraining是“真正的”。否则,加载一个预训练的检测器。

如果doTraining [detector,info] = trainPointPillarsObjectDetector(cdsAugmented,detector,options);其他的预训练检测器=负载(“pretrainedPointPillarsDetector.mat”“探测器”);检测器=预训练的检测器;结束

生成检测

使用训练好的网络检测测试数据中的对象:

  • 从测试数据中读取点云。

  • 在测试点云上运行检测器以获得预测的边界框和置信度分数。

  • 控件显示带有包围框的点云helperDisplay3DBoxesOverlaidPointCloudHelper函数,在示例的末尾定义。

ptCloud = testData{45,1};gtLabels = testLabels(45,:);指定仅使用检测的置信阈值%置信度得分高于此值。confidenceThreshold = 0.5;[box,score,labels] = detect(检测器,ptCloud,“阈值”, confidenceThreshold);boxlabelsCar = box(标签==“汽车”:);boxlabelsTruck = box(标签==“卡车”:);在点云上显示预测结果。helperDisplay3DBoxesOverlaidPointCloud (ptCloud。位置、boxlabelsCar“绿色”...boxlabelsTruck,“红色”“预测边界框”);

使用测试集评估检测器

在大量点云数据集上评估训练好的目标检测器的性能。

numInputs = 50;从长方体标签生成旋转的矩形。bds = boxLabelDatastore(testLabels(1:numInputs,:));groundTruthData = transform(bds,@(x)createRotRect(x));%设置阈值。nmpositive iouthreshold = 0.5;confidenceThreshold = 0.25;detectionResults = detect(检测器,testData(1:numInputs,:),...“阈值”, confidenceThreshold);将包围框转换为旋转的矩形格式并计算评估指标。i = 1:height(detectionResults) box = detectionResults. boxes {i};detectionResults。Boxes{i} = box(:,[1,2,4,5,9]);结束metrics = evaluateDetectionAOS(detectionResults,groundTruthData,...nmsPositiveIoUThreshold);disp(指标(:,1:2))
AOS AP _______ _______轿车0.74377 0.75569卡车0.60989 0.61157

辅助函数

函数helperDownloadPandasetData (outputFolder lidarURL)从给定的URL下载数据集到输出文件夹。lidarDataTarFile = fullfile(输出文件夹,“Pandaset_LidarData.tar.gz”);如果~存在(lidarDataTarFile“文件”mkdir (outputFolder);disp (“正在下载熊猫激光雷达驾驶数据(5.2 GB)……”);websave (lidarDataTarFile lidarURL);解压(lidarDataTarFile outputFolder);结束提取文件。如果(~存在(fullfile (outputFolder激光雷达的),“dir”))...& & (~ (fullfile (outputFolder,存在“长方体”),“dir”)解压(lidarDataTarFile outputFolder);结束结束函数helperDisplay3DBoxesOverlaidPointCloud (ptCld labelsCar carColor,...labelsTruck、truckColor titleForFigure)%显示不同颜色包围框的点云%的类。图;ax = pcshow(ptCld);showShape (“长方体”labelsCar,“父”ax,“不透明度”, 0.1,...“颜色”carColor,“线宽”, 0.5);持有;showShape (“长方体”labelsTruck,“父”ax,“不透明度”, 0.1,...“颜色”truckColor,“线宽”, 0.5);标题(titleForFigure);变焦(ax, 1.5);结束

参考文献

[1] Lang, Alex H., Sourabh Vora, Holger Caesar,周陆兵,杨炯,Oscar Beijbom。PointPillars:用于点云对象检测的快速编码器在2019 IEEE/CVF计算机视觉和模式识别会议(CVPR), 12689 - 12697。美国加州长滩:IEEE, 2019。https://doi.org/10.1109/CVPR.2019.01298

Hesai和Scale。PandaSet。https://scale.com/open-datasets/pandaset