使用PointPillars深度学习的激光雷达三维目标检测
这个例子展示了如何训练PointPillars网络用于点云中的目标检测。
激光雷达点云数据可以通过各种激光雷达传感器获取,包括Velodyne®,Pandar和Ouster传感器。这些传感器捕获场景中物体的三维位置信息,这对自动驾驶和增强现实中的许多应用都很有用。然而,由于每个物体的数据稀疏性、物体遮挡和传感器噪声,用点云数据训练健壮的检测器是具有挑战性的。深度学习技术已经被证明可以通过直接从点云数据中学习鲁棒的特征表示来解决许多这些挑战。一种用于三维物体检测的深度学习技术是PointPillars [1]。使用与PointNet类似的架构,PointPillars网络从称为柱子的稀疏点云中提取密集、鲁棒的特征,然后使用二维深度学习网络和改进的SSD对象检测网络来估计联合的三维边界框、方向和类别预测。
这个例子使用了PandaSet [2来自Hesai和Scale的数据集。PandaSet包含使用Pandar64传感器捕获的各种城市场景的8240个无组织激光雷达点云扫描。该数据集为18个不同的对象类(包括汽车、卡车和行人)提供了3-D边界框标签。
下载激光雷达数据集
这个例子使用了PandaSet的一个子集,其中包含2560个经过预处理的有组织的点云。每个点云覆盖
,被指定为64 × 1856矩阵。点云以PCD格式存储,其对应的地面真值数据存储在PandaSetLidarGroundTruth.mat
文件。该文件包含三个类(汽车、卡车和行人)的3-D边界框信息。数据集的大小为5.2 GB。
从给定的URL下载Pandaset数据集helperDownloadPandasetData
Helper函数,在本示例末尾定义。
doTraining = false;outputFolder = fullfile(tempdir,“Pandaset”);lidarURL = [“https://ssd.mathworks.com/万博1manbetxsupportfiles/lidar/data/”…“Pandaset_LidarData.tar.gz”];helperDownloadPandasetData (outputFolder lidarURL);
根据您的互联网连接,下载过程可能需要一些时间。该代码将暂停MATLAB®的执行,直到下载过程完成。或者,您可以使用web浏览器将数据集下载到本地磁盘并提取文件。如果这样做,请更改outputFolder
变量转换为下载文件的位置。
加载数据
创建一个文件数据存储,以便从指定路径加载PCD文件pcread
(计算机视觉工具箱)函数。
path = fullfile(输出文件夹,激光雷达的);lidarData = fileDatastore(路径,“ReadFcn”@ (x) pcread (x));
加载汽车和卡车对象的3-D边界框标签。
gtPath = fullfile(输出文件夹,“长方体”,“PandaSetLidarGroundTruth.mat”);data = load(gtPath,“lidarGtLabels”);label = timeable2table (data. lidartlabels);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];
使用cropFrontViewFromLidarData
辅助函数,作为支持文件附加到本例中,用于:万博1manbetx
从输入的全视图点云裁剪前视图。
指定的ROI内的框标签
gridParams
.
[croppedPointCloudObj,processedLabels] = 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 = floor(0.7 * length(shuffledindiices));trainData = croppedPointCloudObj(shuffledIndices(1:idx),:);testData = croppedPointCloudObj(shuffledIndices(idx+1:end),:);trainLabels = processedLabels(shuffledindiices (1:idx),:);testLabels = processedLabels(shuffledindiices (idx+1:end),:);
将训练数据保存为PCD文件,以便您可以轻松访问数据存储库saveptCldToPCD
辅助函数,作为支持文件附加到此示例。万博1manbetx你可以设置writefile
“错误的”
如果您的训练数据保存在文件夹中,并且由万博1manbetxpcread
函数。
writeFiles = true;dataLocation = fullfile(输出文件夹,“InputData”);[trainData,trainLabels] = saveptCldToPCD(trainData,trainLabels,…dataLocation, writefile);
数据处理100%完成
使用创建文件数据存储fileDatastore
来加载PCD文件pcread
(计算机视觉工具箱)函数。
lds = fileDatastore(数据位置,“ReadFcn”@ (x) pcread (x));
使用创建一个框标签数据存储boxLabelDatastore
(计算机视觉工具箱)用于加载3d边界框标签。
bds = boxLabelDatastore(trainLabels);
使用结合
函数将点云和三维边界框标签合并到单个数据存储中进行训练。
CDS = combine(ld,bds);
数据增加
本例使用真实数据增强和其他几种全局数据增强技术,为训练数据和相应的框增加更多的多样性。有关使用激光雷达数据的3d对象检测工作流程中使用的典型数据增强技术的详细信息,请参阅使用深度学习的激光雷达目标检测的数据增强(激光雷达工具箱).
在增强之前读取和显示点云helperDisplay3DBoxesOverlaidPointCloud
Helper函数,在示例末尾定义。
augData = read(cd);augptCld = augData{1,1};augLabels = augData{1,2};augClass = augData{1,3};labelsCar = augLabels(augClass== .“汽车”:);labelsTruck = augLabels(augClass== .“卡车”:);helperDisplay3DBoxesOverlaidPointCloud (augptCld。位置、labelsCar“绿色”,…labelsTruck,“红色”,“在数据增强之前”);
重置(cds);
使用sampleGroundTruthObjectsFromLidarData
辅助函数,作为支持文件附加到本例中,用于从训练数据中提取所有的基础真值边界框。万博1manbetx
classNames = {“汽车”,“卡车”};sampleLocation = fullfile(tempdir,“GTsamples”);[sampledGTData,indices] = sampleGroundTruthObjectsFromLidarData(cds,classNames,…“MinPoints”, 20岁,“sampleLocation”, sampleLocation);
使用augmentGroundTruthObjectsToLidarData
辅助函数,作为支持文件附加到此示例中,用于向每个点云随机添加固定数量的汽车和卡车类对象。万博1manbetx使用变换
函数将基础真值和自定义数据增强应用于训练数据。
numObjects = [10,10];cdsAugmented = transform(cds,@(x)) augmentGroundTruthObjectsToLidarData(x,…sampledGTData指数,一会,numObjects));
此外,对每个点云应用以下数据增强。
沿着x轴随机翻转
随机缩放5%
从[-pi/4, pi/4]沿z轴随机旋转
分别沿x、y、z轴随机平移[0.2,0.2,0.1]米
cdsAugmented = transform(cdsAugmented,@(x) augmentData(x));
显示增强点云以及地面真相增强框helperDisplay3DBoxesOverlaidPointCloud
Helper函数,在示例末尾定义。
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
(激光雷达工具箱)函数自动创建PointPillars对象检测网络。PointPillars网络使用了PointNet网络的简化版本,该网络将柱子的特征作为输入。对于每个支柱特征,网络应用一个线性层,然后是批处理归一化和ReLU层。最后,网络在通道上应用最大池化操作以获得高级编码特征。这些编码的特征被分散回原来的柱子位置,以创建伪图像。然后,该网络用二维卷积主干和各种SSD检测头处理伪图像,以预测三维边界框及其类别。
PointPillars检测器中的PointPillars网络如下图所示。
你可以用深度网络设计器创建如图所示的网络。
的pointPillarsObjectDetector
函数需要你指定几个参数化PointPillars网络的输入:
类名
锚箱
点云距离
体素的大小
突出支柱数量
每根柱子的点数
定义突出支柱的数量。P = 12000;定义每个支柱的点数。N = 100;%根据训练数据估计锚框。anchorBoxes = calculateAnchorsPointPillars(trainLabels);classNames = trainLabels.Properties.VariableNames;定义PointPillars检测器。检测器= pointPillarsObjectDetector(pointCloudRange,classNames,anchorBoxes,…“VoxelSize”voxelSize,“NumPillars”、磷、“NumPointsPerPillar”N);
如果需要对PointPillars网络体系结构进行更多的控制,您可以手动设计网络。有关更多信息,请参见设计PointPillars网络。
火车点柱对象检测器
指定网络训练参数trainingOptions
.集“CheckpointPath”
到一个临时地点,以便在训练过程中保存部分训练过的探测器。如果训练中断,您可以从保存的检查点恢复训练。
使用CPU或GPU训练检测器。使用GPU需要Parallel Computing Toolbox™和支持CUDA®的NVIDIA®GPU。有关更多信息,请参见不同版本万博1manbetx的GPU支持(并行计算工具箱).要自动检测是否有可用的GPU,请设置executionEnvironment
来“汽车”
.如果您没有GPU,或者不想使用GPU进行训练,请设置executionEnvironment
来“cpu”
.要确保使用GPU进行训练,请设置executionEnvironment
来“图形”
.
executionEnvironment =“汽车”;如果canUseParallelPool dispatchInBackground = true;其他的dispatchInBackground = false;结束options = 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 = load(“pretrainedPointPillarsDetector.mat”,“探测器”);检测器= pretraineddetector .检测器;结束
生成检测
使用训练好的网络检测测试数据中的对象:
从测试数据中读取点云。
在测试点云上运行检测器以获得预测的边界框和置信度分数。
显示带有边界框的点云
helperDisplay3DBoxesOverlaidPointCloud
Helper函数,在示例末尾定义。
ptCloud = testData{45,1};gtLabels = testLabels(45,:);指定仅使用检测的置信阈值%置信度得分高于此值。confidenceThreshold = 0.5;[box,score,labels] = detect(检测器,ptCloud,“阈值”, confidenceThreshold);boxlabelsCar = box(labels'==“汽车”:);boxlabelsTruck = box(labels'==“卡车”:);在点云上显示预测结果。helperDisplay3DBoxesOverlaidPointCloud (ptCloud。位置、boxlabelsCar“绿色”,…boxlabelsTruck,“红色”,“预测边界框”);
使用测试集评估检测器
在大量的点云数据集上对训练好的目标检测器进行评估,以衡量其性能。
numInputs = 50;从长方体标签生成旋转的矩形。bds = boxLabelDatastore(testLabels(1:numInputs,:));groundTruthData = transform(bds,@(x) createRotRect(x));%设置阈值。nmpositiveiouthreshold = 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,7]);结束metrics = evaluateDetectionAOS(detectionResults,groundTruthData,…nmsPositiveIoUThreshold);disp(指标(:,1:2))
《超能美联社 _______ _______ 汽车卡车0.89735 - 0.89735 0.758 - 0.758
辅助函数
函数helperDownloadPandasetData (outputFolder lidarURL)从给定的URL下载数据集到输出文件夹。lidarDataTarFile = fullfile(outputFolder,“Pandaset_LidarData.tar.gz”);如果~存在(lidarDataTarFile“文件”mkdir (outputFolder);disp (“下载PandaSet激光雷达驾驶数据(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(ptld);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。点柱:快速编码器从点云对象检测。在2019 IEEE/CVF计算机视觉与模式识别会议(CVPR), 12689 - 12697。长滩,CA, USA: IEEE, 2019。https://doi.org/10.1109/CVPR.2019.01298.
[2] Hesai和Scale。PandaSet。https://scale.com/open-datasets/pandaset.