这个例子展示了如何比较地面真实数据与车道边界检测算法的结果。它还说明了如何使用这种比较来调整算法参数,以获得最佳的检测结果。
地面真实数据通常在图像坐标系中可用,而边界在车辆坐标系中建模。比较两者涉及坐标转换,因此在解释结果时需要格外小心。驾驶决策基于车辆坐标系中的距离。因此,表达并使用车辆坐标中的物理单位而不是像素坐标来理解精度要求。
的单摄像机示例
描述了单目摄像机传感器的内部结构和车道边界建模过程。该示例显示了如何根据手动验证的地面真实数据评估这些模型的准确性。在建立了比较框架后,该框架被扩展以微调边界检测算法的参数,以获得最佳的pe表现。
你可以使用地面真理贴标机在视频中标记和标记车道边界的应用程序。这些带注释的车道边界表示为沿着感兴趣的边界放置的点集。在评估和微调自动车道边界检测算法时,拥有一套丰富的人工注释车道边界用于各种驾驶场景是至关重要的。为caltech_cordova1.avi
视频文件是可用的工具箱。
加载在图像坐标中指定的预定义的左和右自我车道边界。每个边界由一组M × 2的数字表示,这些数字表示沿边界的M个像素位置。每个视频帧最多有两个这样的集合,代表左车道和右车道。
加载=负载(“caltech_cordova1_EgoBoundaries.mat”);传感器= loaded.sensor;%伴生单镜头物体gtImageBoundaryPoints = loaded.groundTruthData.EgoLaneBoundaries;%显示此帧索引处的地面真相示例frameInd=36;%加载视频帧frameTimeStamp=seconds(加载的.groundTruthData(frameInd,:).Time);videoReader=videoReader(加载的.videoName);videoReader.CurrentTime=frameTimeStamp;frame=videoReader.readFrame();%获得这一帧的左车道点boundaryPoints = gtImageBoundaryPoints {frameInd};leftLanePoints = boundaryPoints {1};图imshow(帧)在绘图(leftLanePoints(:,1),leftLanePoints(:,2),“+”,“MarkerSize”10“线宽”4);标题(“左车道边界地面真实数据样本”);
将地面真值点从图像坐标转换为车辆坐标,以便与边界模型进行直接比较。要执行此转换,请使用
与关联的成像车
单眼
对象以执行此转换。
gtVehicleBoundaryPoints =细胞(元素个数(gtImageBoundaryPoints), 1);对于frameInd = 1:numel(gtImageBoundaryPoints);如果ptsinvevehicle = cell(1, numel(boundaryPoints));对于ptsvehicle {cInd} = imageToVehicle(sensor, boundaryPoints{cInd});终止gtVehicleBoundaryPoints{frameInd}=ptsInVehicle;终止终止
对样本视频运行车道边界建模算法,获取测试数据进行对比。在这里,重用辅助传感器
模块中引入的单目相机的视觉感知的例子。在处理视频时,需要额外的一步来返回检测到的边界模型。这个逻辑被包装在一个辅助函数中,探测边界
,在本例的最后定义。
monoSensor=helperMonoSensor(传感器);边界=detectBoundaries(loaded.videoName,monoSensor);
使用
函数查找与地面真理中边界匹配的边界数。只有当地面真值的所有点都在与相应的测试边界的指定距离内时,地面真值才被分配到测试边界。如果多个地面真值边界满足此准则,则选择横向距离最大的最小边界。其他的被标记为假阳性。evaluateLaneBoundaries
阈值= 0.25;%(车辆坐标)(米)[numMatches, numMisses, numFalsePositives, assignments] =...评估车道边界(边界、GTV车辆边界点、阈值);显示(['匹配数:',num2str(numMatches)];disp(['未命中次数:',num2str(nummises)];disp(['误报数:',num2str(numFalsePositives)];
匹配次数:409失败次数:36误报次数:27
您可以使用这些原始计数来计算其他统计数据,如精度、召回率和F1分数:
精度= numMatches / (numMatches + numFalsePositives);disp ([的精度:num2str(精密)]);回忆= numMatches / (numMatches + numMisses);disp ([的灵敏度/回忆:num2str(召回)]);f1Score = 2 *(精度*召回)/(精度+回忆);disp ([的F1分数:num2str (f1Score)]);
准确度:0.93807灵敏度/召回:0.9191 F1评分:0.92849
另外,返回地面真实值和测试边界之间每一次成功匹配的赋值索引。这可以用来可视化检测和地面真实边界,以更好地理解失效模式。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的”,“真阳性”,...“颜色”,“绿色”);FP绘图仪=laneBoundaryPlotter(bep,“DisplayName的”,“假阳性”,...“颜色”,“红色”);plotLaneBoundary (gtPlotter frameVehiclePoints);plotLaneBoundary (tpPlotter matchedModels);plotLaneBoundary (fpPlotter fpModels);标题(“鸟眼对比结果图”);
为了获得更好的结果背景,您还可以在视频上可视化地面真值点和边界模型。
获取与感兴趣的帧对应的帧。
videoReader = videoReader (loaded.videoName);videoReader。CurrentTime =秒(loaded.groundTruthData.Time (frameInd));帧= videoReader.readFrame ();
将边界模型考虑为实线(不管传感器如何对其进行分类)以实现可视化。
fpModels.BoundaryType=“固体”;matchedModels。BoundaryType =“固体”;
插入匹配的模型,假阳性和地面真值点。这幅图有助于推断人行横道的存在给边界建模算法带来了挑战。
xVehicle=3:20;车架=插入式车身(车架,FP车型,传感器,xVehicle,“颜色”,“红色”);frame = insertLaneBoundary(frame, matchedModels, sensor, xVehicle,“颜色”,“绿色”); 图ha=轴;imshow(框架,“父”,哈);%合并左右边界点boundaryPoints=[frameImagePoints{1};frameImagePoints{2}];保留在绘图(ha,边界点(:,1),边界点(:,2),“+”,“MarkerSize”10“线宽”4);标题(“比较结果的摄影机视图”);
你也可以在这个框架的鸟瞰视图中可视化结果。
birdsEyeImage=transformImage(monoSensor.BirdsEyeConfig,frame);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);标题(“对比结果的鸟瞰图”);
您可以使用前面描述的评估框架来微调车道边界检测算法的参数。辅助传感器
公开了控制寻道算法结果的三个参数。
LaneSegmentationSensitivity
-控制的灵敏度
函数。这个函数以二进制车道特征掩码的形式返回车道候选点。灵敏度值从0到1不等,默认值为0.25。增加这个数字会导致更多的车道候选点和潜在的更多的错误检测。segmentLaneMarkerRidge
LaneXExtentThreshold
—指定车道的最小范围(长度)。它表示为检测到的车道长度与指定摄像头配置的最大车道长度的比值。默认值为0.4。增加这个数字以拒绝更短的车道边界。
兰斯特长阈值
-指定接受检测到的车道边界的最小规格化强度。
LaneXExtentThreshold
和兰斯特长阈值
是从XExtent
和力量
的属性抛物线基
对象。这些属性是如何对边界建模算法施加额外约束以获得可接受结果的一个例子。变化的影响兰斯特长阈值
有额外的细微差别值得探索。典型的车道边界是用实线或虚线标记的。当与实线相比,虚线有更少的嵌入点,导致更低的强度值。这使得设定一个共同的力量阈值变得很有挑战性。要检查此参数的影响,首先通过设置生成所有边界兰斯特长阈值
为0。此设置确保它不会对输出产生影响。
monoSensor。LaneStrengthThreshold = 0;边界= detectBoundaries (“加州理工学院科尔多瓦1.avi”, monoSensor);
的兰斯特长阈值
性质辅助传感器
控制规范化力量
参数的抛物线基
模型。归一化因子,MaxLaneStrength
,是一个虚拟车道的强度,它运行到鸟瞰图的全部范围。该值仅由birdsEyeView
的配置辅助传感器
。评估兰斯特长阈值
,首先计算样本视频中所有检测到的边界归一化车道强度的分布。注意到有两个明显的峰,一个在归一化强度为0.3,一个在0.7。这两个峰值分别对应虚线和实线边界。从这个情节中,您可以凭经验确定,为了确保检测到虚线车道边界,兰斯特长阈值
应低于0.3。
优势= cellfun (@ (b) (b。强度),边界,“UniformOutput”,假);强度=[强度{:}];标准化强度=强度/monoSensor.MaxLaneStrength;图形hist(标准化强度);头衔(“归一化车道强度直方图”);
您可以使用比较框架进一步评估的影响兰斯特长阈值
参数对建模算法的检测性能的影响。请注意,阈值
控制模型与地面真实之间最大物理距离的值保持不变。该值由ADAS系统的精度要求决定,通常不会改变。
阈值=升至;[~, ~, ~, assignments] =...evaluateLaneBoundaries(边界,gtVehicleBoundaryPoints,阈值);
根据标准化强度对每个边界进行分类作业
信息有助于将每个边界划分为真阳性(匹配)或假阳性。兰斯特长阈值
是一个“最小”阈值,因此在给定值被分类为真正的边界对于所有更低的阈值仍然是真正的。
nMatch = 0 (1100);归一化车道强度被装入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);如果帧分配(绑定)这个边界与地面真理边界相匹配,%记录为以上所有力量值的真正值%它的强度值。nMatch (1: strengthBucket) = nMatch (1: strengthBucket) + 1;其他的这是误报nFP临界多边形求解(1:strengthBucket) = (1: strengthBucket) + 1;终止终止终止
使用此信息来计算“错过”边界的数量,即算法在指定位置未能检测到的地面真值边界兰斯特长阈值
利用这些信息,计算准确度和召回率指标。
gtTotal =总和(cellfun (@ (x)元素个数(x) gtVehicleBoundaryPoints));nMiss = gtTotal - nMatch;precisionPlot = nMatch。/(临界多边形求解nMatch +);recallPlot = nMatch。/ (nMatch + nMiss);
根据车道强度阈值参数的各种值绘制精度和召回指标。此图有助于确定车道强度参数的最佳值。对于此视频剪辑,要最大化召回和召回指标,兰斯特长阈值
应该在0.20 - 0.25的范围内。
图;情节(precisionPlot);持有在;情节(recallPlot);包含(“LaneStrengthThreshold * 100”);ylabel (的精度和召回);传奇(“精度”,“回忆”);标题(“laneststrength阈值对精度和召回指标的影响”);
检测视频中的边界。
探测边界
使用一个预先配置的辅助传感器
对象来检测视频中的边界。
函数边界= 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);%保存边界模型{结束+ 1}=边界...[sensorOut。leftEgoBoundary sensorOut.rightEgoBoundary);% #好< AGROW >waitbar(frameInd/(videoReader.Duration*videoReader.FrameRate),hwb);终止终止