主要内容

代码生成激光雷达点云的分割网络

此示例显示如何为激光雷达语义分割的深度学习网络生成CUDA®MEX代码。此示例使用预训练的SqueezeSegV2[1]网络,该网络可以分割属于三类的有组织激光雷达点云(出身背景汽车卡车).有关网络培训程序的信息,请参见基于SqueezeSegV2深度学习网络的激光雷达点云语义分割(激光雷达工具箱).生成的MEX代码将点云作为输入,并使用DAGNetwork对象用于SqueezeSegV2网络。

第三方先决条件

要求的

这个例子生成CUDA MEX,并具有以下第三方要求。

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

可选

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

验证GPU环境

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

envcfg = coder.gpuenvconfig(“主持人”);envCfg。DeepLibTarget ='cudnn';envCfg.DeepCodegen=1;envCfg.Quiet=1;coder.checkGpuInstall(envCfg);

分段网络

SqueezeSegV2是专为举办激光雷达点云的语义分割卷积神经网络(CNN)。这是训练上的激光雷达数据集,并将其导入MATLAB®用于推断一个深编码器 - 解码器分割网络。在SqueezeSegV2,编码器子网由被穿插MAX-池层卷积层。这种安排先后减小输入图像的分辨率。解码器子网由一系列转置卷积层,其中连续地增加输入图像的分辨率。此外,SqueezeSegV2网络减轻丢失的数据通过包括上下文聚合模块(凸轮)的影响。甲CAM是卷积子网与值filterSize [7,7],其从较大的感受域,这提高了网络的缺少数据的鲁棒性的聚集体的上下文信息。该SqueezeSegV2网络在这个例子中被训练到属于三类(背景,汽车和卡车)分段点。

有关使用Mathworks激光雷达数据集在MATLAB®中训练语义分割网络的更多信息,请参阅基于PointSeg深度学习网络的激光雷达点云语义分割(激光雷达工具箱)

下载预训练挤压SEGV2网络。

net=getSqueezeSegV2Net();
下载预训练SqueezeSegV2(2 MB)...

DAG网络包含238层,包括卷积、ReLU和批量归一化层,以及焦点损失输出层。要显示深度学习网络架构的交互式可视化,请使用analyzeNetwork函数。

analyzeNetwork(净);

squeezesegv2_predict入口点函数

squeezesegv2_predict.m本例附带的入口点函数以点云为输入,利用存储在的深度学习网络对点云进行预测挤压SEGV2NET.mat文件。该函数从加载网络对象挤压SEGV2NET.mat文件到持久变量中mynet和重新使用在随后的预测呼叫的持久变量。

类型(“squeezesegv2_predict.m”);
功能输出=挤压SEGV2_预测(输入)%#codegen%mynet持久对象用于加载DAG网络对象。首次调用此函数时,%构造并设置持久对象。后续调用此函数时,%重用同一对象以调用predict on inputs,从而避免重新构建和%重新加载网络对象。%Copyright 2020MathWorks,Inc.持久mynet;如果isempty(mynet)mynet=coder.loadDeepLearningNetwork('SqueezeSegV2Net.mat');end%传入输出=预测(mynet,in);

生成CUDA MEX代码

的CUDA MEX代码squeezesegv2_predict.m入口点函数,用于创建一个MEX目标一个GPU代码配置对象和目标语言设置为C ++。使用coder.DeepLearningConfig(GPU编码器)函数来创建CuDNN的深度学习配置对象,并将其分配给DeepLearningConfig图形处理器代码配置对象的属性。运行codegen命令,指定输入大小[64,1024,5]。此值对应于SqueezeSegV2网络输入层的大小。

cfg = coder.gpuConfig (墨西哥人的);cfg。TargetLang =“c++”;cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn');codegen配置cfgsqueezesegv2_predictarg游戏{(64、1024、5、uint8)}-报告
代码生成成功:查看报告

为了产生CUDA C ++代码,需要NVIDIA TensorRT文库的优点,在代码中,指定coder.DeepLearningConfig(“tensorrt”)而不是coder.DeepLearningConfig(“cudnn”)

有关如何在Intel®处理器上为深度学习网络生成MEX代码的信息,请参阅基于MKL-DNN的深度学习网络代码生成(MATLAB编码器)

准备数据

在MATLAB®中加载一个有组织的测试点云。将点云转换为五通道图像进行预测。

ptCloud=pcread('ousterLidarDrivingData.pcd');I = pointCloudToImage (ptCloud);%检查转换的数据
名称大小字节类属性我64x1024x5 327680 UINT8

图像有五个通道。的(x, y, z)点坐标包括前三个通道。第四个通道包含激光雷达强度测量。第五个通道包含范围信息,计算为 r x 2 + y 2 + z 2

可视化图像的强度通道。

intensityChannel = I(:,:,4);图;imshow(intensityChannel);标题(“强度图像”);

在数据上运行生成的MEX

调用挤压SEGV2_预测_mex在五个通道图像。

predict_scores = squeezesegv2_predict_mex(I);

predict_scores变量是具有对应于每个类别的逐像素预测分数三个通道的三维矩阵。通过使用最大预测得分,以获得逐像素标签计算信道

[~,argmax]=max(预测分数,[],3);

将分割标签覆盖在“强度通道”图像上,并显示分割区域。调整分割输出的大小并添加颜色栏,以实现更好的可视化效果。

类别=[“背景”“汽车”“卡车”];提出= lidarColorMap ();SegmentedImage = labeloverlay (intensityChannel argmax,“颜色表”,cmap);分段图像=调整大小(分段图像,'规模',[2 1],'方法'“最近”);图;imshow (SegmentedImage);N =元素个数(类);蜱虫= 1 / (N * 2): 1 / N: 1;colorbar ('TickLabels',cellstr(类),“蜱”蜱虫,'TickLength',0,“TickLabelInterpreter”“没有”);彩色地图(cmap)标题(“语义分割结果”);

在点云序列上运行生成的MEX代码

读取输入的点云序列。该序列包含10个有组织的点云使用Ouster OS1激光雷达传感器采集的帧。输入数据的高度为64,宽度为1024,因此每个pointCloud对象的大小为64 * 1024。

数据文件=“highwaySceneData.mat”%在工作空间中加载数据。负载(功能);

设置不同的颜色以可视化不同兴趣类别的逐点标签。

给汽车涂上红色。carClassCar =零(64,1024,3,“uint8”);carClassCar(:,: 1) = 255*ones(64, 1024, 1)“uint8”);将蓝色应用于卡车。truckClassColor = 0 (64, 1024, 3,)“uint8”);truckClassColor(:,:,3)= 255吨*酮(64,1024,“uint8”);给背景添加灰色。backgroundClassColor=153*个,“uint8”);

设置pcplayer函数属性以显示序列和输出预测。逐帧读取输入序列并使用模型检测感兴趣的类。

xlimits = [0 120.0]。ylimits = [-80.7 80.7];zlimits = [-8.4 27];玩家= pcplayer(xlimits,ylimits,zlimits);集(得到(player.Axes,“父”),'单位'“归一化”'outerposition',[0 0 1 1]);放大(获得(player.Axes,“父”), 2);集(球员。轴,“XColor”“没有”'YColor'“没有”'ZColor'“没有”);i=1:numel(inputData)ptCloud=inputData{i};%将点云转换为五通道图像进行预测。I = pointCloudToImage (ptCloud);%在5通道图像上调用squeezesegv2_predict_mex。predict_scores = squeezesegv2_predict_mex(I);%转换数字输出值分类标签。[~, predictedOutput] = max (predict_scores [], 3);predictedOutput = categorical(predictedOutput, 1:3, classes);%从标签中提取索引。carIndices = predictedOutput =='车';truckIndices = predictedOutput =='卡车';backgrounddindices = predictedOutput ==“背景”为每个类提取一个点云。carPointCloud = select(ptCloud, carIndices,“OutputSize”“满”);truckPointCloud = select(ptCloud, truckIndices,“OutputSize”“满”);backgroundPointCloud =选择(ptCloud,backgroundIndices,“OutputSize”“满”);%填充颜色到不同的类。carPointCloud。颜色= carClassCar;truckPointCloud。颜色= truckClassColor;backgroundPointCloud。颜色= backgroundClassColor;%合并并添加所有处理过的带有类信息的点云。colorred = pcmerge(carPointCloud, truckPointCloud, 0.01);coloredCloud = pcmerge(coloredCloud, backgroundPointCloud, 0.01);%查看输出。视图(播放器,coloredCloud);的DrawNow;结束

辅助函数

下面是本示例中使用的helper函数。

类型pointCloudToImage.m
功能图像= pointCloudToImage(ptcloud)%pointCloudToImage将转换组织3-d点云到5通道%2-d的图像。图像= ptcloud.Location;图像(:,:,4)= ptcloud.Intensity;rangeData = iComputeRangeData(图像(:,:,1),图像(:,:,2),图像(:,:,3));图像(:,:,5)= rangeData;%施法至UINT8。图像= UINT8(图像);结尾 % -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  ---------------------------功能rangeData = iComputeRangeData(xChannel广告,yChannel,zChannel)rangeData = SQRT(xChannel广告。* xChannel广告+ yChannel。* yChannel+ zChannel * zChannel)。结束
类型lidarColorMap.m
功能CMAP = lidarColorMap()CMAP = [0.00 0.00 0.00%0.98背景0.00 0.00%车0.00 0.00 0.98%卡车];结束

工具书类

[1]吴碧晨,周旋宇,赵思成,岳翔宇,库尔特·库泽。“从激光雷达点云分割道路目标的改进模型结构和无监督域适应”。预印本,2018年9月22日提交。http://arxiv.org/abs/1809.08495。