基于Complex-YOLO v4网络的激光雷达目标检测
这个例子展示了如何训练Complex-YOLO v4网络在点云上执行对象检测。
Complex-YOLO [1]方法是一种有效的激光雷达目标检测方法,因为它直接作用于由点云转换而来的鸟瞰RGB地图。在本例中,使用Complex-YOLO方法训练一个YOLO v4 [2的网络来预测二维盒子的位置和鸟瞰图框架中的方向。然后将二维位置和方向预测投影到点云上,以生成感兴趣对象周围的三维边界框。
下载激光雷达数据集
此示例使用了pandset数据集的一个子集[3.包含2560个预处理过的有组织点云。每个点云覆盖360度视角,指定为64 × 1856矩阵。点云以PCD格式存储,其对应的地面真相数据存储在PandaSetLidarGroundTruth.mat
文件。该文件包含三个类的3d边界框信息,分别是汽车、卡车和行人。数据集的大小为5.2 GB。
方法从给定的URL下载pandset数据集helperDownloadPandasetData
Helper函数,在本例末尾定义。
outputFolder = fullfile (tempdir,“Pandaset”);lidarURL = [“https://ssd.mathworks.com/supportfiles/lidar/data/”...“Pandaset_LidarData.tar.gz”];helperDownloadPandasetData (outputFolder lidarURL);
根据您的网络连接情况,下载过程可能需要一些时间。该代码暂停MATLAB®的执行,直到下载过程完成。或者,您可以使用web浏览器将数据集下载到您的本地磁盘并解压缩文件。如果这样做,请更改outputFolder
变量设置为下载文件的位置。下载文件包含激光雷达
,长方体
,semanticLabels
文件夹,其中分别包含点云、长方体标签信息和语义标签信息。
下载Pretrained模型
这个例子实现了复杂YOLO v4对象检测器的两个变体:
complex-yolov4-pandaset
-在pandset数据集的点云生成的鸟瞰图上训练的标准复杂YOLO v4网络tiny-complex-yolov4-pandaset
-轻量级复杂YOLO v4网络训练的鸟瞰图像生成的pandset数据集的点云
经过预先训练的网络针对三种对象类别进行训练:汽车、卡车和行人。
modelName =“tiny-complex-yolov4-pandaset”;mdl = downloadPretrainedComplexYOLOv4 (modelName);网= mdl.net;
加载数据
方法创建文件数据存储以从指定路径加载PCD文件pcread
函数。
路径= fullfile (outputFolder,激光雷达的);lidarData = fileDatastore(路径,“ReadFcn”@ (x) pcread (x));
加载汽车、卡车和行人对象的3-D边界框标签。
gtPath = fullfile (outputFolder,“长方体”,“PandaSetLidarGroundTruth.mat”);data =负载(gtPath“lidarGtLabels”);标签= timetable2table (data.lidarGtLabels);boxLabels =标签(:,2:结束);
显示全视图点云。
图ptCld = read(lidarData);ax = pcshow (ptCld.Location);集(ax,“XLim”50 [-50],“YLim”, 40 [-40]);变焦(ax, 2.5);轴从;
从点云数据创建鸟瞰图
pandset数据由全视图点云组成。对于本例,将裁剪全视图点云,并使用标准参数将它们转换为鸟瞰图像。这些参数决定了传递到网络的输入的大小。沿着x、y和z轴选择较小范围的点云可以帮助您检测更接近原点的对象。
xMin = -25.0;xMax = 25.0;yMin = 0.0;yMax = 50.0;zMin = -7.0;zMax = 15.0;
定义鸟瞰图的尺寸。您可以为鸟瞰图设置任何尺寸,但是preprocessData
Helper函数将其调整为网络输入大小。对于本例,网络输入大小为608 × 608。
bevHeight = 608;bevWidth = 608;
找到网格分辨率。
gridW = (yMax - yMin)/bevWidth;gridH = (xMax - xMin)/bevHeight;
定义网格参数。
yMin gridParams = {{xMin, xMax, yMax, zMin, zMax}, {bevWidth, bevHeight}, {gridW, gridH}};
方法将训练数据转换为鸟瞰图transformPCtoBEV
Helper函数,作为支持文件附加到本示例中。你可以设置writefile
来假
如果您的训练数据已经存在于outputFolder
.
writefile = true;如果writefile transformPCtoBEV (lidarData boxLabels、gridParams outputFolder);结束
为培训创建数据存储对象
创建一个用于加载鸟瞰图的数据存储。
dataPath公司= fullfile (outputFolder,“BEVImages”);imd = imageDatastore (dataPath公司);
创建一个用于加载地面真相框的数据存储。
labelPath = fullfile (outputFolder,“长方体”,“BEVGroundTruthLabels.mat”);负载(labelPath“processedLabels”);建筑物= boxLabelDatastore (processedLabels);
从训练数据中删除没有标签的数据。
(imd,建筑物)= removeEmptyData (imd,建筑物);
将数据集分为训练集和测试集,分别用于训练网络和评估网络。使用60%的数据用于训练集,其余用于测试。
rng (0);shuffledIndices = randperm(大小(imds.Files, 1));idx = floor(0.6 * length(shuffledIndices));
将图像数据存储分为训练集和测试集。
imdsTrain =子集(imd, shuffledIndices (1: idx));imdsTest =子集(imd, shuffledIndices (idx + 1:结束);
将框标签数据存储分为训练集和测试集。
bldsTrain =子集(建筑物,shuffledIndices (1: idx));bldsTest =子集(建筑物,shuffledIndices (idx + 1:结束);
组合图像和框标签数据存储。
trainData =结合(imdsTrain bldsTrain);testData =结合(imdsTest bldsTest);
使用validateInputDataComplexYOLOv4
Helper函数,作为支持文件附加到本示例中,用于检测:
图像格式无效或包含nan的示例
包含0、nan、inf或为空的边界框
缺少或非分类标签。
边界框的值必须是有限且正的,不能是nan。它们还必须在图像边界内,具有正的高度和宽度。
validateInputDataComplexYOLOv4 (trainData);validateInputDataComplexYOLOv4 (testData);
训练数据进行预处理
对培训数据进行预处理,为培训做好准备。的preprocessData
在示例末尾列出的Helper函数将以下操作应用于输入数据。
将图像调整为网络输入大小。
在[0 1]范围内缩放图像像素。
集
isRotRect
来真正的
返回旋转后的矩形。
networkInputSize = [608 608 3];isRotRect = true;preprocessedTrainingData =变换(trainData @(数据)preprocessData(数据、networkInputSize isRotRect));
读取预处理后的训练数据。
data =阅读(preprocessedTrainingData);
显示带有边框的图像。
我={1 1}数据;bbox ={1,2}数据;标签={1,3}数据;helperDisplayBoxes (bbox,标签);
重置数据存储。
重置(preprocessedTrainingData);
修改预训练的Complex-YOLO V4 Network
Complex-YOLO V4网络使用从训练数据中估计的锚盒来对数据集的类型有更好的初始估计,并帮助网络学习准确预测锚盒。
首先,因为训练图像的大小不同,所以使用变换
函数预处理训练数据并将所有图像调整为相同的大小。
指定锚的数量:
complex-yolov4-pandaset模型
-指定9个锚tiny-complex-yolov4-pandaset模型
-指定6个锚
为了再现性,设置随机种子。估计使用的锚框estimateAnchorBoxes
函数。你可以设置isRotRect
为false,因为旋转角度不是边界框估计锚点所必需的。有关锚框的更多信息,请参阅的“指定锚框”一节从YOLO v4开始.
rng(0) isRotRect = false;trainingDataForEstimation =变换(trainData @(数据)preprocessData(数据、networkInputSize isRotRect));numAnchors = 6;[anchorBoxes, meanIoU] = estimateAnchorBoxes (trainingDataForEstimation numAnchors)
anchorBoxes =6×222 51 10 11 23 58 26 63 25 54 16 23
meanIoU = 0.7951
为训练配置预训练模型configureComplexYOLOV4
函数。该函数配置YOLO v4模型的检测头,以预测角度回归以及边界框、对象性评分和分类评分。
这个函数返回修改后的层图、网络输出名称、重新排序的锚框和锚框掩码,以选择要在检测到的头中使用的锚框。分配给检测头的锚盒的大小对应于从检测头输出的特征图的大小。该函数对锚框进行重新排序,将大锚框分配给低分辨率的特征映射,将小锚框分配给高分辨率的特征映射。
指定用于培训的类名。。一会= {“汽车”“卡车”“Pedestrain”};[净,networkOutputs anchorBoxes] = configureComplexYOLOv4(网,一会,anchorBoxes modelName);
指定培训选项
指定这些培训选项。
设置代数为90。
将迷你批大小设置为8。当使用更小的批处理大小时,稳定的训练可以有更高的学习率。根据可用内存设置此值。
将学习率设置为0.001。
将预热周期设置为1000次迭代。它有助于在较高的学习率下稳定梯度。
将L2正则化因子设为0.001。
指定惩罚阈值为0.5。检测到的与ground truth重叠小于0.5的将被扣分。
初始化渐变的速度为[],SGDM使用它来存储渐变的速度。
maxEpochs = 90;miniBatchSize = 8;learningRate = 0.001;warmupPeriod = 1000;l2Regularization = 0.001;penaltyThreshold = 0.5;速度= [];
火车模型
如果有GPU,请使用GPU进行训练。使用GPU需要并行计算工具箱™和CUDA®支持的NVIDIA®GPU。有关支持的设备的信息,请参见GPU计算的需求(并行计算工具箱).
使用minibatchqueue
函数将预处理后的训练数据进行批量分解,并具有辅助函数createBatchData
,它将返回批处理图像和结合各自的类id的边界框。若要更快地提取用于训练的批数据,请设置dispatchInBackground
来真正的
使用平行池。
minibatchqueue
自动检测GPU是否可用。如果您没有GPU或不想使用GPU进行训练,请设置OutputEnvironment
参数cpu
.
如果canUseParallelPool dispatchInBackground = true;其他的dispatchInBackground = false;结束mbqTrain = minibatchqueue (preprocessedTrainingData 2...“MiniBatchSize”miniBatchSize,...“MiniBatchFcn”@(图片,盒子,标签)createBatchData(图片,盒子,标签,类名),...“MiniBatchFormat”,[“SSCB”,""),...“DispatchInBackground”dispatchInBackground,...“OutputCast”,["",“替身”]);
使用辅助功能创建训练进度图configureTrainingProgressPlotter。
最后,指定自定义训练循环。每一次迭代:
从
minibatchqueue
.如果没有数据,请重新设置minibatchqueue
和洗牌。评估模型的梯度使用
dlfeval
和modelGradients
支持函数,列在本例的末尾。为正则化的梯度应用一个权值衰减因子,以获得更健壮的训练。
方法根据迭代确定学习率
piecewiseLearningRateWithWarmup
支持功能。更新
网
参数使用sgdmupdate
函数。更新
状态
净参数与移动平均线。显示每次迭代的学习率、总损失和单个损失(盒子损失、对象损失和类损失)。使用这些值来解释每个迭代中各自的损失是如何变化的。例如,经过几次迭代后,盒损耗突然出现峰值,这意味着预测包含Inf值或nan。
更新训练进度图。
如果损失达到饱和状态,可以终止训练。
doTraining = false;如果doTraining迭代= 0;为学习率和小批丢失创建子图。无花果=图;[lossPlotter, learningRatePlotter] = configureTrainingProgressPlotter(图);%自定义训练循环。为epoch = 1:maxEpochs reset(mbqTrain);洗牌(mbqTrain);而(hasdata(mbqTrain))迭代=迭代+ 1;[XTrain, YTrain] =下一个(mbqTrain);使用dlfeval和% modelGradients函数。(渐变、州lossInfo) = dlfeval (@modelGradients,净、XTrain YTrain, anchorBoxes, penaltyThreshold, networkOutputs);%应用L2正则化。gradient = dlupdate(@(g,w) g + l2Regularization*w, gradient, net.Learnables);确定当前学习率值。currentLR = piecewiseLearningRateWithWarmup(迭代,时代、learningRate warmupPeriod, maxEpochs);使用SGDM优化器更新网络可学习参数。(净、速度)= sgdmupdate(净、渐变速度,currentLR);更新dlnetwork的状态参数。网=状态;%显示进展。如果国防部(迭代,10)= = 1 displayLossInfo(时代、迭代、currentLR lossInfo);结束用新点更新训练图。updatePlots (lossPlotter learningRatePlotter、迭代、currentLR lossInfo.totalLoss);结束结束其他的网= mdl.net;anchorBoxes = mdl.anchorBoxes;结束
若要通过扫描超参数值的范围来查找最佳训练选项,请使用深层网络设计师(深度学习工具箱)应用程序。
评估模型
计算机视觉工具箱™提供对象检测器评估功能,以测量常见指标,如平均精度(evaluateDetectionAOS
)用于旋转矩形。本例使用平均方向相似度(AOS)度量。AOS是用于测量旋转矩形检测的检测器性能的一个度量。这个指标提供了一个单一的数字,它结合了检测器做出正确分类(精度)的能力和检测器找到所有相关对象(召回)的能力。
创建一个表来保存返回的边界框、分数和标签%的探测器。结果=表(“大小”[0 3],...“VariableTypes”, {“细胞”,“细胞”,“细胞”},...“VariableNames”, {“盒子”,“分数”,“标签”});在测试集中的图像上运行检测器并收集结果。重置(testData)而hasdata (testData)读取数据存储并获取映像。data =阅读(testData);形象={1 1}数据;运行检测器。executionEnvironment =“汽车”;(bboxes、分数、标签)= detectComplexYOLOv4(净、图像、anchorBoxes一会,executionEnvironment);收集结果。台=表({bboxes},{},{}标签,“VariableNames”, {“盒子”,“分数”,“标签”});结果=[结果;(资源);结束使用平均精度度量来评估目标检测器。metrics = evaluateDetectionAOS(结果,testData)
指标=3×5表《超能美联社OrientationSimilarity精密召回 _______ _______ _____________________ _______________ _______________ 车0.83079 - 0.90904{7339×1双}{7339×1双}{7339×1双}卡车0.46622 - 0.48079{1134×1双}{1134×1双}{1134×1双}Pedestrain 0.6626 - 0.72495{3439×1双}{3439×1双}{3439×1双}
使用训练过的Complex-YOLO V4检测对象
利用网络进行目标检测。
读取数据存储。reset(testData) data = read(testData);%获取图像。我={1 1}数据;运行检测器。executionEnvironment =“汽车”;(bboxes、分数、标签)= detectComplexYOLOv4 (anchorBoxes,净,我一会,executionEnvironment);%显示输出。图helperDisplayBoxes(我bboxes标签);
方法将检测到的方框转移到点云transferbboxToPointCloud
Helper函数,作为支持文件附加到本示例中。
lidarTestData =子集(lidarData shuffledIndices (idx + 1:结束);ptCld =阅读(lidarTestData);[ptCldOut, bboxCuboid] = transferbboxToPointCloud (bboxes、gridParams ptCld);helperDisplayBoxes (ptCldOut、bboxCuboid、标签);
支持功能
模型梯度
这个函数modelGradients
将Complex-YOLO v4网络作为输入,这是一个小批量的输入数据XTrain
对应的地面真值框YTrain
,以及指定的惩罚阈值。它返回损失相对于可学习参数的梯度网
,对应的小批丢失信息,以及当前批的状态。
的modelGradients
函数通过执行这些操作计算总损失和梯度。
方法从输入批处理的图像中生成预测
complexYOLOv4Forward
方法。收集CPU上的预测以进行后处理。
将Complex-YOLO v4网格单元坐标的预测转换为边界框坐标,以便与地面真相数据进行比较。
使用转换后的预测和地面真实数据生成损失计算目标。生成边界框位置(x、y、宽度、高度、偏航)、对象置信度和类概率的目标。参见配套函数
generateComplexYOLOv4Targets
.利用支持函数计算预测边界盒坐标与目标盒坐标的均方误差
bboxOffsetLoss
,在示例的最后定义。利用支持函数计算预测对象置信度评分与目标对象置信度评分的二元交叉熵
objectnessLoss
,在示例的最后定义。利用支持函数计算预测对象类与目标的二元交叉熵
classConfidenceLoss
,在示例的最后定义。将总损失计算为所有损失的总和。
计算关于总损失的可学习变量的梯度。
函数[gradients,state,info] = modelGradients(net,XTrain,YTrain,anchors,penaltyThreshold,networkOutputs) inputImageSize = size(XTrain,1:2);在CPU中收集基本事实以进行后处理。。YTrain =收集(extractdata (YTrain));从网络中提取预测。。[YPredCell、州]= complexYOLOv4Forward(网络,XTrain networkOutputs,锚);收集CPU中的激活以进行后处理并提取dlarray数据。集合预测= cellfun(@ gather,YPredCell(:,1:8),“UniformOutput”、假);@ extractdata, gatheredforecasts,“UniformOutput”、假);%将预测从网格单元格坐标转换为框坐标。tiledAnchors = generateTiledAnchorsComplexYolov4 (gatheredPredictions(:, 2:5),锚);gatheredPredictions (:, 2:5) = applyAnchorBoxOffsetsComplexYolov4 (tiledAnchors, gatheredPredictions (:, 2:5) inputImageSize);从地面真实数据生成预测目标。。[boxTarget, objectnessTarget classTarget、objectMaskTarget boxErrorScale] = generateComplexYOLOv4Targets (gatheredPredictions、YTrain inputImageSize,锚,penaltyThreshold);%计算损失。boxLoss = bboxOffsetLoss(YPredCell(:,[2 3 9 10 6 7]),boxTarget,objectMaskTarget,boxErrorScale);objLoss = objectnessLoss (YPredCell (: 1), objectnessTarget, objectMaskTarget);clsLoss = classConfidenceLoss (YPredCell (:, 8), classTarget, objectMaskTarget);totalLoss = boxLoss + objLoss + clsLoss;信息。boxLoss = boxLoss;信息。objLoss = objLoss;信息。clsLoss = clsLoss; info.totalLoss = totalLoss;计算与损失相关的可学习变量的梯度。。梯度= dlgradient (totalLoss net.Learnables);结束
损失函数
计算包围框位置的均方误差。
函数boxLoss = bboxOffsetLoss(boxPredCell,boxDeltaTarget,boxMaskTarget,boxErrorScaleTarget) lossX = sum(cellfun(@(a,b,c,d) mse(a.*c.*d,b.*c.*d),boxPredCell(:,1),boxDeltaTarget(:,1),boxMaskTarget(:,1),boxErrorScaleTarget));lossY = sum(cellfun(@(a,b,c,d) mse(a.*c.*d,b.*c.*d),boxPredCell(:,2),boxDeltaTarget(:,2),boxMaskTarget(:,1),boxErrorScaleTarget));lossW = sum(cellfun(@(a,b,c,d) mse(a.*c.*d,b.*c.*d),boxPredCell(:,3),boxDeltaTarget(:,3),boxMaskTarget(:,1),boxErrorScaleTarget));lossH = sum(cellfun(@(a,b,c,d) mse(a.*c.*d,b.*c.*d),boxPredCell(:,4),boxDeltaTarget(:,4),boxMaskTarget(:,1),boxErrorScaleTarget));lossYaw1 = sum(cellfun(@(a,b,c,d) mse(a.*c.*d,b.*c.*d),boxPredCell(:,5),boxDeltaTarget(:,5),boxMaskTarget(:,1),boxErrorScaleTarget));lossYaw2 = sum(cellfun(@(a,b,c,d) mse(a.*c.*d,b.*c.*d),boxPredCell(:,6),boxDeltaTarget(:,6),boxMaskTarget(:,1),boxErrorScaleTarget));boxLoss = lossX +损耗+ lossW + lossH + lossYaw1 + lossYaw2;结束
计算类可信度分数的二元交叉熵损失。
函数clsLoss = classConfidenceLoss(classPredCell,classTarget,boxMaskTarget) clsLoss = sum(cellfun(@(a,b,c) crossentropy(a.*c,b.*c,“TargetCategories”,“独立”)、classPredCell classTarget boxMaskTarget (:, 3)));结束
计算二元交叉熵损失的目标评分。
函数objLoss = objectnessLoss(objectnessPredCell,objectnessDeltaTarget,boxMaskTarget) objLoss = sum(cellfun(@(a,b,c) crossentropy(a.*c,b.*c,“TargetCategories”,“独立”)、objectnessPredCell objectnessDeltaTarget boxMaskTarget (:, 2)));结束
数据进行预处理
函数data = preprocessData(数据、targetSize isRotRect)调整图像的大小,并将像素缩放到0和1之间。同时规模%对应的边界框。为ii = 1:size(data,1) I = data{ii,1};imgSize =大小(I);将单通道的输入图像转换为三个通道。如果numel(imgSize) < 3 I = repmat(I,1,1,3);结束bboxes = {ii, 2}数据;我= im2single (imresize(我targetSize (1:2)));规模= targetSize(1:2)。/ imgSize (1:2);bboxes = bboxresize (bboxes、规模);如果~isRotRect bboxes = bboxes(:,1:4);结束data(ii, 1:2) = {I,bboxes};结束结束函数[XTrain, YTrain] = createBatchData(数据、groundTruthBoxes groundTruthClasses一会)返回沿XTrain和批处理维度组合的图像%归一化边界框与YTrain中的classid连接。沿批处理尺寸连接图像。。XTrain =猫(4、数据{:1});从类名中获取类id。一会= repmat({分类(类名)},大小(groundTruthClasses));[~, classIndices] = cellfun (@ (a, b) ismember (a、b), groundTruthClasses,一会,“UniformOutput”、假);将标签索引和训练图像大小附加到缩放的边界框。%,并创建响应的单个单元格数组。combinedResponses = cellfun (@ (bbox, classid) [bbox, classid], groundTruthBoxes, classIndices,“UniformOutput”、假);len = max (cellfun (@ (x)大小(x, 1), combinedResponses));paddedBBoxes = cellfun(@(v) padarray(v,[len-size(v,1),0],0,“职位”)、combinedResponses“UniformOutput”、假);YTrain =猫(4,paddedBBoxes {: 1});结束
学习率表命令功能
函数currentLR = piecewiseLearningRateWithWarmup(迭代,时代、learningRate warmupPeriod, numEpochs)%分段elearningratewithwarmup函数计算当前基于迭代次数的学习率%。持续的warmUpEpoch;如果迭代< = warmupPeriod增加热身期间迭代次数的学习率。currentLR = learningRate *((迭代/ warmupPeriod) ^ 4);warmUpEpoch =时代;elseif迭代>= warmupPeriod && epoch < warmUpEpoch+floor(0.6*(numepoch -warmUpEpoch))热身期结束后,如果剩余课时数小于60%,则保持学习速率不变。currentLR = learningRate;elseifepoch >= warmUpEpoch+floor(0.6*(numepoch -warmUpEpoch)) && epoch < warmUpEpoch+floor(0.9*(numepoch -warmUpEpoch))%如果剩余的代数大于但小于60%%超过90%,则学习率乘以0.1。currentLR = learningRate * 0.1;其他的如果还剩下90%以上的时间,就把所学的内容加倍。%率0.01。currentLR = learningRate * 0.01;结束结束
效用函数
函数[lossPlotter, learningRatePlotter] = configureTrainingProgressPlotter (f)创建子图来显示损失和学习速率。图(f);clf次要情节(2,1,1);ylabel (学习速率的);包含(“迭代”);learningRatePlotter = animatedline;次要情节(2,1,2);ylabel (“全损”);包含(“迭代”);lossPlotter = animatedline;结束函数displayLossInfo(时代、迭代,currentLR lossInfo)显示每次迭代的丢失信息。disp (”时代:“+时代+" |迭代:"+迭代+“|学习率:”+ currentLR +..." |全损:"+双(收集(extractdata (lossInfo.totalLoss))) +..." |盒子丢失:"+双(收集(extractdata (lossInfo.boxLoss))) +..." |对象丢失:"+双(收集(extractdata (lossInfo.objLoss))) +..." |班级损失:"+双(收集(extractdata (lossInfo.clsLoss))));结束函数updatePlots (lossPlotter learningRatePlotter、迭代、currentLR totalLoss)更新损耗和学习率图。addpoints (lossPlotter、迭代、双(extractdata(收集(totalLoss))));addpoints (learningRatePlotter迭代,currentLR);drawnow结束函数helperDisplayBoxes (obj bboxes、标签)显示图像和点云上方的方框。。数字如果~ isa (obj,“pointCloud”) imshow(obj) shape =“矩形”;其他的pcshow (obj.Location);形状=“长方体”;结束showShape(形状,bboxes(标签= =“汽车”:)...“颜色”,“绿色”,“线宽”, 0.5);在;showShape(形状,bboxes(标签= =“卡车”:)...“颜色”,“红色”,“线宽”, 0.5);showShape(形状,bboxes(标签= =“Pedestrain”:)...“颜色”,“黄色”,“线宽”, 0.5);持有从;结束函数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);结束结束
参考文献
西蒙,马丁,斯特凡·米尔兹,卡尔·阿曼德,霍斯特·迈克尔·格罗斯。“Complex-YOLO:点云上的实时三维目标检测”。ArXiv: 1803.06199 (Cs)2018年9月24日。https://arxiv.org/abs/1803.06199.
伯奇科夫斯基,阿列克谢,王建尧,廖宏远。“yolo4:目标检测的最佳速度和精度”。ArXiv: 2004.10934 (Cs,套)2020年4月22日。https://arxiv.org/abs/2004.10934.
[3]PandaSet是由合赛和Scale提供的cc -, - 4.0许可证.