评估和可视化车道边界检测对地面真理
这个例子展示了如何评估车道边界检测的性能对已知地面真理。在本例中,您将描述车道边界检测算法的性能在每帧的基础上通过计算拟合优度的措施。这种方法可以用来确定、可视化和理解潜在失效模式的算法。
概述
随着兴趣的自动驾驶问题的解决方案,建立能够评估和验证的准确性检测算法已经成为非常重万博 尤文图斯要的。验证检测算法准确性尤为重要,有几个参数,可以调整来实现结果满足预定义的质量要求。这个例子中走过这样一个工作流,车道边界可以测量的精度水平。这个工作流帮助查明失效模式在这些算法在每帧的基础上,以及描述其整体性能。这个工作流还帮助您可视化和定量理解算法的性能。然后,您可以使用这种理解来优化底层算法来改善其性能。
地面实况数据加载
在这个例子中使用的数据集是一个视频文件从一个前置摄像头在汽车驾驶穿过街道。地面实况的车道边界一直手动标记视频与地面真理贴标签机应用程序,使用一条线ROI贴上“LaneBoundary。”This video is 8 seconds, or 250 frames long. It has three intersection crossings, several vehicles (parked and moving), and lane boundaries (double line, single, and dashed). To create a ground truth lane boundary dataset for your own video, you can use the地面实况贴标签机应用程序。
%与地面实况数据加载垫文件。加载=负载(“caltech_cordova1_laneAndVehicleGroundTruth.mat”);
的加载
结构包含三个字段:
groundTruthData
两列的时间表:LaneBoundaries
和车辆
。LaneBoundaries
包含地面实况点自我车道边界(左和右),表示为一个单元阵列XY点形成一个聚线。车辆
包含车辆地面实况边框在相机视图中,表示为M-by-4数组(x, y,宽度、高度)。传感器
,一个monoCamera
对象与属性校准相机安装在车辆。该对象允许您估计车辆之间的实际距离和对象在它前面。videoName
,一个字符数组,其中包含文件名的视频帧存储。
从数据结构,打开视频文件使用VideoReader
通过帧循环。的VideoReader
对象使用一个helperMonoSensor
对象检测车道和对象的视频帧,使用存储在相机设置传感器
。一个时间表
变量存储在gtdata
地面实况数据。该变量包含每帧数据用于分析。
%创建VideoReader对象读取视频的帧。videoName = loaded.videoName;fileReader = VideoReader (videoName);%地面实况数据被组织在一个时间表。gtdata = loaded.groundTruthData;%显示地面真理的前几行数据。头(gtdata)
0秒时间车辆LaneBoundaries _______ _______ * * * {6 x4双}}{2 x1细胞0.033333秒{6 x4双}}{2 x1细胞0.066667秒{6 x4双}}{2 x1细胞0.1秒{6 x4双}}{2 x1细胞0.13333秒{6 x4双}}{2 x1细胞0.16667秒{6 x4双}}{2 x1细胞0.2秒{6 x4双}}{2 x1细胞0.23333秒{5 x4双}{2 x1细胞}
的gtdata
时间表的列车辆
和LaneBoundaries
。在每一个时间戳,车辆
列包含一个M-by-4车辆边界框和数组LaneBoundaries
列拥有双元素单元阵列的左和右车道边界点。
首先,可视化地面实况图像帧的数据加载。
%的第一帧视频。帧= readFrame (fileReader);%在第一帧提取所有车道点。lanePoints = gtdata.LaneBoundaries {1};%提取车辆在第一帧边界框。vehicleBBox = gtdata.Vehicles {1};%重叠和车辆边界框的右车道点。= insertMarker帧(帧,lanePoints {2},“X”);= insertObjectAnnotation帧(帧,“矩形”vehicleBBox,“汽车”);%显示地面实况第一帧数据。图imshow(框架)
运行车道边界检测算法
利用视频帧和monoCamera
参数,可以自动估计车道边界的位置。插图,processFrame
的方法helperMonoSensor
这里使用类来检测车道边界(如parabolicLaneBoundary
对象)和车辆(如[x, y,宽度、高度]边界框矩阵)。对于这个例子的目的,这是车道边界检测算法在测试”。You can use the same pattern for evaluating a custom lane boundary detection algorithm, whereprocessFrame
被替换为自定义检测功能。地面真理分车辆坐标也存储在LanesInVehicleCoord
列的gtdata
时间表。这样,他们可以在鸟瞰可视化显示。首先,配置helperMonoSensor
对象的传感器
。的helperMonoSensor
类组装所需的所有必要步骤运行车道边界检测算法。
%建立monoSensorHelper处理视频。monoCameraSensor = loaded.sensor;monoSensorHelper = helperMonoSensor (monoCameraSensor);%创建新的时间表,同时测量向量。测量=时间表(gtdata.Time);%设置时间表列控股车道边界和车辆数据。numFrames =地板(fileReader.FrameRate * fileReader.Duration);测量。LaneBoundaries =细胞(numFrames, 2);测量。VehicleDetections =细胞(numFrames, 1);gtdata。LanesInVehicleCoord =细胞(numFrames, 2);%回放视频t = 0时,创建一个帧索引来控制电流%框架。fileReader。CurrentTime = 0;frameIndex = 0;%循环videoFile直到没有新的帧。而hasFrame (fileReader) frameIndex = frameIndex + 1;帧= readFrame (fileReader);%使用processFrame方法计算检测。%这个方法可以取代一个定制的车道检测方法。检测= processFrame (monoSensorHelper,框架);%存储估计车道边界和车辆检测。测量。(detections.leftEgoBoundary LaneBoundaries {frameIndex} =…detections.rightEgoBoundary];测量。VehicleDetections {frameIndex} = detections.vehicleBoxes;%为了便于比较,将地面真理莱恩指出%车辆坐标系。gtPointsThisFrame = gtdata.LaneBoundaries {frameIndex};vehiclePoints =细胞(1,元素个数(gtPointsThisFrame));为2 = 1:元素个数(gtPointsThisFrame) vehiclePoints {2} = imageToVehicle (monoCameraSensor, gtPointsThisFrame {2});结束%地面实况点表示存储在车辆坐标。gtdata。LanesInVehicleCoord {frameIndex} = vehiclePoints;结束
现在您已经处理视频车道检测算法,验证地面实况点是正确地转化为车辆坐标系。中的第一项LanesInVehicleCoord
列的gtdata
时间表包含第一帧的车辆坐标。情节这些地面实况点在第一帧的鸟瞰图。
%回放视频t = 0。fileReader。CurrentTime = 0;%的第一帧视频。帧= readFrame (fileReader);birdsEyeImage = transformImage (monoSensorHelper。BirdsEyeConfig,框架);%提取右车道点第一帧的鸟瞰图。firstFrameVehiclePoints = gtdata.LanesInVehicleCoord {1};pointsInBEV = vehicleToImage (monoSensorHelper。BirdsEyeConfig, firstFrameVehiclePoints {2});%安装在框架上点。birdsEyeImage = insertMarker (birdsEyeImage pointsInBEV,“X”,“大小”6);%在鸟瞰图显示转变点。图imshow (birdsEyeImage)
测量检测错误
计算错误车道边界检测是一个重要的一步验证几个下游子系统的性能。这些子系统包括车道偏离警告系统,依赖于车道检测子系统的准确性。
你可以估计这个精度通过测量拟合优度。与地面真理分,估计计算,您现在可以比较和想象他们找出检测算法有怎样的表现。
拟合优度可以测量在每帧级别或为整个视频。每帧数据提供关于特定场景的详细信息,如行为在弯曲道路检测算法的性能可能会有所不同。全球数据提供一个全局的估计数量的车道,错过了检测。
使用evaluateLaneBoundaries
和一个函数返回全局检测统计数据作业
数组中。这个数组匹配估计相应的地面实况分车道边界对象。
的阈值参数evaluateLaneBoundaries
函数表示的最大横向距离车辆坐标资格作为一个匹配估计抛物线车道边界。
阈值= 0.25;%在米[numMatches, numMisses numFalsePositives、作业]=…evaluateLaneBoundaries (measurements.LaneBoundaries…gtdata.LanesInVehicleCoord,…阈值);disp ([的匹配:num2str (numMatches)]);disp ([的失误:num2str (numMisses)]);disp ([的假阳性的数量:num2str (numFalsePositives)]);
数量的匹配:407数量的想念:38假阳性的数量:28
使用作业
数组,你可以计算每道有用指标,如平均横向距离估计和地面真实点。这些指标显示算法执行。计算的平均距离度量,使用helper函数helperComputeLaneStatistics
,这是定义在这个例子。
averageDistance = helperComputeLaneStatistics (measurements.LaneBoundaries,…gtdata.LanesInVehicleCoord,…作业,@mean);%情节之间的平均距离估计和地面真理。图阻止(gtdata。时间,averageDistance)标题(估计和地面之间的平均距离真理”网格)在ylabel (“米距离”)传说(的左边界,“右边界”)
可视化并回顾地面实况和你的算法之间的差异
你现在有一个定量的理解车道检测算法的准确性。然而,它是不可能完全理解失败仅仅基于情节在前一节中。查看视频和可视化的错误在每帧的基础上是至关重要的在确定特定失效模式可以提高细化算法。
您可以使用地面实况贴标签机应用程序作为可视化工具来查看包含地面实况的视频数据和估计车道边界。的
类提供了一个接口附加自定义可视化工具到地面真理贴标签机。driving.connector.Connector
使用parabolicLaneBoundary
数组和地面实况数据计算车辆估计点的坐标位置。的parabolicLaneBoundary
数组定义了一个线,地面实况数据离散点标记在路上。的helperGetCorrespondingPoints
函数估计点估计的行对应于相同的轴车辆的距离。这个helper函数定义的例子。
地面真理分,估计分现在包含在一个新的时间表
在地面真理贴标签机可视化应用程序创建的groundTruth
对象被存储为一个垫子文件。
%计算估计使用monoCamera点位置。[estVehiclePoints, estImagePoints] = helperGetCorrespondingPoints (monoCameraSensor,…measurements.LaneBoundaries,…gtdata.LanesInVehicleCoord,…作业);%估计通道添加到测量的时间表。测量。EstimatedLanes = estImagePoints;测量。LanesInVehicleCoord = estVehiclePoints;%创建一个新的时间表与可视化所需的所有变量。名称= {“LanePoints”;“DetectedLanePoints”};类型= labelType ({“行”;“行”});labelDefs =表(名称,类型,“VariableNames”,{“名字”,“类型”});visualizeInFrame =时间表(gtdata.Time,…gtdata.LaneBoundaries,…measurements.EstimatedLanes,…“VariableNames”、名称);%创建groundTruth对象。数据源= groundTruthDataSource (videoName);dataToVisualize = groundTruth(数据源、labelDefs visualizeInFrame);%保存所有的结果在distanceData前一节。垫在%的临时文件夹。dataToLoad = [tempdir“distanceData.mat”];保存(dataToLoad,“monoSensorHelper”,“videoName”,“测量”,“gtdata”,“averageDistance”);
的helperCustomUI
类创造情节和使用数据从垫文件加载鸟瞰图,像您刚才创建的一个。地面实况贴标签机应用的连接器接口的交互helperCustomUI
类通过helperUIConnector
类同步视频的平均距离和鸟瞰图的阴谋。这使您能够分析每帧同步的结果分析和可视化。
遵循以下步骤来可视化结果如下面图片所示:
到临时目录
distanceData.mat
保存和打开地面真理贴标签机应用。然后开始地面真理贴标签机应用,与指定的连接器处理helperUIConnector
使用以下命令:
> > origdir = pwd;> > cd (tempdir) > > groundTruthLabeler(数据源,“ConnectorTargetHandle”,@helperUIConnector);
进口标签:可视化地面实况车道标记和估计的车道图像中的坐标。从应用程序将来发布,点击进口标签。然后选择从工作空间选项和负载
dataToVisualize
地面实况应用。主应用程序窗口现在包含车道标记的注释。
你现在可以浏览视频和检查错误。返回到原始目录中,你可以输入:
> > cd (origdir)
从这个可视化,你可以做一些推断算法和地面实况数据的质量。
左边的车道精度始终比右车道准确性。鸟瞰图显示在密切观测,地面实况数据标记为双线的外边界,而估计车道边界了一般双线标记的中心。这表明左边的车道估计可能比数字更准确的描绘,这一个明确定义的地面实况数据集等观测是至关重要的。
发现差距约2.3秒和4秒之前的对应于十字路口的道路上人行横道。这表明该算法不执行在人行横道的存在。
约6.8秒,当车辆接近三分之一的十字路口,自我巷发散到只剩下巷和直巷。,该算法未能准确捕捉左边的车道,和地面实况数据也不包含任何信息5帧。
结论
这个例子展示了如何衡量一个车道边界检测算法的准确性,使用可视化地面实况贴标签机应用。您可以扩展这个概念到其他自定义算法简化这些工作流和扩展应用程序的功能自定义测量。
万博1manbetx支持功能
helperComputeLaneStatistics
这个helper函数计算车道边界检测的统计数据与地面实况点。它接受一个函数处理,可用于推广需要计算的统计数据,包括@mean和@median。
函数统计= helperComputeLaneStatistics (estModels gtPoints,作业,fcnHandle) numFrames =长度(estModels);%让左派和右派估计南默认代表缺乏%的数据。统计=南*的(numFrames 2);为frameInd = 1: numFrames%左右估计南默认情况下。stat (frameInd:) =南*的(2,1);为idx = 1:长度(estModels {frameInd})%忽视假阳性作业。如果作业{frameInd} (idx) = = 0继续;结束% k边界estModelInFrame匹配k%元素索引gtPointsInFrame作业。这种模式下= estModels {frameInd} (idx);thisGT = gtPoints {frameInd}{作业{frameInd} (idx)};thisGTModel = driving.internal.piecewiseLinearBoundary (thisGT);如果意味着(thisGTModel.Points (:, 2)) > 0%左车道xPoints = thisGTModel.Points (: 1);yDist = 0(大小(xPoints));为指数= 1:元素个数(xPoints) gtYPoints = thisGTModel.computeBoundaryModel (xPoints(指数));testYPoints = thisModel.computeBoundaryModel (xPoints(指数));yDist(指数)= abs (testYPoints-gtYPoints);结束stat (frameInd, 1) = fcnHandle (yDist);其他的%右车道xPoints = thisGTModel.Points (: 1);yDist = 0(大小(xPoints));为指数= 1:元素个数(xPoints) gtYPoints = thisGTModel.computeBoundaryModel (xPoints(指数));testYPoints = thisModel.computeBoundaryModel (xPoints(指数));yDist(指数)= abs (testYPoints-gtYPoints);结束stat (frameInd 2) = fcnHandle (yDist);结束结束结束结束
helperGetCorrespondingPoints
这个helper函数创建车辆和图像坐标点轴位置匹配的地面真值点。
函数[vehiclePoints, imagePoints] = helperGetCorrespondingPoints (monoCameraSensor、estModels gtPoints,作业)numFrames =长度(estModels);imagePoints =细胞(numFrames, 1);vehiclePoints =细胞(numFrames, 1);为frameInd = 1: numFrames如果isempty(作业{frameInd}) imagePointsInFrame = [];vehiclePointsInFrame = [];其他的estModelInFrame = estModels {frameInd};gtPointsInFrame = gtPoints {frameInd};imagePointsInFrame =细胞(长度(estModelInFrame), 1);vehiclePointsInFrame =细胞(长度(estModelInFrame), 1);为idx = 1:长度(estModelInFrame)%忽视假阳性作业。如果作业{frameInd} (idx) = = 0 imagePointsInFrame {idx} = (NaN南);继续;结束% k边界estModelInFrame匹配k%元素索引gtPointsInFrame作业。这种模式下= estModelInFrame (idx);thisGT = gtPointsInFrame{作业{frameInd} (idx)};xPoints = thisGT (: 1);yPoints = thisModel.computeBoundaryModel (xPoints);vehiclePointsInFrame {idx} = [xPoints, yPoints];imagePointsInFrame {idx} = vehicleToImage (monoCameraSensor [xPoints yPoints]);结束结束vehiclePoints {frameInd} = vehiclePointsInFrame;imagePoints {frameInd} = imagePointsInFrame;%让imagePoints[],而不是{}遵守groundTruth对象。如果isempty (imagePoints {frameInd}) imagePoints {frameInd} = [];结束如果isempty (vehiclePoints {frameInd}) vehiclePoints {frameInd} = [];结束结束结束