主要内容

使用单目摄像机和语义分割创建占用网格

这个例子展示了如何估计车辆周围的空闲空间,并使用语义分割和深度学习创建占用网格。然后使用该占用网格创建车辆成本图,该地图可用于规划路径。

关于自由空间估算

自由空间估计可以识别环境中的区域,在这些区域中,自动驾驶汽车可以在不撞上任何障碍物(如行人、路缘或其他车辆)的情况下行驶。车辆可以使用各种传感器来估计空闲空间,如雷达、激光雷达或摄像头。这个例子关注的是使用语义分割估计图像传感器的空闲空间。

在这个例子中,你将学习如何:

  • 利用语义图像分割估计空闲空间。

  • 使用空闲空间估算创建占用网格。

  • 在鸟瞰图上可视化占用网格。

  • 使用占用网格创建车辆成本图。

  • 检查世界上的位置是否被占用或空闲。

下载预训练网络

这个例子使用了一个预先训练好的语义分割网络,它可以将像素分为11个不同的类,包括行人,天空.图像中的空闲空间可以通过定义分类为的图像像素来估计作为自由空间。所有其他类都被定义为非自由空间或障碍。

训练这个网络的完整过程显示在基于深度学习的语义分割(计算机视觉工具箱)的例子。下载预训练的网络。

下载预训练的网络。pretrainedURL =“//www.tatmou.com/金宝appsupportfiles/vision/data/segnetVGG16CamVid.mat”;pretrainedFolder = fullfile(tempdir,“pretrainedSegNet”);pretrainedSegNet = fullfile(pretrainedFolder,“segnetVGG16CamVid.mat”);如果~存在(pretrainedFolder“dir”mkdir (pretrainedFolder);disp (“下载预训练的SegNet (107 MB)…”);websave (pretrainedSegNet pretrainedURL);disp (“下载完成了。”);结束% %加载网络。data = load(pretrainedSegNet);Net = data.net;

注:资料下载时间视乎阁下的互联网连接而定。上面使用的命令阻塞MATLAB®直到下载完成。或者,您可以使用web浏览器先将数据集下载到本地磁盘。在本例中,要使用从web下载的文件,请更改pretrainedFolder变量设置为下载文件的位置。

估算可用空间

利用下载的语义分割网络对图像进行处理,估计剩余空间。网络返回图像中每个图像像素的分类。自由空间被标识为已分类为的图像像素

本例中使用的图像是CamVid数据集[1]中的图像序列中的一帧。本例中显示的程序可以应用于帧序列,以估计车辆行驶时的空闲空间。然而,由于在本例中使用了非常深度的卷积神经网络架构(带有VGG-16编码器的SegNet),因此处理每一帧大约需要1秒。因此,为了方便起见,处理单个帧。

读取图像。I = imread(“seq05vd_snap_shot.jpg”);分割图像。[C,scores,allScores] = semanticseg(I,net);将空闲空间覆盖到图像上。B = labeloverlay(I,C,“IncludedLabels”“路”);显示空闲空间和图像。图imshow (B)

要了解空闲空间估计的置信度,请显示的输出分数类为每个像素。置信度值可用于通知下游算法估计的有效性。例如,即使网络将一个像素分类为在美国,置信度评分可能低到足以出于安全原因而忽略这一分类。

使用网络对Road的输出分数作为自由空间置信度。roadClassIdx = 4;freespaceconf自信心= allScores(:,:,roadClassIdx);显示空闲空间置信度。figure imagesc(freespaceconf自信心)“自由空间信心评分”) colorbar

虽然初始分割结果为像素显示道路上的大多数像素被正确分类,可视化分数提供了分类器在这些分类中的信心的更丰富的细节。例如,当你越接近汽车的边界,置信度就越低。

创建鸟瞰图

自由空间估计在图像空间中生成。为了便于生成对导航有用的占用网格,需要将空闲空间估计转换为车辆坐标系统。这可以通过将空闲空间估计转换为鸟瞰图像来实现。

要创建鸟瞰图像,首先定义摄像机传感器配置。本例末尾金宝app列出的支持函数,camvidMonoCameraSensor,返回一个monoCamera(自动驾驶工具箱)对象,表示用于收集CamVid[1]数据的单目摄像机。配置monoCamera(自动驾驶工具箱)需要相机的intrinsic和extrinsics,这是使用CamVid数据集中提供的数据进行估计的。为了估计相机的固有值,该功能使用了CamVid的棋盘式校准图像和相机校准器(计算机视觉工具箱)摄像机外部数据的估计,如高度和俯仰,是由CamVid数据集的作者估计的外部数据得出的。

为CamVid数据创建monoCamera。sensor = camvidmonocamersensor ();

给定相机设置,birdsEyeView(自动驾驶工具箱)对象将原始图像转换为鸟瞰图。该对象允许您使用车辆坐标指定要转换的区域。注意,车辆坐标单元是由monoCamera(自动驾驶工具箱)对象,当摄像机安装高度以米为单位指定时。例如,如果高度以毫米为单位指定,那么模拟的其余部分将使用毫米。

定义鸟瞰转换参数。distAheadOfSensor = 20;%,单位为米,如先前在monoCamera高度输入中指定的那样spaceToOneSide = 3;左右各看3米bottomOffset = 0;outView = [bottomOffset, distAheadOfSensor, -spaceToOneSide, spaceToOneSide];outImageSize = [NaN, 256];%输出图像宽度(像素);高度是自动选择,以保留单位每像素的比率birdsEyeConfig = birdsEyeView(sensor,outView,outImageSize);

生成鸟瞰图,为图像和自由空间自信。

根据CamVid传感器的大小调整图像和空闲空间。imageSize = sensor. intrinsic . imageSize;I = imresize(I,imageSize);freespaceconf自信心= imresize(freespaceconf自信心,imageSize);将图像和自由空间信心分数转换为鸟瞰视图。。imageBEV = transformImage(birdsEyeConfig,I);freespacbev = transformImage(birdsEyeConfig, freespaceconf自信心);在鸟瞰视图中显示图像帧。图imshow (imageBEV)

将图像转换为鸟瞰图,产生自由空间自信。

图imagesc(freeSpaceBEV)“自由空间信心”

距离传感器较远的区域更模糊,这是由于像素较少,因此需要更多的插值。

基于空闲空间估计创建占用网格

占用网格用于将车辆周围环境表示为车辆坐标中的离散网格,并用于路径规划。占用网格中的每个单元格都有一个表示该单元格占用概率的值。估计的空闲空间可用于填充占用网格的值。

使用空闲空间估计来填充占用网格的过程如下:

  1. 在车辆坐标中定义占用网格的尺寸。

  2. 为每个网格单元生成一组(X,Y)点。这些点在飞行器的坐标系统中。

  3. 方法将车辆坐标空间(X,Y)中的点转换为鸟瞰图像坐标空间(X,Y)vehicleToImage(自动驾驶工具箱)变换。

  4. 对(x,y)位置的自由空间置信度值进行抽样,使用griddedInterpolant要插值不完全位于图像像素中心的自由空间置信度值。

  5. 用与该网格单元对应的所有(x,y)点的平均空闲空间置信值填充占用网格单元。

为简洁起见,上面所示的程序在支持函数中实现,金宝appcreateOccupancyGridFromFreeSpaceEstimate,在本例的末尾列出。根据鸟瞰配置定义占用网格的维度,并通过调用创建占用网格createOccupancyGridFromFreeSpaceEstimate

定义占用网格的尺寸和分辨率。gridX = distAheadOfSensor;gridY = 2 * spaceToOneSide;cellSize = 0.25;%(以米为单位),以匹配CamVid传感器使用的单位根据空闲空间估计创建占用网格。occuancygrid = createoccuancygridfromfreespaceestimate (...freeSpaceBEV, birdsEyeConfig, gridX, gridY, cellSize);

可视化使用的占用网格birdsEyePlot(自动驾驶工具箱).创建一个birdsEyePlot(自动驾驶工具箱)并添加占用网格顶部使用pcolor

创建鸟瞰图。bep = birdsEyePlot(“XLimits”[0 distAheadOfSensor],“YLimits”, [-5 5]);在鸟瞰图中添加占用网格。持有[numCellsY,numCellsX] = size(occuancygrid);X = linspace(0, gridX, numCellsX);Y = linspace(-gridY/2, gridY/2, numCellsY);h = pcolor(X,Y, occuancygrid);标题(“占用网格(概率)”色条删除(图例)使占用网格可视化透明,并删除网格线。h.FaceAlpha = 0.5;h.LineStyle =“没有”

鸟瞰图还可以显示来自多个传感器的数据。例如,使用添加雷达覆盖区域coverageAreaPlotter(自动驾驶工具箱)

为绘图添加覆盖区域。caPlotter = coverageAreaPlotter(bep,“DisplayName的”“覆盖范围”);更新为视野35度,射程60米。%mountPosition = [0 0];范围= 15;方向= 0;fieldOfView = 35;plotCoverageArea(caPlotter, mountPosition, range, orientation, fieldOfView);持有

显示来自多个传感器的数据对于自动驾驶汽车的诊断和调试决策非常有用。

使用占用网格创建车辆成本图

vehicleCostmap(自动驾驶工具箱)提供功能来检查车辆坐标或世界坐标中的位置是否被占用或空闲。任何路径规划或决策算法都需要这种检查。创建vehicleCostmap(自动驾驶工具箱)使用生成的occupancyGrid

创建成本图。costmap = vehicleCostmap(flipud(occuancygrid),...“CellSize”cellSize,...“MapLocation”[0, -spaceToOneSide]);costmap.CollisionChecker.InflationRadius = 0;显示成本图。图绘制(costmap,“通货膨胀”“关闭”colormap(parula) colorbar title(“车辆Costmap”定位成本图,使其与车辆坐标对齐。%系统,其中x轴指向自我车辆和% y轴指向左边。视图(gca、-90、90)

来说明如何使用vehicleCostmap(自动驾驶工具箱),在世界坐标中创建一组位置。这些位置代表了车辆可能经过的路径。

在车辆坐标中创建一组位置。candidatlocations = [8 0.375 10 0.375 12 2 14 0.375];

使用checkOccupied(自动驾驶工具箱)检查每个位置是否被占用或空闲。基于结果,一个潜在的路径可能是不可能遵循的,因为它与定义在costmap

检查位置是否已被占用。isOccupied = checkOccupied(costmap, candidatlocations);为了可视化,将位置划分为空闲位置和已占用位置。occupiedLocations = candidateLocations(isOccupied,:);freeLocations = candidateLocations(~isOccupied,:);在成本图顶部显示免费和已占用点。持有markerSize = 100;散射(freeLocations (: 1) freeLocations (:, 2), markerSize,‘g’“填充”)散射(occupiedLocations (: 1) occupiedLocations (:, 2), markerSize,“r”“填充”);传奇([“免费”“占领”)举行

使用occupancyGridvehicleCostmap(自动驾驶工具箱),checkOccupied(自动驾驶工具箱)上面所示说明了路径规划器所使用的基本操作,例如pathPlannerRRT(自动驾驶工具箱).有关路径规划的详细信息,请参阅自动代泊车员(自动驾驶工具箱)的例子。

参考文献

[1] Brostow, Gabriel J., Julien Fauqueur和Roberto Cipolla。视频中的语义对象类:一个高清地面真相数据库。模式识别信.第30卷,2009年第2期,第88-97页。

金宝app支持功能

函数sensor = camvidmonocamersensor ()根据CamVid的数据返回一个monoCamera摄像头配置%数据集[1]。cameraCalibrator应用程序用于使用CamVid提供的%校准图像:% http://web4.cs.ucl.ac.uk/staff/g.brostow/MotionSegRecData/data/CalibrationSeq_and_Files_0010YU.zip%校正图案网格尺寸为28毫米。相机间距由存储在这里的相机姿态矩阵[R t]计算:% http://web4.cs.ucl.ac.uk/staff/g.brostow/MotionSegRecData/data/EgoBoost_trax_matFiles.zip%的引用% ----------Brostow, Gabriel J., Julien Fauqueur和Roberto Cipolla。“语义对象视频中的类:一个高清地面真相数据库。”_Pattern识别% Letters_。第30卷,2009年第2期,第88-97页。calibrationData = load(“camera_params_camvid.mat”);描述相机配置。focalLength = calibrationData.cameraParams.FocalLength;principalPoint = calibrationData.cameraParams.PrincipalPoint;imageSize = calibrationData.cameraParams.ImageSize;%根据[1]中所示的相机设置估计的相机高度。高度= 0.5;%距离地面的高度,单位为米使用数据集中提供的相机外部参数计算相机间距。Pitch = 0;相机朝向地面的%俯仰角,单位为度camintrinsic = cameraIntrinsics(focalLength,principalPoint,imageSize);传感器= monoCamera(camintrinsic,高度,“节”、沥青);结束
函数occuancygrid = createoccuancygridfromfreespaceestimate (...格子,freeSpaceBEV、birdsEyeConfig gridX cellSize)返回一个包含占用概率的占用网格一个统一的二维网格。占用网格中的单元数%。numCellsX = cell (gridX / cellSize);numCellsY = cell (gridY / cellSize);为每个网格单元生成一组(X,Y)点。这些点在车辆的坐标系统。首先定义每个网格的边%的细胞。在车辆坐标中定义每个网格单元格的边缘。XEdges = linspace(0,gridX,numCellsX);YEdges = linspace(-gridY/2,gridY/2,numCellsY);接下来,指定沿着每个点生成的样本点的数量%网格单元格中的维度。中计算步长% X和Y方向。步长将用于移动的边缘值%每个网格生成的点覆盖了网格单元的整个区域%期望的分辨率。从每个格子中抽取20个点。抽样多点可能产生%以额外计算为代价的更平滑的估计。numSamplePoints = 20;所需步长为所需点的抽样数。XStep = (XEdges(2)-XEdges(1)) / (numSamplePoints-1);YStep = (YEdges(2)-YEdges(1)) / (numSamplePoints-1);最后,在网格的两个维度上滑动点集。%的细胞。在使用过程中对占用概率进行抽样% griddedInterpolant。为采样占用概率创建griddedInterpolant。使用1%减去空闲空间置信度,表示占用概率。occuancyprob = 1 - free espacebev;sz = size(occuancyprob);[y,x] = ndgrid(1:sz(1),1:sz(2));F = gridinterpolant (y,x, occuancyprob);将占用网格初始化为零。占用格=零(numCellsY*numCellsX,1);的两个维度上滑动XEdges和YEdges点集合%网格单元格。j = 1:numSamplePoints%增加x方向上的样本点X = XEdges + (j-1)*XStep;i = 1:numSamplePoints%增量样本点在y方向上Y = YEdges + (i-1)*YStep;在鸟瞰车辆坐标中生成一个样本点网格。[XGrid,YGrid] = meshgrid(X,Y);将样本点网格转换为图像坐标xy = vehicleToImage(birdsEyeConfig,[XGrid(:) YGrid(:)]);%剪辑样本点位于图像边界内Xy = max(Xy,1);Xq = min(xy(:,1),sz(2));Yq = min(xy(:,2),sz(1));%使用griddedInterpolant和keep采样占用概率连续求和。occuancygrid = occuancygrid + F(yq,xq);结束结束确定平均占用概率。occuancygrid = occuancygrid / numSamplePoints^2;occuancygrid =重塑(occuancygrid,numCellsY,numCellsX);结束