主要内容

使用激光雷达探测、分类和跟踪车辆

这个例子展示了如何使用安装在ego车辆上的激光雷达传感器捕获的激光雷达点云数据来检测、分类和跟踪车辆。本例中使用的激光雷达数据是从高速公路驾驶场景中记录的。在本例中,对点云数据进行分割以确定对象的类别PointSeg网络。采用联合概率数据关联(JPDA)跟踪器和交互式多模型滤波器对被检测车辆进行跟踪。

概述

感知模块在实现具有ADAS系统的车辆充分的自治方面发挥着重要作用。LIDAR和Camera是感知工作流程中的基本传感器。LIDAR擅长提取对象的精确深度信息,而相机会产生对对象分类有用的环境的丰富和详细信息。

本例主要包括以下几个部分:

  • 地平面分割

  • 语义分割

  • 定向边界盒装

  • 有跟踪方向的包围盒

该流程图概述了整个系统。

加载数据

激光雷达传感器以有组织格式或无组织格式生成点云数据。本例中使用的数据是使用Ouster OS1激光雷达传感器收集的。这种激光雷达产生有组织的点云,有64条水平扫描线。点云数据由三个通道组成,代表X-,y-, 和Z.点的坐标。每个通道的尺寸为64 × 1024。使用helper函数helperDownloadData下载数据并将其加载到MATLAB®工作空间。

注意:这个下载可能需要几分钟。

[ptClouds, pretrainedModel] = helperDownloadData;

地平面分割

本例采用了一种混合方法,使用segmentGroundFromLidarDatapcfitplane功能。首先,利用该方法估计地平面参数segmentGroundFromLidarData函数。将估计的接地面沿车辆的方向划分成条状,以适应飞机,利用pcfitplane功能上的每条。这种混合方法以分段的方式稳健地拟合地平面,并处理点云中的变化。

负载点云ptCloud = ptClouds {1};定义裁剪点云的ROIxlimit = [-30,30];Ylimit = [-12,12];zlimit = [-3,15];roi = [xlimit,ylimit,zlimit];%提取地面平面[nonGround、地面]= helperExtractGround (ptCloud roi);图;pcshowpair (nonGround、地面);传奇({{白}Nonground \颜色的“地面颜色\{白}”},“位置”“东北朝”);

语义分割

这个例子使用掠夺PointSeg网络模型。PointSeg是一个针对汽车、卡车和背景等对象类训练的端到端实时语义分割网络。网络的输出是一个掩码图像,每个像素都按其类标记。这个蒙版用于过滤点云中不同类型的对象。网络的输入是五通道图像,即X, y, z,强度和范围。有关网络或如何培训网络的更多信息,请参阅基于PointSeg深度学习网络的激光雷达点云语义分割的例子。

准备输入数据

helperPrepareData函数从加载的点云数据生成五通道数据。

加载并可视化一个样本框架帧= helperPrepareData (ptCloud);图;次要情节(5、1、1);显示亮度图像(帧(:,:1));标题(“X频道”);次要情节(5、1、2);显示亮度图像(帧(::2));标题('y频道');次要情节(5、1,3);显示亮度图像(帧(:,:,3));标题(“Z频道”);次要情节(5、1、4);显示亮度图像(帧(::4));标题(“强度通道”);次要情节(5、1、5);显示亮度图像(帧(::5));标题(“范围通道”);

对加载的预训练网络中的一帧进行前向推理。

如果~ ('网''var') net = pretrainedModel.net;结尾%定义类类= [“背景”“汽车”“卡车”];%定义颜色贴图lidarColorMap = [0.98 0.98 0.00 .%未知0.01 0.98 0.01汽车%绿色0.01 0.01 0.98蓝色的摩托车];向前跑传球pxdsResults = semanticseg(框架、网络);具有分段输出的%覆盖强度图像segmentedImage = labeloverlay (uint8(帧(:,:,4)),pxdsResults,“Colormap”,lidarcolormap,'透明度', 0.5);%显示结果图;imshow (segmentedImage);helperPixelLabelColorbar (lidarColorMap、类);

使用生成的语义掩码过滤包含卡车的点云。类似地,为其他类过滤点云。

truckIndices = pxdsResults ==“卡车”;TruckPointCloud = Select(非地,Truckindices,'输出'“全部”);%裁剪点云更好的显示croppedPtCloud =选择(ptCloud findPointsInROI (ptCloud roi));croppedTruckPtCloud =选择(truckPointCloud findPointsInROI (truckPointCloud roi));%显示地面和非地点图;pcshowpair(croppedptcloud,croppedtruckptcloud);传奇({{白}Nonvehicle \颜色的'\ color {white}车'},“位置”“东北朝”);

聚类和包围盒拟合

在提取不同目标类的点云后,利用该算法对目标进行欧氏聚类pcsegdist函数。为了将属于一个单个群集的所有点分组,作为群集获得的点云用作非应点的生长区域的种子点。使用findNearestNeighbors函数循环遍历所有点以增长区域。方法将提取的聚类拟合在l形包围盒中pcfitcuboid函数。当从自上而下的视图中看到,这些车辆的簇类似于字母L的形状。此功能有助于估计车辆的方向。面向边界盒拟合有助于估计物体的标题角度,这在路径规划和交通操纵等应用中有用。

簇的长方体边界也可以通过寻找每个方向上的最小和最大空间范围来计算。然而,该方法无法估计被检测车辆的方向。两种方法的区别如图所示。

[标签,numClusters] = pcsegdist (croppedTruckPtCloud, 1);%定义长方体参数Params = Zeros(0,9);为了numclusterindex = 1: numclusterincluster = label == clusterIndex;电脑=选择(croppedTruckPtCloud ptsInCluster);位置= pc.Location;Xl = (max(location(:,1)) - min(location(:,1)));Yl = (max(location(: 2)) - min(location(: 2)));Zl = (max(location(:,3)) - min(location(:,3)));%过滤小包围框如果尺寸(位置,1)*尺寸(位置,2)> 20 &&任何(任何(pc.location))&& xl> 1 && yl> 1 indices = zeros(0,1);ObjectPtCloud = PointCloud(位置);为了i = 1:大小(位置,1)指数(终端+ 1)= findNearestNeighbors (nonGround seedPoint 1);结尾去除重叠指数指数=独特(指标);适合方向的包围框Model = PCFitCuboid(选择(非基础,索引));参数(结束+ 1,:) = model.parameters;结尾结尾%显示点云和检测到的边界框图;pcshow(crocpedptcloud.location,crocpedptcloud.location(:,3));showshape(“长方体”参数,“颜色”“红色”“标签”“卡车”);

可视化设置

使用helperLidarObjectDetectionDisplay类以在一个窗口中可视化完整的工作流。可视化窗口的布局分为以下几部分:

  1. LIDAR系列图像:点云图像在2-D中作为范围图像

  2. 分段图像:检测到从具有强度图像或数据的第四频道覆盖的语义分段网络生成的标签

  3. 定向包围盒检测:带有定向包围盒的三维点云

  4. 顶视图:点云的顶视图与定向边界框

显示= helperLidarObjectDetectionDisplay;

遍历数据

HelperlidarobjectDetection.类是封装上述各节中提到的所有分割、聚类和包围盒拟合步骤的包装器。使用findDetections函数提取检测到的对象。

%初始化LIDAR对象检测器Lidardetector = Helperlidarobjecdetector(“模型”净,“XLimits”xLimit,...'ylimit',ylimit,“ZLimit”, zLimit);%准备5d激光雷达数据inputData = helperPrepareData (ptClouds);%设置可重复结果的随机数发生器S = rng (2018);%初始化显示初始化阶段(显示);numframes = numel(inputdata);为了数= 1:numFrames获取当前数据输入= inputData{数};rangeImage =输入(::5);从激光雷达数据中提取边界框[绑定盒,CoolarPtCloud,PointLabels] = DetectBbox(LidAdgetector,输入);用彩色点云更新显示updatePointCloud(显示、coloredPtCloud);%更新边界框updateBoundingBox()边界框(显示、大小);%更新分割图像updateSegmentedImage(显示、pointLabels rangeImage);drawnow ('limitrate');结尾

跟踪方向的包围盒

在本例中,您将使用联合概率数据关联(JPDA)跟踪器。的时间步DT.设置为0.1秒,因为数据集是以10赫兹捕获的。跟踪器的状态空间模型是基于带参数的长方体模型, [ X y Z. ϕ L. W. H ] .有关如何在激光雷达数据中跟踪边界框的更多细节,请参阅用激光雷达追踪车辆:从点云到轨迹表(传感器融合与跟踪工具箱)的例子。在本例中,类信息是使用ObjectAttributes财产的objectDetection对象.在创建新曲目时,使用helper函数定义的过滤器初始化函数Helpermulticlassinitimmfilter使用检测类来设置对象的初始尺寸。这有助于跟踪器调整边界盒测量模型与适当的尺寸的轨道。

用这些参数建立一个JPDA跟踪器对象。

[10 100];%赋值阈值;Confthreshold = [7 10];%历史逻辑的确认阈值delThreshold = [2 3];%历史逻辑删除阈值kc = 1e-5;单位体积误报率%% IMM过滤器初始化功能filterInitFcn = @helperMultiClassInitIMMFilter;带有IMM滤波器的联合概率数据关联跟踪器追踪= trackerJPDA ('filterinitializationfcn'filterInitFcn,...'tracklogic''历史'...'AssignmentThreshold'assignmentGate,...“ClutterDensity”Kc,...'确认察觉'confThreshold,...“DeletionThreshold”,德拉什德,“InitializationThreshold”, 0);allTracks =结构([]);时间= 0;dt = 0.1;定义测量噪声measNoise = blkdiag(0.25 *眼(3),25岁,眼(3));numTracks = 0 (numFrames, 2);

检测到的对象被组装为单元数组ObjectDetection.(自动驾驶工具箱)对象的使用helperAssembleDetections函数。

显示= helperLidarObjectDetectionDisplay;初始化阶段(显示);为了count = 1:numframes time = time + dt;获取当前数据输入= inputData{数};rangeImage =输入(::5);从激光雷达数据中提取边界框[绑定盒,CoolarPtCloud,PointLabels] = DetectBbox(LidAdgetector,输入);%将边界框组装到ObjectDetections中检测= HelperAsseMbordetections(边界箱,测量,时间);通过检测到跟踪器如果〜Isempty(检测)%更新跟踪器[confirmedTracks, tentativeTracks allTracks信息]=追踪(检测、时间);numTracks(计数,1)=元素个数(confirmedTracks);结尾用彩色点云更新显示updatePointCloud(显示、coloredPtCloud);%更新分割图像updateSegmentedImage(显示、pointLabels rangeImage);%更新显示,如果轨道不是空的如果~ isempty (confirmedTracks) updateTracks(显示、confirmedTracks);结尾drawnow ('limitrate');结尾

总结

这个例子展示了如何在激光雷达数据上检测和分类装有定向包围盒的车辆。您还学习了如何使用IMM过滤器跟踪具有多个类信息的对象。通过增加更多的训练数据,可以进一步改进语义分割结果。

金宝app支持功能

helperPrepareData

函数multiChannelData = helperPrepareData(输入)%创建5通道数据,如x, y, z,强度和范围来自POINTCLOUD的大小64×1024-y-5的百分比。如果isa(输入,“细胞”)numframes = numel(输入);multichanneldata = cell(1,numframes);为了i = 1:numFrames inputData = input{i};x = inputData.Location (:,: 1);y = inputData.Location (:: 2);z = inputData.Location (:,:, 3);强度= inputData.Intensity;=√x范围。2 + y ^2 + z ^2);multiChannelData{i} = cat(3, x, y, z,强度,范围);结尾其他的x = input.Location (:,: 1);y = input.Location (:: 2);z = input.Location (:,:, 3);强度= input.Intensity;=√x范围。2 + y ^2 + z ^2);multiChannelData = cat(3, x, y, z,强度,范围);结尾结尾

Pixellabelolorbar.

函数一会helperPixelLabelColorbar(提出)%添加一个颜色条到当前轴。颜色栏被格式化%以显示带有颜色的类名。甘氨胆酸colormap(提出)%添加颜色栏到当前的数字。c = colorbar (“对等”甘氨胆酸,);%使用类名作为标记。c.TickLabels =一会;numClasses =大小(提出,1);%中心打勾标签。c.Ticks = 1 / (numClasses * 2): 1 / numClasses: 1;%删除勾号。c.TickLength = 0;结尾

helperExtractGround

函数[ptCloudNonGround, ptCloudGround] = helperExtractGround (ptCloudIn roi)%裁剪点云idx = findPointsInROI (ptCloudIn roi);电脑=选择(ptCloudIn idx,'输出'“全部”);%使用分段平面配件获得地面平面的索引[Ptcloudground,IDX] =分段平面(PC,ROI);nongroundidx = true(大小(pc.location,[1,2]));nongroundidx(IDX)= false;ptcloudnonground = select(pc,nongroundidx,'输出'“全部”);结尾函数[groundPlane,idx] = piecewiseplanefiting (ptCloudIn,roi) groundPtsIdx =...segmentGroundFromLidarData (ptCloudIn...“ElevationAngleDelta”,5,“InitialElevationAngle”15);groundPC =选择(ptCloudIn groundPtsIdx,'输出'“全部”);将x轴分成3个区域segmentLength = (roi(2) - roi(1))/3;x1 = [roi(1),roi(1) + segmentLength];x2 = [x1(2),x1(2) + segmentLength];x3 = [x2(2),x2(2) + segmentLength];roi1 = (x1, roi(3:结束));roi2 = (x2, roi(3:结束));roi3 = [x3, roi(3:结束)];idxBack = findPointsInROI (groundPC roi1);idxCenter = findPointsInROI (groundPC roi2);idxForward = findPointsInROI (groundPC roi3);打破前面和后面的点云ptback = select(groundpc,Idxback,'输出'“全部”);ptforward = select(groundpc,idxforward,'输出'“全部”);[~, inliersForward] = planeFit (ptForward);[~, inliersBack] = planeFit (ptBack);idx = [inliersForward;idxCenter;inliersBack];groundPlane = select(ptCloudIn, idx,'输出'“全部”);结尾函数[plane,inlinersIdx] = planeFit(ptCloudIn) [~,inlinersIdx, ~] = pcfitplane(ptCloudIn,1,[0,0,1]);飞机=选择(ptCloudIn inlinersIdx,'输出'“全部”);结尾

helperAssembleDetections

函数mydetections = helperAssembleDetections (bboxes measNoise,时间戳)将包围框组装为objectDetection的单元格数组MyDetections = Cell(大小(Bboxes,1),1);为了I = 1:size(bboxes,1) classid = bboxes(I,end);lidarModel = [bboxes(i,1:3), bboxes(i,end-1), bboxes(i,4:6)];为了避免被跟踪器直接确认,ClassID被传递为%ObjectAttributes。MyDetections {i} = ObjectDetection(时间戳,...Lidarmodel',“MeasurementNoise”...measNoise,'ObjectAttributes'结构('班级号',班级号));结尾结尾

helperDownloadData

函数[lidarData, pretrainedModel] = helperDownloadData outputFolder = fullfile(tempdir,'wpi');URL =.“https://ssd.mathworks.com/金宝appsupportfiles/lidar/data/lidarSegmentationAndTrackingData.tar.gz”;lidardatatarfile = fullfile(outputfolder,'lidarsmentationandtrackingdata.tar.gz');如果~存在(lidarDataTarFile“文件”mkdir (outputFolder);websave (lidarDataTarFile、url);解压(lidarDataTarFile outputFolder);结尾%检查tar.gz文件是否已下载,但未解压如果~ (fullfile (outputFolder,存在'wpi_lidardata.mat'),“文件”)Untar(LidardataTarfile,Outputfolder);结尾%加载LIDAR数据data =加载(fullfile (outputFolder'highwaydata.mat'));lidarData = data.ptCloudData;%下载净化模型URL =.“https://ssd.mathworks.com/金宝appsupportfiles/lidar/data/pretrainedPointSegModel.mat”;modelfile = fullfile(outputfolder,“pretrainedPointSegModel.mat”);如果~存在(modelFile“文件”) websave (modelFile url);结尾pretrainedModel =负载(fullfile (outputFolder“pretrainedPointSegModel.mat”));结尾

参考文献

[1]张晓,徐文达,董chiyu, John M. Dolan,“基于激光扫描的车辆检测l形拟合”,IEEE智能车辆研讨会,2017年6月

[2]王宇,“基于点云的三维激光雷达实时语义分割”,《中国科学:信息科学》,2018年第4期。