使用PointPillars深度学习的激光雷达三维物体检测
这个例子展示了如何训练PointPillars网络在点云中进行对象检测。
激光雷达点云数据可由多种激光雷达传感器获取,包括Velodyne®、Pandar和Ouster传感器。这些传感器捕获场景中物体的三维位置信息,这对自动驾驶和增强现实中的许多应用都很有用。然而,由于每个物体的数据稀疏性、物体遮挡和传感器噪声,用点云数据训练鲁棒检测器具有挑战性。深度学习技术已经被证明可以通过直接从点云数据学习鲁棒特征表示来解决这些挑战。一种用于3d对象检测的深度学习技术是PointPillars [1]。使用与PointNet类似的架构,PointPillars网络从称为柱子的稀疏点云中提取密集、健壮的特征,然后使用二维深度学习网络和改进的SSD对象检测网络来估计联合三维边界盒、方向和类预测。
下载Lidar数据集
本例使用了PandaSet的一个子集[2包含2560个预处理过的有组织点云。每个点云覆盖
的视图,并指定为64 × 1856的矩阵。点云以PCD格式存储,其对应的地面真值数据存储在PandaSetLidarGroundTruth.mat
文件。该文件包含三个类别的3d边界框信息,分别是汽车、卡车和行人。数据集的大小为5.2 GB。
方法从给定的URL下载Pandaset数据集helperDownloadPandasetData
Helper函数,在本例末尾定义。
doTraining = false;outputFolder = fullfile (tempdir,“Pandaset”);lidarURL = [“https://ssd.mathworks.com/supportfiles/lidar/data/”…“Pandaset_LidarData.tar.gz”];helperDownloadPandasetData (outputFolder lidarURL);
根据你的网络连接情况,下载过程可能需要一些时间。该代码暂停MATLAB®的执行,直到下载过程完成。或者,您可以下载数据集到您的本地磁盘使用您的网络浏览器,并解压文件。如果您这样做,请更改outputFolder
变量的代码,以下载文件的位置。下载的文件包含激光雷达
,长方体
和semanticLabels
分别存放点云、长方体标签和语义标签信息的文件夹
加载数据
创建一个文件数据存储,从指定路径加载PCD文件使用pcread
函数。
路径= fullfile (outputFolder,激光雷达的);lidarData = fileDatastore(路径,“ReadFcn”@ (x) pcread (x));
加载汽车和卡车对象的3d边框标签。
gtPath = fullfile (outputFolder,“长方体”,“PandaSetLidarGroundTruth.mat”);data =负载(gtPath“lidarGtLabels”);标签= timetable2table (data.lidarGtLabels);boxLabels =标签(: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];
使用cropFrontViewFromLidarData
Helper函数,作为支持文件附在本例中,用于:
从输入的全视图点云中裁剪正面视图。
所指定的ROI内的框标签
gridParams
。
[croppedPointCloudObj, processedLabels] = cropFrontViewFromLidarData (…lidarData、boxLabels pointCloudRange);
数据处理100%完成
显示裁剪点云和地面真值框标签使用helperDisplay3DBoxesOverlaidPointCloud
在示例末尾定义的Helper函数。
电脑= croppedPointCloudObj {1};gtLabelsCar = processedLabels.Car {1};gtLabelsTruck = processedLabels.Truck {1};helperDisplay3DBoxesOverlaidPointCloud (pc。位置、gtLabelsCar…“绿色”gtLabelsTruck,“红色”,“裁剪点云”);
重置(lidarData);
为训练创建数据存储对象
将数据集分为训练集和测试集。选择70%的数据用于训练网络,剩下的用于评估。
rng (1);shuffledIndices = randperm(大小(processedLabels, 1));idx = floor(0.7 * length(shuffledIndices));trainData = croppedPointCloudObj (shuffledIndices (1: idx):);testData = croppedPointCloudObj (shuffledIndices (idx + 1:结束):);trainLabels = processedLabels (shuffledIndices (1: idx):);testLabels = processedLabels (shuffledIndices (idx + 1:结束):);
的方法将训练数据保存为PCD文件,以便您可以轻松访问数据存储saveptCldToPCD
Helper函数,作为支持文件附加到本例中。你可以设置writefile
“错误的”
如果您的训练数据保存在文件夹中,并且得到pcread
函数。
writefile = true;dataLocation = fullfile (outputFolder,“InputData”);[trainData, trainLabels] = saveptCldToPCD (trainData trainLabels,…dataLocation, writefile);
数据处理100%完成
创建一个文件datastore使用fileDatastore
加载PCD文件使用pcread
函数。
像= fileDatastore (dataLocation,“ReadFcn”@ (x) pcread (x));
创建一个框标签数据存储使用boxLabelDatastore
用于加载3-D边界框标签。
bds = boxLabelDatastore (trainLabels);
使用结合
函数将点云和3-D边界框标签合并到单个数据存储中进行训练。
cd =结合(摩门教,bds);
数据增加
本例使用了ground truth数据增强和其他几种全局数据增强技术,为训练数据和相应的方框添加了更多的多样性。有关使用激光雷达数据的三维物体检测工作流程中使用的典型数据增强技术的更多信息,请参见基于深度学习的激光雷达目标检测数据增强。
的增强之前,读取并显示一个点云helperDisplay3DBoxesOverlaidPointCloud
Helper函数,在示例末尾定义..
augData =阅读(cds);augptCld = augData {1};augLabels = augData {1,2};augClass = augData {1,3};labelsCar = augLabels (augClass = =“汽车”:);labelsTruck = augLabels (augClass = =“卡车”:);helperDisplay3DBoxesOverlaidPointCloud (augptCld。位置、labelsCar“绿色”,…labelsTruck,“红色”,“之前数据增强”);
重置(cds);
使用sampleLidarData
函数从训练数据中采样3-D边界框及其对应点。
一会= {“汽车”,“卡车”};sampleLocation = fullfile (outputFolder,“GTsamples”);[ldsSampled, bdsSampled] = sampleLidarData (cd,一会,“MinPoints”, 20岁,…“详细”假的,“WriteLocation”, sampleLocation);cdsSampled =结合(ldsSampled bdsSampled);
使用pcBboxOversample
函数向每个点云随机添加固定数量的汽车和卡车类对象。使用变换
函数,用于将ground truth和自定义数据增强应用到训练数据。
numObjects = [10 10];cdsAugmented =变换(cd, @ (x) pcBboxOversample (x, cdsSampled,一会,numObjects));
将这些额外的数据增强技术应用到每一个点云上。
沿x轴随机翻转
随机缩放5%
沿z轴从[-pi/4, pi/4]随机旋转
分别沿x-、y-、z轴随机平移[0.2、0.2、0.1]米
cdsAugmented =变换(cdsAugmented @ (x) augmentData (x));
显示一个增强的点云和地面真理增强框使用helperDisplay3DBoxesOverlaidPointCloud
Helper函数,在示例末尾定义。
augData =阅读(cdsAugmented);augptCld = augData {1};augLabels = augData {1,2};augClass = augData {1,3};labelsCar = augLabels (augClass = =“汽车”:);labelsTruck = augLabels (augClass = =“卡车”:);helperDisplay3DBoxesOverlaidPointCloud (augptCld。位置、labelsCar“绿色”,…labelsTruck,“红色”,数据增加的);
重置(cdsAugmented);
创建point柱子对象检测器
使用pointPillarsObjectDetector
函数来创建point柱子对象检测网络。有关point柱子网络的更多信息,请参见切入点柱的入门。
该图显示了point柱子对象检测器的网络架构。您可以使用深层网络设计师(深度学习工具箱)创建PointPillars网络的应用程序。
的pointPillarsObjectDetector
函数要求你指定几个参数化PointPillars网络的输入:
类名
锚箱
点云的范围
体素的大小
突出支柱的数量
每个支柱的点数
%定义突出柱子的数量。P = 12000;定义每个支柱的点数。N = 100;
从训练数据使用中估计锚盒calculateAnchorsPointPillars
Helper函数,作为支持文件附加到本例中。
anchorBoxes = calculateAnchorsPointPillars (trainLabels);一会= trainLabels.Properties.VariableNames;
定义point柱子检测器。
探测器= pointPillarsObjectDetector (anchorBoxes pointCloudRange,类名,…“VoxelSize”voxelSize,“NumPillars”、磷、“NumPointsPerPillar”N);
训练point柱子对象检测器
,指定网络训练参数trainingOptions
(深度学习工具箱)函数。集“CheckpointPath”
到一个临时位置,以启用在训练过程中保存部分训练的检测器。如果训练中断,可以从保存的检查点恢复训练。
使用CPU或GPU训练检测器。使用GPU需要并行计算工具箱™和CUDA®支持的NVIDIA®GPU。有关更多信息,请参见GPU计算的需求(并行计算工具箱)。若要自动检测是否有可用的GPU,请设置executionEnvironment
来“汽车”
。如果没有GPU,或者不想使用GPU进行训练,设置executionEnvironment
来“cpu”
。为保证使用GPU进行训练,设置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);其他的pretrainedDetector =负载(“pretrainedPointPillarsDetector.mat”,“探测器”);探测器= pretrainedDetector.detector;结束
生成检测
使用训练过的网络来检测测试数据中的对象:
从测试数据中读取点云。
在测试点云上运行检测器,得到预测的边界框和置信度分数。
控件显示带边界框的点云
helperDisplay3DBoxesOverlaidPointCloud
Helper函数,在示例末尾定义。
45 ptCloud = testData {1};gtLabels = testLabels(45岁);%指定仅使用检测的置信阈值% confidence得分高于此值。confidenceThreshold = 0.5;(盒、分数、标签)=检测(ptCloud探测器,“阈值”, confidenceThreshold);boxlabelsCar(标签' = = =框“汽车”:);boxlabelsTruck(标签' = = =框“卡车”:);%在点云上显示预测。helperDisplay3DBoxesOverlaidPointCloud (ptCloud。位置、boxlabelsCar“绿色”,…boxlabelsTruck,“红色”,“预测边界框”);
使用Test集评估检测器
在大量点云数据上对训练过的目标检测器进行评估,以衡量其性能。
numInputs = 50;%从长方体标签生成旋转的矩形。bds = boxLabelDatastore (testLabels (1: numInputs,:));groundTruthData =变换(bds, @ (x) createRotRect (x));%设置阈值。nmsPositiveIoUThreshold = 0.5;confidenceThreshold = 0.25;detectionResults =检测(探测器,testData (1: numInputs,:)…“阈值”, confidenceThreshold);%将边框转换为旋转矩形格式并计算评价指标。。为i = 1:height(detectionResults) box = detectionResults. boxes {i};detectionResults。盒子我{}=盒(:,(1、2、4、5、9]);结束指标= evaluateDetectionAOS (detectionResults groundTruthData,…nmsPositiveIoUThreshold);disp(指标(:,1:2))
AOS AP _______ _______ Car 0.74377 0.75569 Truck 0.60989 0.61157
辅助函数
函数helperDownloadPandasetData (outputFolder lidarURL)%从给定URL下载数据集到输出文件夹。lidarDataTarFile = fullfile (outputFolder,“Pandaset_LidarData.tar.gz”);如果~存在(lidarDataTarFile“文件”mkdir (outputFolder);disp (“下载PandaSet Lidar驾驶数据(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。《point柱子:用于点云物体检测的快速编码器》。在2019 IEEE/CVF计算机视觉和模式识别会议(CVPR), 12689 - 12697。美国加利福尼亚州长滩:IEEE, 2019。https://doi.org/10.1109/CVPR.2019.01298。
[2] Hesai和Scale。PandaSet。https://scale.com/open-datasets/pandaset。