本讲主要是讲如何使用预先训练好的语义分割算法来分割图像中的天空和道路,并使用该算法在真值标注应用程序中自动进行地面真值标注。
34.1 Ground Truth Labeler应用程序
良好的地面真实数据对于开发自动驾驶算法和评估其性能至关重要。然而,创建和维护一套多样化和高质量的注释驾驶数据需要付出巨大的努力。真值标注应用使这一过程变得简单而高效。该应用包括将对象注释为矩形、线条或像素标签的功能。像素标签是一个过程,其中图像中的每个像素都被分配了一个类或类别,然后可以用来训练像素级分割算法。虽然您可以使用该应用程序手动标记所有数据,但这个过程需要大量的时间和资源,特别是对于像素标签。作为一种替代方案,该应用程序还提供了一个框架,以纳入算法来扩展和自动化标签过程。您可以使用您创建的算法来自动标记整个数据集,然后以更高效、更短的手动验证步骤结束。您还可以编辑自动化步骤的结果,以说明算法可能遗漏的挑战性场景。 在本讲中,将:使用预先训练的分割算法来分割属于 "道路 "和 "天空 "类别的像素。创建一个自动化算法,该算法可用于真值标定的应用程序,以自动标记道路和天空像素。然后,该地面真值数据可用于训练新的语义分割网络,或重新训练现有网络。
34.2 创建道路和天空检测算法
首先,创建一个语义分割算法,分割图像中的道路和天空像素。使用深度学习的语义分割(Computer Vision Toolbox)示例描述了如何为语义分割训练一个深度学习网络。该网络已被训练成可以预测11类语义标签,包括 "道路 "和 "天空"。这些网络的性能取决于它们的可泛化程度。将网络应用于它们在训练过程中没有遇到的情况,可能会导致不合格的结果。在学习过程中反复引入自定义的训练数据,可以使网络在类似的数据集上表现更好。
下载一个网络,它是在剑桥大学的CamVid数据集上进行预训练的。
pretrainedURL= 'https://www.mathworks.com/supportfiles/vision/data/segnetVGG16CamVid.mat';
pretrainedFolder= fullfile(tempdir,'pretrainedSegNet');
pretrainedSegNet= fullfile(pretrainedFolder,'segnetVGG16CamVid.mat');
if~exist(pretrainedSegNet,'file')
if ~exist(pretrainedFolder,'dir')
mkdir(pretrainedFolder);
end
disp('Downloading pretrainedSegNet (107 MB)...');
websave(pretrainedSegNet,pretrainedURL);
end
对图像进行分割并显示:
% Loadthe semantic segmentation network
data =load(pretrainedSegNet);
% Loada test image from drivingdata
roadSequenceData= fullfile(toolboxdir('driving'), 'drivingdata', 'roadSequence');
I =imread(fullfile(roadSequenceData, 'f00000.png'));
% Runthe network on the image
automatedLabels = semanticseg(I, data.net);
%Display the labels overlaid on theimage, choosing relevant categories
figure,imshow(labeloverlay(I, automatedLabels, 'IncludedLabels', ["Sky", "Road"]));
该网络的输出在MATLAB中以分类矩阵的形式表示。所列出的类别包括语义分割网络所训练的所有类别,而不仅仅是输出中存在的类别。这些信息也可以从网络对象本身获得。
% Listcategories of pixels labeled
categories(automatedLabels)
ans = 11×1cell
{'Sky' }
{'Building' }
{'Pole' }
{'Road' }
{'Pavement' }
{'Tree' }
{'SignSymbol'}
{'Fence' }
{'Car' }
{'Pedestrian'}
{'Bicyclist' }
% Theblue overlay indicates the 'Sky' category, and the green overlay
%indicates 'Road'.
34.3 复查像素分割自动化类通过创建一个继承自抽象基类vision.labeleler.AutomationAlgorithm(Computer Vision Toolbox)的类,将这种语义分割算法纳入应用程序的自动化工作流程。这个基类定义了应用程序用于配置和运行算法的 API。真值标注应用程序提供了一种获取初始自动化类模板的便捷方法。RoadAndSkySegmentation类基于该模板,为像素标签分割提供了一个随时可用的自动化类。RoadAndSkySegmentation类中的第一组属性指定了算法的名称,提供了算法的简要描述,并给出了使用方向。
properties(Constant)
%Name
% Character vector specifying name of algorithm.
Name = 'RoadAndSkySegmentation'
%Description
% Character vector specifying short description of algorithm.
Description = 'This algorithm usessemanticseg with a pretrained network to annotate roads and sky'
%UserDirections
% Cell array of character vectors specifying directions for
% algorithm users to follow in order to use algorithm.
UserDirections = {...
['Automation algorithms are a way toautomate manual labeling ' ...
'tasks. This AutomationAlgorithmautomatically creates pixel ', ...
'labelsfor road and sky.'], ...
['Review and Modify: Review automated labelsover the interval ', ...
'using playback controls.Modify/delete/add ROIs that were not ' ...
'satisfactorily automated at this stage. If the results are '...
'satisfactory, click Accept toaccept the automated labels.'], ...
['Accept/Cancel: If results ofautomation are satisfactory, ' ...
'click Accept to accept all automated labelsand return to ' ...
'manual labeling. If results of automation are not ' ...
'satisfactory, click Cancel toreturn to manual labeling ' ...
'without saving automated labels.']};
end
RoadAndSkySegmentation类的下一节指定了核心算法所需的自定义属性。PretrainedNetwork 属性持有预训练的网络。AllCategories 属性持有三个类别的名称。
properties
% PretrainedNetwork saves theSeriesNetwork object that does the semantic
% segmentation.
PretrainedNetwork
% Categories holds the default'background', 'road', and 'sky'
% categorical types.
AllCategories = {'background'};
% Store names for 'road' and 'sky'.
RoadName
SkyName
end
checkLabelDefinition是在RoadAndSkySegmentation中定义的第一个方法,它检查是否只有PixelLabel类型的标签被启用以实现自动化。PixelLabel是语义分割唯一需要的类型。
function TF= checkLabelDefinition(~, labelDef)
isValid = false;
if (strcmpi(labelDef.Name, 'road')&& labelDef.Type == labelType.PixelLabel)
isValid = true;
algObj.RoadName = labelDef.Name;
algObj.AllCategories{end+1} =labelDef.Name;
elseif (strcmpi(labelDef.Name,'sky') && labelDef.Type == labelType.PixelLabel)
isValid = true;
algObj.SkyName = labelDef.Name;
algObj.AllCategories{end+1} =labelDef.Name;
elseif(labelDef.Type ==labelType.PixelLabel)
isValid = true;
end
end
接下来的一组函数控制算法的执行。vision.labeleler.AutomationAlgorithm类包含一个接口,该接口包含 "initialize"、"run "和 "terminate "等方法,用于轻松设置和运行自动化。初始化函数根据应用中现有的标签来填充初始算法状态。在RoadAndSkySegmentation类中,初始化函数被定制为从tempdir加载预训练的语义分割网络,并将其保存到PretrainedNetwork属性中。
functioninitialize(algObj, ~, ~)
% Point to tempdir wherepretrainedSegNet was downloaded.
pretrainedFolder =fullfile(tempdir,'pretrainedSegNet');
pretrainedSegNet =fullfile(pretrainedFolder,'segnetVGG16CamVid.mat'); data = load(pretrainedSegNet);
% Store the network in the'PretrainedNetwork' property of this object.
algObj.PretrainedNetwork = data.net;
end
接下来,run函数定义了这个自动化类的核心语义分割算法。"run "对每个视频帧都会被调用,并期望自动化类返回一组标签。RoadAndSkySegmentation中的run函数包含了前面介绍的逻辑,用于创建对应 "道路 "和 "天空 "的像素标签的分类矩阵。这可以扩展到网络所训练的任何类别,仅限于这两个类别,仅作说明。
function autoLabels = run(algObj, I)
% Setup categorical matrix withcategories including road and
% sky
autoLabels =categorical(zeros(size(I,1), size(I,2)),0:2,algObj.AllCategories,'Ordinal',true);
pixelCat = semanticseg(I,this.PretrainedNetwork);
if ~isempty(pixelCat)
% Add the selected label at the bounding box position(s)
autoLabels(pixelCat =="Road") = algObj.RoadName;
autoLabels(pixelCat =="Sky") = algObj.SkyName;
end
end
这个算法不需要任何清理,所以终止函数是空的。
34.4 使用App中的Pixel Segmentation Automation类上一节中描述的属性和方法已经在RoadAndSkySegmentation自动化算法类文件中实现。要在应用程序中使用这个类。在当前文件夹下创建所需的文件夹结构+vision/+labeler,并将自动化类复制到其中。
mkdir('+vision/+labeler');
copyfile('RoadAndSkySegmentation.m','+vision/+labeler');
打开groundTruthLabeler应用,自定义数据进行标注。为了便于说明,打开caltech_cordova1.avi视频。
groundTruthLabeler caltech_cordova1.avi
在左侧窗格中,单击 "定义新的ROI标签 "按钮,定义两个ROI标签,名称分别为道路和天空,类型为像素标签,如图所示:
- 点击算法 > 选择算法 > 刷新列表。
- 点击Algorithm > RoadAndSkySegmentation。如果你没有看到这个选项,请确保当前工作文件夹中有一个名为+vision/+labeler的文件夹,文件名为RoadAndSkySegmentation.m在其中。
- 单击 "自动"。打开一个新的面板,显示算法的使用方向。
- 单击 "运行"。创建的算法会在视频的每一帧上执行,对 "道路 "和 "天空 "类别进行分割。运行完成后,使用滑块或方向键滚动浏览 "道路 "和 "天空 "类别。视频,并验证自动化算法的结果:
- 很明显,摄像机视野之外的区域被错误地标注为 "天空",而被控车辆本身的部分区域被标注为 "道路"。这些结果表明,该网络之前并未对此类数据进行过训练。这个工作流允许对这些结果进行手动修正,这样就可以利用训练和标记的迭代过程(有时称为主动学习或循环中的人类)来进一步完善网络在以下数据上的准确性。自定义数据集:您可以通过使用"标签像素 "选项卡中的笔刷工具,手动调整结果,并添加或删除像素注释。标签像素选项卡中还提供了其他工具,如泛光填充和智能多边形,可以在适当的时候使用。
- 一旦您对整个视频的像素标签类别感到满意,请单击 "接受"。
视频的像素标签的自动化就完成了。现在您可以继续标记其他感兴趣的对象,保存会话,或导出本次标记运行的结果。
34.5 总结
这个例子展示了如何在真值标注应用中使用自动化算法接口,使用预先训练好的语义分割网络来加速道路和天空像素的标注。
原文标题 : 基于MATLAB&SIMULINK开发自动驾驶系统第三十四讲使用语义分割进行自动真值标注