主要内容

基于pointnet++深度学习的航空激光雷达语义分割代码生成

此示例演示如何为pointnet++[生成CUDA®MEX代码]1]网络用于激光雷达语义分割。这个例子使用了一个预先训练过的pointnet++网络,它可以分割属于8类(建筑物、汽车、卡车、电线杆、电线、栅栏、地面和植被)的无组织激光雷达点云。有关pointnet++网络的更多信息,请参见从pointnet++开始(激光雷达工具箱)

第三方的先决条件

要求

  • CUDA支持NVIDIA®GPU和兼容的驱动程序。

可选

对于非mex构建,如静态库、动态库或可执行程序,此示例具有以下附加要求。

验证GPU环境

要验证用于运行此示例的编译器和库是否已正确设置,请使用coder.checkGpuInstall函数。

envCfg = coder.gpuEnvConfig (“主机”);envCfg。DeepLibTarget =“cudnn”;envCfg。DeepCodegen = 1;envCfg。安静= 1;coder.checkGpuInstall (envCfg);

负载PointNet + +网络

使用getPointnetplusNet函数,该函数作为支持文件附加到这个示例中,用于加载预先训练的pointnet++网络。有关如何训练这个网络的更多信息,请参见基于pointnet++深度学习的航空激光雷达语义分割(激光雷达工具箱)的例子。

网= getPointnetplusNet;

预训练网络是DAG网络。要显示网络体系结构的交互式可视化,请使用analyzeNetwork(深度学习工具箱)函数。

的采样和分组层以及插值层实现functionLayer(深度学习工具箱)函数。这两个pointCloudInputLayerfunctionLayer函数不支持代码生成。对于代码生成支持,用自定义层和pointCloudInputLayerimageInputLayer通过使用helperReplaceInputAndFunctionLayersHelper函数,作为支持文件附加到本示例中。这个函数将网络保存为带有名称的MAT文件pointnetplusCodegenNet.mat

网= helperReplaceInputAndFunctionLayers(净);

pointnetplusPredict入口点函数

pointnetplusPredict入口点函数以点云数据矩阵为输入,利用存储在的深度学习网络对其进行预测pointnetplusCodegenNet.mat文件。对象加载网络对象pointnetplusCodegenNet.mat文件到一个持久变量mynet并在后续的预测调用中重用持久变量。

类型(“pointnetplusPredict.m”);
持久对象mynet用于加载DAG网络对象。第一次调用此函数时,构造持久对象并设置%。当该函数随后被调用时,相同的对象%被重用以在输入上调用predict,从而避免重构和%重新加载网络对象。版权所有The MathWorks, Inc.持久mynet;if isempty(mynet) mynet = code . loaddeeplearningnetwork ('pointnetplusCodegenNet.mat');End %传入输入输出= predict(mynet,in);

生成CUDA MEX代码

生成CUDA®代码pointnetplusPredict入口点函数,为MEX目标创建一个GPU代码配置对象,并将目标语言设置为c++。使用编码器。DeepLearningConfig函数来创建一个CuDNN深度学习配置对象,并将其分配给DeepLearningConfig属性的图形处理器代码配置对象。运行codegen命令,使用网络输入层的点云数据大小,在本例中为[8192 1 3]。

cfg = coder.gpuConfig (墨西哥人的);cfg。TargetLang =“c++”;cfg。DeepLearningConfig =编码器。DeepLearningConfig(TargetLibrary=“cudnn”);codegen配置cfgpointnetplusPredictarg游戏{randn(8192, 1, 3,“单”)}报告
代码生成成功:查看报告

要为TensorRT目标生成CUDA®代码,请创建并使用TensorRT深度学习配置对象,而不是CuDNN配置对象。

利用生成的MEX代码分割空中点云

本例中的网络在DALES数据集上进行训练[2].按照上面的说明山谷网站下载数据集到指定的文件夹dataFolder变量。创建一个文件夹来存储测试数据。

dataFolder = fullfile (tempdir,“山谷”);testDataFolder = fullfile (dataFolder,“dales_las”“测试”);

DALES数据集中的每个点云覆盖面积为500 × 500米,比地面激光雷达点云的典型覆盖面积大得多。方法将点云划分为小的、不重叠的块,以实现高效的内存处理blockedPointCloud(激光雷达工具箱)对象。

方法定义块尺寸blockSize参数。由于数据集中每个点云的大小不同,将块的z维设置为避免沿z轴创建块。

blockSize = [51 51 Inf];

首先,创建一个blockedPointCloud(激光雷达工具箱)对象。然后,创建一个blockedPointCloudDatastore(激光雷达工具箱)对象对测试数据进行处理blockedPointCloud(激光雷达工具箱)对象。

tbpc = blockedPointCloud (fullfile (testDataFolder5080 _54470.las), blockSize);tbpcds = blockedPointCloudDatastore (tbpc);

定义用于训练网络的参数。有关更多详细信息,请参见基于pointnet++深度学习的航空激光雷达语义分割(激光雷达工具箱)的例子。

numNearestNeighbors = 20;半径= 0.05;numPoints = 8192;maxLabel = 1;一会= [“地面”“植物”“汽车”“卡车”“电线”“篱笆”“两极”“建筑”];numClasses =元素个数(类名);

初始化预测标签和目标标签的占位符。

labelsDensePred = [];labelsDenseTarget = [];

对测试数据应用与训练数据相同的转换,tbpcds,遵循以下步骤。

  • 提取点云。

  • 下采样点云到指定的数量,numPoints

  • 将点云归一化到范围[0 1]。

  • 转换点云,使其与网络的输入层兼容。

对测试点云数据进行推理,计算预测标签。对稀疏点云的标签进行预测pointnetplusPredict_mex函数。然后对稀疏点云的预测标签进行插值,得到密集点云的预测标签,并在所有不重叠的块上迭代此过程。

hasdata (tbpcds)与块信息一起读取块。[ptCloudDense, infoDense] =阅读(tbpcds);从块信息中提取标签。labelsDense = infoDense.PointAttributes.Classification;只选择有标签的数据。ptCloudDense =选择(ptCloudDense {1}, labelsDense ~ = 0);labelsDense = labelsDense (labelsDense ~ = 0);使用helperDownsamplePoints函数,附加到本例中作为的支持文件中提取下采样点云密集的点云。ptCloudSparse = helperDownsamplePoints (ptCloudDense,...labelsDense numPoints);%使密集点云的空间范围等于稀疏点云%点云。限制= [ptCloudDense.XLimits; ptCloudDense.YLimits ptCloudDense.ZLimits];ptCloudSparseLocation = ptCloudSparse.Location;: ptCloudSparseLocation(1:2) =限制(:1:2)';ptCloudSparse = pointCloud (ptCloudSparseLocation,颜色= ptCloudSparse。的颜色,...= ptCloudSparse强度。强度、正常= ptCloudSparse.Normal);使用附加到本例中的helperNormalizePointCloud函数%一个支持文件,以规范化0到1之间的点云。ptCloudSparseNormalized = helperNormalizePointCloud (ptCloudSparse);ptCloudDenseNormalized = helperNormalizePointCloud (ptCloudDense);使用在本文末尾定义的helperTransformToTestData函数%示例,以将点云转换为单元格数组并排列%的维度,以使其与输入层兼容%的网络。ptCloudSparseForPrediction = helperTransformToTestData (ptCloudSparseNormalized);%获得输出预测。scoresPred = pointnetplusPredict_mex(单(ptCloudSparseForPrediction {1 1}));[~, labelsSparsePred] = max (scoresPred [], 3);labelsSparsePred = uint8 (labelsSparsePred);使用helperInterpolate函数,附加到这个例子中作为%的支持文件,计算密集点云的标签,%使用稀疏点云和稀疏点云上预测的标签。interpolatedLabels = helperInterpolate (ptCloudDenseNormalized,...ptCloudSparseNormalized、labelsSparsePred numNearestNeighbors,...半径,maxLabel numClasses);连接块中的预测标签和目标标签。labelsDensePred = vertcat (labelsDensePred interpolatedLabels);labelsDenseTarget = vertcat (labelsDenseTarget labelsDense);结束
使用“Processes”配置文件启动并行池(parpool)…连接到并行池(工作人员数量:6)。

为了更好地可视化,请显示从点云数据推断出的单个块。

图;ax = pcshow (ptCloudDense.Location interpolatedLabels);轴;helperLabelColorbar (ax,类名);标题(“用检测到的语义标签覆盖点云”);

支持功能

helperLabelColorbar函数向当前轴添加一个颜色条。颜色栏被格式化为显示带有颜色的类名。

函数helperLabelColorbar (ax,类名)% Colormap用于原始类。提出= [[0,0255);(0255,0);[255192203];(255255,0);(255、0255);(255165,0);(139、0150);(255, 0, 0)];提出255 = cmap. /;提出=提出(1:元素个数(类名):); colormap(ax,cmap);为当前图形添加颜色条。c = colorbar (ax);c.Color =' w '%将标记标记居中,并使用类名作为标记。numClasses = size(classNames, 1);c.Ticks = 1:1: numClasses;c.TickLabels =一会;%移除勾标记。c.TickLength = 0;结束

helperTransformToTestData函数将点云转换为单元格数组,并排列点云的维度以使其与网络的输入层兼容。

函数data = helperTransformToTestData(数据)如果~iscell(data) data = {data};结束numObservations =大小(数据,1);i = 1:numObservations tmp = data{i,1}.Location;Data {i,1} = permute(tmp,[1 3 2]);结束结束

参考文献

祁,查尔斯R.,李毅,郝苏,和列奥尼达J.古巴人。pointnet++:度量空间中点集的深度层次特征学习。ArXiv: 1706.02413 (Cs)2017年6月7日。https://arxiv.org/abs/1706.02413

瓦尼,妮娜,维贾扬·k·阿萨里,奎恩·格雷林。DALES:用于语义分割的大规模航空激光雷达数据集。ArXiv: 2004.11985 (Cs,统计)2020年4月14日。https://arxiv.org/abs/2004.11985

另请参阅

功能

对象

相关的话题

Baidu
map