主要内容

评估对地面真实数据的车道边界检测

这个例子展示了如何比较地面真实数据与车道边界检测算法的结果。它还说明了如何使用这种比较来调整算法参数,以获得最佳的检测结果。

概述

地面真理数据通常在图像坐标中提供,而边界在车辆坐标系中建模。比较两者涉及坐标转换,因此需要额外的小心来解释结果。驾驶决策是基于车辆坐标系的距离。因此,使用车辆坐标中的物理单元而不是像素坐标来表达和理解准确性要求更有用。

单纸面申请描述单眼相机传感器的内部结构和模型车道边界的过程。此示例显示了如何评估这些模型的准确性,针对手动验证的地面真实数据。在建立比较框架之后,该框架扩展到边界检测算法的微调参数以获得最佳性能。

加载并准备地面真理数据

你可以使用地面真理贴标机在视频中标记和标记车道边界的应用程序。这些带注释的车道边界表示为沿着感兴趣的边界放置的点集。在评估和微调自动车道边界检测算法时,拥有一套丰富的人工注释车道边界用于各种驾驶场景是至关重要的。为caltech_cordova1.avi视频文件是可用的工具箱。

加载在图像坐标中指定的预定义的左和右自我车道边界。每个边界由一组M × 2的数字表示,这些数字表示沿边界的M个像素位置。每个视频帧最多有两个这样的集合,代表左车道和右车道。

加载=负载(“caltech_cordova1_EgoBoundaries.mat”);传感器=加载。%关联的单纸对象gtimageboundarypoints = loaded.groundtruthdata.egolaneBoundaries;%在此帧指数上显示了地面真相的样本Frameind = 36;%加载视频帧frametimestamp =秒(加载.groundtruthdata(frameind,:)。时间);videoReader = videoReader (loaded.videoName);VideoReader.Currenttime = FrameTimestamp;帧= videoReader.readFrame ();%获得这一帧的左车道点boundaryPoints = gtImageBoundaryPoints {frameInd};leftLanePoints = boundaryPoints {1};图imshow(帧)plot(leftlanepoints(:,1),leftlanepoints(:,2),'+''Markersize'10'行宽'4);标题(“左车道边界地面真实数据样本”);

将地面真理从图像坐标转换为车辆坐标,以便与边界模型进行直接比较。要执行此转换,请使用Imagetovehicle.函数与关联的单纸巾对象执行此转换。

gtVehicleBoundaryPoints =细胞(元素个数(gtImageBoundaryPoints), 1);为了Frameind = 1:Numel(GTImageBoundaryPoints)边界点= GTImageBoundaryPoints {FrameInd};如果〜isempty(边界点)ptsinvehicle = cell(1,numel(边界点));为了ptsvehicle {cInd} = imageToVehicle(sensor, boundaryPoints{cInd});结尾gtvehicleboundarypoints {frameind} = ptsinvehicle;结尾结尾

使用单眼传感器模型车道边界

在示例视频上运行车道边界建模算法,以获得比较的测试数据。在这里,重用了HelperMonosensor模块中引入的单目相机的视觉感知的例子。在处理视频时,需要额外的一步来返回检测到的边界模型。这个逻辑被包装在一个辅助函数中,探测器,在本例的最后定义。

monoSensor = HelperMonosensor(传感器);界限=检测到(加载.VideOname,MonoSensor);

评价车道边界模型

使用evaluateLaneBoundaries函数找到与地面真相匹配这些边界的边界的数量。仅当基础事实的所有点在相应的测试边界中横向地区的所有点都在指定距离内时,才会分配地面真相。如果多个地面真理边界满足该标准,则选择具有最小最大横向距离的距离。其他人被标记为误报。

阈值= 0.25;%(车辆坐标)(米)[numMatches, numMisses, numFalsePositives, assignments] =...evaluateLaneBoundaries(边界,gtVehicleBoundaryPoints,阈值);disp (['匹配数:',num2str(nummatches)]);disp (['错过的人数:',num2str(nummisses)]);disp (['误报的数量:',num2str(numfalsepositives)]);
匹配次数:321失败次数:124误报次数:25

您可以使用这些原始计数来计算其他统计数据,如精度、召回率和F1分数:

精度= numMatches / (numMatches + numFalsePositives);disp ([的精度:num2str(精密)]);回忆= numMatches / (numMatches + numMisses);disp ([的灵敏度/回忆:num2str(召回)]);f1Score = 2 *(精度*召回)/(精度+回忆);disp ([的F1分数:,num2str(f1score)]);
精确度:0.92775灵敏度/召回:0.72135 F1得分:0.81163

使用鸟瞰图可视化结果

evaluateLaneBoundaries另外,在地面真理和测试边界之间的每个成功匹配返回分配索引。这可以用于可视化检测到的和地面的界限,以更好地了解失败模式。

找到一个有一个匹配边界和一个假阳性的帧。每一帧的地面真值数据都有两个边界。因此,一个候选框架将有两个赋值指标,其中一个为0表示假阳性。

hasMatch = cellfun(@(x)numel(x)==2,赋值);hasfalse = cellfun(@(x)nnz(x)==1,赋值);frameInd =找到(hasMatch&hasFalsePositive 1“第一”);FramevehiclePoints = GtvehicleBoundaryPoints {Frameind};FrameImagePoints = GTImageBoundaryPoints {Frameind};framemodels =边界{frameind};

使用分配输出evaluateLaneBoundaries找到匹配(真实阳性)和模型的模型,这些模型在实际情况下没有匹配(误报)。

matchedmodels = frameModels(作业{frameind}〜= 0);fpmodels = framemodels(作业{frameind} == 0);

设置鸟瞰图,并在它上可视化地面真相和模型。

cep = birdsEyePlot ();gtPlotter = laneBoundaryPlotter (cep),“DisplayName的”'真相'...“颜色”“蓝”);tpPlotter = laneBoundaryPlotter (cep),“DisplayName的”“真阳性”...“颜色”“绿色”);fpplotter = LaneBoundaryPlotter(BEP,“DisplayName的”'假阳性'...“颜色”“红色”);plotLaneBoundary (gtPlotter frameVehiclePoints);plotLaneBoundary (tpPlotter matchedModels);plotLaneBoundary (fpPlotter fpModels);标题('Bird'-Eye Plot的比较结果');

在相机和鸟瞰图中的视频上可视化结果

为了获得更好的结果,您还可以在视频上可视化地面真实点和边界模型。

得到与感兴趣的坐标系对应的坐标系。

videoReader = videoReader (loaded.videoName);videoReader。CurrentTime =秒(loaded.groundTruthData.Time (frameInd));帧= videoReader.readFrame ();

将边界模型考虑为实线(不管传感器如何对其进行分类)以实现可视化。

FPModels.BoundaryType =.'坚硬的';matchedModels。BoundaryType ='坚硬的'

插入匹配的模型,假阳性和地面真值点。这幅图有助于推断人行横道的存在给边界建模算法带来了挑战。

xvehicle = 3:20;Frame = InsertLaneBoundary(帧,FPModels,传感器,Xvehicle,“颜色”“红色”);frame = insertLaneBoundary(frame, matchedModels, sensor, xVehicle,“颜色”“绿色”);图HA =轴;imshow(框架,'父母',哈);%合并左右边界点BuargationPoints = [FrameImagePoints {1}; FrameImagePoints {2}];持有绘图(HA,边界点(:,1),边界点(:,2),'+''Markersize'10'行宽'4);标题('比较结果的相机视图');

你也可以在这个框架的鸟瞰视图中可视化结果。

BirdseyeImage = Transportimage(Monosensor.birdseyeconfig,框架);xvehicle = 3:20;BirdseyeImage = InsertLaneBoundary(BirdseyeImage,FPModels,Monosensor.birdseyeconfig,xvehicle,“颜色”“红色”);birdsEyeImage = insertLaneBoundary(birdsEyeImage, matchedModels, monoSensor.)BirdsEyeConfig xVehicle,“颜色”“绿色”);%合并左右边界点ptsinvehicle = [framevehiclepoints {1}; framevehiclepoints {2}];gtpointsinbev = vehicletoimage(monosensor.birdseyeconfig,ptsinvehicle);图imshow(birdseyeimage);持有情节(gtPointsInBEV (: 1) gtPointsInBEV (:, 2),'+''Markersize'10'行宽'4);标题('Bird's-Eye View对比较结果');

调谐边界建模参数

您可以使用前面描述的评估框架来微调车道边界检测算法的参数。HelperMonosensor公开了控制寻道算法结果的三个参数。

  • LaneSegmentationSensitivity-控制的灵敏度SementLanemarkerridge.函数。这个函数以二进制车道特征掩码的形式返回车道候选点。灵敏度值从0到1不等,默认值为0.25。增加这个数字会导致更多的车道候选点和潜在的更多的错误检测。

  • LaneXExtentThreshold—指定车道的最小范围(长度)。它表示为检测到的车道长度与指定摄像头配置的最大车道长度的比值。默认值为0.4。增加这个数字以拒绝更短的车道边界。

  • LANESTRENGTHRESHOLD.- 指定接受检测到的车道边界的最小归一化强度。

LaneXExtentThresholdLANESTRENGTHRESHOLD.来自于XExtent力量的属性抛物面普遍对象。这些属性是如何对边界建模算法施加额外约束以获得可接受结果的一个例子。变化的影响LANESTRENGTHRESHOLD.有额外的细微差别值得探索。典型的车道边界是用实线或虚线标记的。当与实线相比,虚线有更少的嵌入点,导致更低的强度值。这使得设定一个共同的力量阈值变得很有挑战性。要检查此参数的影响,首先通过设置生成所有边界LANESTRENGTHRESHOLD.为0。此设置确保它不会对输出产生影响。

monosensor.lanestrentththreshold = 0;界限=检测到('caltech_cordova1.avi', monoSensor);

LANESTRENGTHRESHOLD.财产HelperMonosensor控制规范化力量参数的抛物面普遍模型。归一化因子,maxlanestrenth.,是在鸟瞰图像的全部范围内运行的虚拟车道的强度。该值仅由此确定birdsEyeView的配置HelperMonosensor.评估影响的影响LANESTRENGTHRESHOLD.,首先计算样本视频中所有检测到的边界归一化车道强度的分布。注意到有两个明显的峰,一个在归一化强度为0.3,一个在0.7。这两个峰值分别对应虚线和实线边界。从这个情节中,您可以凭经验确定,为了确保检测到虚线车道边界,LANESTRENGTHRESHOLD.应低于0.3。

优势= cellfun (@ (b) (b。强度),边界,“UniformOutput”,错误的);优势= [强度{:}];标准化强度=优点/ monosensor.maxlanestrength;图;hist(归一化强度);标题('标准化车道强度的直方图');

您可以使用比较框架进一步评估的影响LANESTRENGTHRESHOLD.参数对建模算法的检测性能的影响。请注意,阈值控制模型与地面真实之间最大物理距离的值保持不变。该值由ADAS系统的精度要求决定,通常不会改变。

阈值=升至;[~, ~, ~, assignments] =...evaluateLaneBoundaries(边界,gtVehicleBoundaryPoints,阈值);

根据其归一化强度箱每个边界。的分配信息有助于将每个边界划分为真阳性(匹配)或假阳性。LANESTRENGTHRESHOLD.是一个“最小”阈值,因此在给定值被分类为真正的边界对于所有更低的阈值仍然是真正的。

nmatch = zeros(1,100);归一化车道强度被装入100个桶中nFP = 0 (1100);%范围从0.01到1.00。为了frameInd = 1:numel(boundaries) frameBoundaries = boundaries{frameInd};frameAssignment =作业{frameInd};为了bInd = 1:numel(frameBoundaries) normalizedStrength = frameBoundaries(bInd).Strength/ monosensor . maxlaneststrength;strengthBucket =地板(normalizedStrength * 100);如果FrameasSignment(绑定)这个边界与地面真理边界相匹配,%记录为以上所有力量值的真正值%其强度值。nMatch (1: strengthBucket) = nMatch (1: strengthBucket) + 1;别的这是误报nFP临界多边形求解(1:strengthBucket) = (1: strengthBucket) + 1;结尾结尾结尾

使用此信息来计算“错过”边界的数量,即算法在指定位置未能检测到的地面真值边界LANESTRENGTHRESHOLD.价值。通过该信息,计算精度和召回度量标准。

gtTotal =总和(cellfun (@ (x)元素个数(x) gtVehicleBoundaryPoints));nMiss = gtTotal - nMatch;precisionPlot = nMatch。/(临界多边形求解nMatch +);recallPlot = nMatch。/ (nMatch + nMiss);

绘制精度并召回指标对车道强度阈值参数的各种值。该曲线可用于确定车道强度参数的最佳值。对于此视频剪辑,以最大化召回和精密度量,LANESTRENGTHRESHOLD.应该在0.20 - 0.25的范围内。

图;情节(precisionPlot);持有;绘图(Recallplot);Xlabel('lanestrongthreshold * 100');ylabel ('精确和召回');传奇(“精度”“回忆”);标题(“laneststrength阈值对精度和召回指标的影响”);

金宝app支持函数

检测视频中的边界。

探测器使用预配置HelperMonosensor对象以检测视频中的边界。

函数边界= detectBoundaries(videoName, monoSensor) videreader = videoReader (videoName);hwb = waitbar (0,'检测和建模视频中的边界......');closeBar = onCleanup(@()删除(hwb));frameInd = 0;边界= {};hasFrame(videreader) frameInd = frameInd+1; / /设置帧id帧= readFrame (videoReader);sensorOut = processFrame(monoSensor, frame);%保存边界模型界限{end + 1} =...[sensorOut。leftEgoBoundary sensorOut.rightEgoBoundary);% #好< AGROW >waitbar(Frameind /(Videoreader.duration * Videoreader.framerate),HWB);结尾结尾

也可以看看

应用

功能

相关话题