这个例子展示了如何比较地面真实数据与车道边界检测算法的结果。它还说明了如何使用这种比较来调整算法参数,以获得最佳的检测结果。
地面真理数据通常在图像坐标中提供,而边界在车辆坐标系中建模。比较两者涉及坐标转换,因此需要额外的小心来解释结果。驾驶决策是基于车辆坐标系的距离。因此,使用车辆坐标中的物理单元而不是像素坐标来表达和理解准确性要求更有用。
这单纸面申请
描述单眼相机传感器的内部结构和模型车道边界的过程。此示例显示了如何评估这些模型的准确性,针对手动验证的地面真实数据。在建立比较框架之后,该框架扩展到边界检测算法的微调参数以获得最佳性能。
你可以使用地面真理贴标机应用程序在视频中标记和标记车道边界。这些带注释的车道边界被表示为沿着感兴趣的界限放置的点组。对于各种驾驶场景具有丰富的手动注释的车道边界,对于评估和微调自动通道边界检测算法至关重要。设置的示例caltech_cordova1.avi
视频文件可用工具箱提供。
加载在图像坐标中指定的预定义的左和右自我车道边界。每个边界由一组M × 2的数字表示,这些数字表示沿边界的M个像素位置。每个视频帧最多有两个这样的集合,代表左车道和右车道。
loaded = load(“caltech_cordova1_EgoBoundaries.mat”);传感器=加载。%关联的单纸对象gtimageboundarypoints = loaded.groundtruthdata.egolaneBoundaries;%在此帧指数上显示了地面真相的样本Frameind = 36;%加载视频帧frametimestamp =秒(加载.groundtruthdata(frameind,:)。时间);VideoReader = Videoreader(加载.videOname);VideoReader.Currenttime = FrameTimestamp;Frame = Videoreader.readFrame();%获得这一帧的左车道点BuargationPoints = GTImageBoundaryPoints {Frameind};leftlanepoints =边界点{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(边界点));为了cind = 1:numel(边界点)ptsinvehicle {cind} = ImageTovehicle(传感器,边界点{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分数:
precision = 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,作业);hasfalsepositive = cellfun(@(x)nnz(x)== 1,作业);Frameind = find(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),'显示名称'那'真相'那......“颜色”那“蓝”);Tpplotter = LaneBoudaryPlotter(BEP,'显示名称'那“真阳性”那......“颜色”那“绿色”);fpplotter = LaneBoundaryPlotter(BEP,'显示名称'那'假阳性'那......“颜色”那'红色的');PlotlaneBoundary(GTPlotter,FramevichiclePoints);PlotlaneBoundary(TPPlotter,MatchedModels);PlotlaneBoundary(FPPlotter,FPModels);标题('Bird'-Eye Plot的比较结果');
为了获得更好的结果,您还可以在视频上可视化地面真实点和边界模型。
得到与感兴趣的坐标系对应的坐标系。
VideoReader = Videoreader(加载.videOname);VideoReader.CurrenTtime =秒(加载.groundtruthData.time(Frameind));Frame = 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
- 控制灵敏度
函数。这个函数以二进制车道特征掩码的形式返回车道候选点。灵敏度值从0到1不等,默认值为0.25。增加这个数字会导致更多的车道候选点和潜在的更多的错误检测。SementLanemarkerridge.
Lanexextentthreshold.
—指定车道的最小范围(长度)。它表示为检测到的车道长度与指定摄像头配置的最大车道长度的比值。默认值为0.4。增加这个数字以拒绝更短的车道边界。
LANESTRENGTHRESHOLD.
- 指定接受检测到的车道边界的最小归一化强度。
Lanexextentthreshold.
和LANESTRENGTHRESHOLD.
来自于Xextent.
和力量
属性抛物面普遍
目的。这些属性是如何放置在边界建模算法上的额外约束以获得可接受的结果。不同的影响LANESTRENGTHRESHOLD.
有额外的细微差别值得探索。典型的车道边界用固体或虚线标记。与实线相比,虚线具有较低数量的Inlier点,导致强度值较低。这使得设定共同的强度阈值使其具有挑战性。要检查此参数的影响,首先通过设置生成所有边界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.strength],边界,'统一输出',错误的);优势= [强度{:}];标准化强度=优点/ monosensor.maxlanestrength;数字;hist(归一化强度);标题('标准化车道强度的直方图');
您可以使用比较框架进一步评估的影响LANESTRENGTHRESHOLD.
参数对建模算法的检测性能的影响。请注意,阈值
控制模型与地面真实之间最大物理距离的值保持不变。该值由ADAS系统的精度要求决定,通常不会改变。
阈值= .25;[〜,〜,〜,作业] =......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:NUMER(FrameBoundaries)归romalizeStrength = FrameBoundaries(绑定).strength / monoSensor.maxlanestrength;强度=楼层(归一化强度* 100);如果Frameassignment(绑定)这个边界与地面真理边界相匹配,%记录为以上所有力量值的真正值%其强度值。nmatch(1:强度)= nmatch(1:强度)+1;别的这是误报NFP(1:强度)= NFP(1:强度)+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('精确和召回');传奇('精确'那'记起');标题(LANESTRENTHRESHOLD对精密和召回度量的影响');
检测视频中的边界。
探测器
使用预配置HelperMonosensor
对象以检测视频中的边界。
函数界限= DetectBoundaries(VideoName,MonoSensor)Videoreader = Videoreader(VideoName);hwb = waitbar(0,'检测和建模视频中的边界......');closeBar = onCleanup(@()删除(hwb));frameInd = 0;边界= {};而hasfame(videoreader)frameind = frameind + 1;框架= ReadFrame(Videoreader);Sensorout = ProcessFrame(MonoSensor,Frame);%保存边界模型界限{end + 1} =......[sensorOut。leftEgoBoundary sensorOut.rightEgoBoundary);% #好< AGROW >waitbar(Frameind /(Videoreader.duration * Videoreader.framerate),HWB);结尾结尾