基于MATLAB&SIMULINK开发自动驾驶系统第二讲之地面真值标签与验证

2.1 开始使用Ground Truth LabelerGround Truth Labeler 应用使 能够在视频、图像序列或激光雷达点云中交互式地标示地面真值数据。使用该应用程序,可以同时标记多个信号,例如从安装在车辆上的摄像头和激光雷达传感器获得的数据。

本示例通过这些步骤引导完成多信号地真值标签工作流程。1 "加载要标记的地面真值信号" - 将多个信号加载到应用程序中,并配置这些信号的显示。1       "为多个信号标记地面真值"--创建标签定义,并使用自动化算法对信号进行标记。2       "导出和探索多个信号的地面真值标签" - 从应用程序中导出标签并探索数据。可以使用这些导出的标签以及相关的信号帧,作为深度学习应用的训练数据。2.2 将接地真值信号加载到标签上Ground Truth Labeler应用提供了两种类型信号的标签选项。- 图像信号是基于图像的。可以从视频或图像序列等来源加载这些信号。- 点云信号是基于激光雷达的信号。可以从诸如点云文件序列等来源加载这些信号。在本例中, 将一个视频和一个点云序列加载到应用程序中。这些信号来自安装在车辆上的摄像头传感器和激光雷达传感器。这些信号代表了同一个驾驶场景。2.2.1 加载时间戳加载点云序列的时间戳。时间戳是一个持续时间向量,与序列在同一文件夹中。要加载时间戳,必须将此文件夹临时添加到 MATLAB® 搜索路径中。pcSeqFolder = fullfile(toolboxdir('driving'),'drivingdata','lidarSequence');addpath(pcSeqFolder)loadtimestamps.mat rmpath(pcSeqFolder)该应用还提供了一个选项来为视频源指定时间戳。本例中使用的视频没有单独的时间戳文件,所以当加载视频时,可以直接从视频源中读取时间戳。2.2.2打开地面真值标签器App要打开Ground Truth Labeler应用程序,在MATLAB命令提示符下,输入此命令。GroundTruthLabeler该应用程序将打开一个空对话框。或者,也可以从"汽车 "下的 "应用程序"选项卡中打开该应用程序。

2.2.3 从数据源加载信号Ground Truth Labeler 应用使能够从多种类型的数据源加载信号。在应用程序中,数据源是包含一个或多个要标记的信号的文件或文件夹。- 对于视频,数据源是一个包含单个视频的 MP4 文件。- 对于点云序列,数据源是一个包含点云数据(PCD)文件序列的文件夹。这些文件共同代表一个单一的点云序列。其他数据源,如rosbags,可以包含多个信号,可以加载。有关数据源和信号之间关系的更多详情,请参见"地面实况标注中的数据源与信号"。加载视频将视频加载到应用程序中。1 在应用程序工具条上,单击"打开">"添加信号"。将打开 "添加/删除信号 "对话框,将 "源类型"参数设置为 "视频",并将"添加 "和 "删除"选项设置为 "信号"。时间戳参数设置为来自文件。

2 在文件名参数中,浏览该视频文件。<matlabroot>是matlabroot函数返回的MATLAB安装文件夹的完整路径。<matlabroot>/toolbox/driving/drivingdata/01_city_c2s_fcw_10s.mp43 点击添加源。视频加载到应用程序中,应用程序直接从视频中读取时间戳。源表显示视频数据源的相关信息。加载点云序列将点云序列加载到应用程序中。1 在"添加/删除信号 "对话框仍然打开且视频已加载的情况下,将 "源类型 "参数设置为"点云序列"。对话框显示特定于加载点云序列的新选项。

2 在文件夹名称参数中,浏览lidarSequence文件夹,该文件夹包含要加载的点云数据(PCD)文件序列。<matlabroot>/toolbox/driving/drivingdata/lidarSequence3 将"时间戳 "参数设置为 "来自工作区"。在 "从工作空间导入 "对话框中,选择为点云序列加载的时间戳变量。单击 "确定"。

4 单击添加源。点云序列加载到应用程序中,应用程序从时间戳变量中读取时间戳。源表显示有关点云序列的数据源。验证有关加载信号的信息Add/Remove Signal(添加/删除信号)对话框底部的表格显示了有关加载信号的信息。验证该表是否为加载的信号显示此信息。- 信号名称列显示应用程序生成的信号名称。对于视频,信号名是数据源的文件名,前缀为video_,没有文件扩展名。对于点云序列,信号名是源文件夹的名称。- 源列显示信号数据源的完整文件路径。- 信号类型列显示每个信号的类型。视频的类型是图像。点云序列的类型是点云。- 时间范围列根据加载的时间戳数据显示信号的持续时间。这两个信号的长度约为10秒。对于点云序列,如果将 "时间戳 "设置为 "使用默认值",那么 "时间范围 "栏就会显示 "点云"。序列的值范围是0到33秒。这个范围是基于34个PCD文件中。文件夹。默认情况下,应用程序将点云序列的时间戳设置为从 0 到有效点云文件数减 1 的持续时间向量。单位以秒为单位。如果发生这个问题,在表,选择点云序列行的复选框。然后,点击删除选中,再次加载信号,再次验证信号信息。验证信号加载正确后,点击确定。应用加载信号后,打开到最后添加的信号的第一帧,本例为点云序列。

2.2.4 配置信号显示当第一次加载信号时,应用程序每次只显示一个信号。要并排显示信号,首先,在应用程序工具条的 "标签 "选项卡上,单击 "显示网格"。然后,移动指针选择1乘2网格,并单击网格。

视频和点云序列并排显示。

要想一起查看视频和点云序列,在信号下方的滑块中,点击播放。按钮。视频播放比点云序列更流畅,因为视频在大约相同的时间内有更多的帧,因此帧率更高。默认情况下,应用程序会播放帧率最高的信号的所有帧。此信号称为主信号。对于所有其他信号,应用程序将显示与主信号当前显示的帧时间一致的帧。要配置哪个信号是主信号,请使用 "播放控制设置 "对话框中的选项。要打开此对话框,请在滑块下方单击时钟设置按钮 。有关使用这些选项控制信号帧显示的更多详情,请参阅的 "控制播放信号帧以进行标注"。加载信号并查看帧后,现在可以创建标签定义并给数据贴标签,如 "为多个信号贴标签地真 "中所述。2.3 多信号的标签接地真值将视频和激光雷达点云序列信号加载到 "地面真值 "应用中后, "将地面真值信号加载到标签 "程序中的描述,创建标签。定义,并对信号帧进行标注。在本例中,只对部分信号进行标签,以达到说明的目的。2.3.1创建标签定义标签定义包含 在信号上标记的标签信息。 可以在应用程序中交互式创建标签定义,也可以通过使用labelDefinitionCreatorMultisignal对象以编程方式创建标签定义。在这个例子中, 可以在应用程序中创建标签定义。创建ROI标签ROI 标签是与信号帧中的兴趣区域 (ROI) 对应的标签。可以定义这些 ROI 标签类型。- 矩形/立方体--在物体(如车辆)周围绘制边界框标签。在图像信号中, 可以将这种类型的标签绘制为二维矩形边界框。在点云信号中,可以将此类型的标签绘制为三维立方体边界框。- 投影立方体--在图像中的物体(如车辆)周围绘制 3-D 界线框标签。- 线条 - 绘制线性 ROI 来标记线条,例如车道边界。- 像素标签 - 绘制像素来标记各种类别,如道路或天空,以进行语义分割。有关这些 ROI 标签定义的详细信息,请参见 "ROI 标签、子标签和属性"。创建一个ROI标签定义,用于标记信号帧中的汽车。1 在左侧窗格的 ROI 标签窗格中,单击 "标签"。2 创建一个名为 "车 "的矩形/立方体标签。3 从 "组 "列表中,选择 "新建组 "并将组命名为 "车辆"。向组添加标签是可选的。4 单击 "确定"。车辆组名称出现在 ROI 标签选项卡上,其下有标签 car。

在每个信号上,汽车标签的绘制方式不同。在视频上,汽车被画成一个二维矩形边界框,类型为矩形。在点云序列上,汽车被画成一个立方体类型的三维立体边界框。创建ROI子标签子标签是与父 ROI 标签相对应的 ROI 标签的一种类型。每个子标签必须属于ROI标签标签定义,或者是ROI标签标签定义的子标签。例如,在驾驶场景中,车辆标签可以有前灯、车牌或车轮的子标签。创建一个ROI子标签定义,用于标注被标注汽车的刹车灯。1 选择子标签的父标签。在左窗格中的 "ROI标签 "选项卡上,单击汽车标签将其选中。2 单击子标签。3 创建一个名为brakeLight的矩形子标签。不支持立方体子标签,因此该子标签仅适用于视频信号。单击 "确定"。brakeLight子标签出现在汽车标签下的ROI Labels标签中。子标签和父标签具有相同的颜色。

创建ROI属性ROI属性指定了关于ROI标签或子标签的附加信息。例如,在驾驶场景中,属性可以包括车辆的类型或颜色。可以定义这些类型的 ROI 属性。- Numeric Value(数值)--指定一个数值标量属性,例如标签车辆的车门数量。- 字符串 - 指定一个字符串标量属性,例如车辆的颜色。- Logical - 指定一个逻辑的真或假属性,例如车辆是否在行驶中。- 列表 - 指定预定义字符串的下拉列表属性,如车辆的品牌或型号。创建一个属性来描述标记的刹车灯是亮还是灭。1 在左侧窗格中的 ROI 标签上,选择制动灯子标签并单击 "属性"。2 在 "属性名称 "框中,键入 "isOn"。将属性类型设置为 "逻辑"。保留默认值设置为 "空",然后单击 "确定"。3 在ROI标签中,展开brakeLight子标签的定义,现在这个子标签的属性框中包含了isOn属性。现在这个子标签的属性框中包含了isOn属性。

创建场景标签场景标签定义了场景中所有信号的附加信息。使用场景标签来描述条件,如照明和天气,或事件,如车道变化。创建一个场景标签以应用于信号帧。1 在应用程序的左侧窗格中,选择 "场景标签 "选项卡。2 单击定义新的场景标签,然后在 "标签名称 "框中,输入名为daytime。3 将标签定义的颜色改为浅蓝色,以体现场景标签的性质。在 "颜色 "参数下,单击 "颜色预览",选择标准的淡蓝色。然后,单击 "确定 "关闭颜色选择窗口。

4 将 "组 "参数设置为默认的 "无",然后单击 "确定"。场景标签窗格显示场景标签定义。

验证标签定义验证 的标签定义是否有这样的设置。1 ROI 标签标签包含一个车辆组,其汽车标签类型为矩形/立方体。2 汽车标签包含一个名为刹车灯的子标签。3 brakeLight子标签包含一个名为isOn的属性。4 "场景标签 "选项卡包含一个名为daytime的淡蓝色场景标签。要编辑或删除一个标签定义,右键单击该标签定义并选择相应的编辑或删除选项。要将这些标签定义保存到MAT文件中,以便在未来的标签会话中使用,请在 "场景标签 "选项卡上点击 "编辑"。应用工具条的标签选项卡,选择 "保存">"标签定义"。在未来的标签对话框中,如果需要对标签定义重新排序或将其移动到不同的组, 可以在标签定义窗格中拖放它们。2.3.2 使用自动化给视频贴标签使用汽车标签为视频中的部分汽车贴上标签。要协助标签过程,请使用内置的标签自动化算法之一。1 选择要标记的时间间隔。指定一个8到10秒的时间间隔,在这个时间间隔内,前面的车与被控车辆接近。在视频下方的文本框中,按此次序输入这些时间。a 在 "当前 "框中,输入8,然后按Enter键。b在 "开始时间 "框中,键入8,使滑块处于时间间隔的开始。c 在 "结束时间 "框中,键入 10。范围滑块和文本框被设置为8-10秒的时间间隔。红色标志表示时间间隔的开始和结束。

应用程序仅显示该时间间隔的信号帧,自动化算法仅适用于该时间间隔。若要扩大时间间隔以填满整个播放部分,请单击 "放大时间间隔"。2 在标签窗口中,单击视频信号以选择它。一次只能自动选择一个信号,因此必须选择要自动选择的信号。3 选择要自动化的标签。在 "ROI 标签 "选项卡中,单击汽车标签。4 从应用程序工具条中,选择选择算法 > 时空插值器。该算法通过在图像帧之间插补 ROI 位置来估计矩形 ROI。时间间隔。5 单击自动。应用程序会提示确认 只想标记视频的一部分。单击 "是"。视频的自动化会话将打开。自动化会话的右侧窗格显示算法说明。

6 在时间间隔开始时,点击并拖动,在帧中心的汽车周围绘制一个汽车标签。对于这种算法,每帧只能画一个标签。给其他汽车贴标签需要单独的自动化环节。

默认情况下,只有当将指针移动到汽车标签上时,汽车标签才会出现。可选地,要始终显示标签,在应用程序工具条上,将 "显示ROI标签 "设置为始终。7 将滑块拖动到最后一帧,并在这一帧中的同一辆车周围绘制汽车标签。可选地,为了提高自动化效果,在中间帧中标注汽车。8 单击 "运行"。自动化算法将汽车标签应用到中间帧中。拖动滑块以查看结果。如有必要,可手动调整标签以提高其准确性。9 当对结果感到满意时,单击 "接受 "关闭会话,并将标签应用到这部分视频中。2.3.3 使用自动化进行标签点云序列使用上一步骤中相同的汽车标签定义来标记点云序列中的汽车。为了协助标记过程,请使用为以下内容设计的内置标签自动化算法。点云标注。在这个例子中,你标注的是被控车辆,在激光雷达点云序列中比前车更容易看到。1 在应用的底部,确认时间范围仍然设置为8到10秒。2 在标签窗口中,点击点云序列进行选择。3 在 ROI 标签选项卡中,单击汽车标签定义。4 在应用程序工具条的标签选项卡上,选择选择算法 > 点云时空插值器。该算法通过在时间间隔内插值ROI位置来估计点云帧之间的立方体ROI。5 单击自动。应用程序会提示确认 要只标记部分点云序列。单击 "是"。打开点云序列的自动化会话。自动化会话的右侧窗格显示算法说明。

6 在时间间隔的开端,在被控车辆四周画一个汽车标签。a 使用滚动轮或框架右上角的 "放大 "按钮,放大汽车。也可以使用 "平移 "按钮将汽车置于框架的中心。

b在左侧窗格的ROI标签上,单击汽车标签。拖动灰色预览立方体,直到它突出显示被控车辆。

c 单击信号框以创建标签。标签会卡在点云的高亮部分。

d 调整立方体标签,直到它完全包围汽车。要调整立方体的大小,请单击并拖动其中一个立方体面。要移动立方体,请按住Shift键并单击并拖动其中一个立方体面。

7 单击立方体,按Ctrl+C复制它。然后,拖动滑块到最后一帧,并将立方体粘贴(Ctrl+V)到同一位置的新帧中。可选地,为了提高自动化效果,可手动调整复制标签的位置。8单击 "运行"。自动化算法将汽车标签应用到中间帧。拖动滑块查看结果。如有必要,手动调整标签以提高其准确性。9 当对结果感到满意时,单击 "接受 "关闭会话,并将标签应用到这部分点云序列中。2.3.4 用子标签和属性手动标记手动为视频中的一帧标注刹车灯子标签及其isOn属性。激光雷达点云信号不支持子标签和属性,所以无法对点云序列进行标注。1 在应用程序的底部,验证时间范围是否仍设置为8至10秒。如果有必要,请将滑块拖动到时间范围的第一帧。2 在 "ROI标签 "选项卡中,单击 "brakeLight "子标签定义将其选中。3隐藏点云序列。在应用程序工具条的标签选项卡上,在 "显示/隐藏信号 "下,清除激光雷达点云序列的复选标记。隐藏信号只是隐藏显示。应用程序会维护隐藏信号的标签,仍然可以导出它们。4 展开视频信号以填充整个标签窗口。5 在视频帧中,选择绘制的汽车标签。标签会变成黄色。必须选择汽车标签(父ROI),然后才能为其添加子标签。6为汽车绘制brakeLight子标签。可以选择将 "显示 ROI 标签 "设置为 "始终",这样就可以确认汽车标签与其子标签之间的关联。

7 在视频帧上,选择其中一个刹车灯子标签。然后,在右侧窗格中的 "属性和子标签 "窗格中,将isOn属性设置为True。对另一个子标签重复此步骤。

2.3.5手动标注场景将白天的场景标签应用到整个场景中。1 将时间间隔回扩到所有信号的整个持续时间。如果放大了时间间隔,请先单击 "放大时间间隔"。然后,将红色标志拖到范围滑块的开始和结束处。2 在应用程序的左侧窗格中,选择 "场景标签 "选项卡。3 选择日间场景标签定义。4 在标签定义上方,单击 "时间间隔"。然后,单击添加标签。日间场景标签会出现一个复选标记,表明该标签现在适用于时间间隔内的所有帧。

查看标签摘要随着所有标签、子标签和属性被应用到信号的至少一帧,现在可以选择查看地面真值标签的可视化摘要。在应用程序工具条上,单击 "查看标签摘要"。有关详细信息,请参阅 "查看地面真值标签摘要"(计算机视觉工具箱)。保存应用程序会话在应用程序工具条上,选择保存并保存应用程序会话的 MAT 文件。保存的会话包括数据源、标签定义和标签的地面真值。它还包括的会话首选项,例如应用程序的布局。现在,可以关闭应用程序会话或继续进入 "导出和探索多个信号的地真标签 "步骤,在该步骤中导出标签。2.4 导出和探索多个信号的地面真值标签按照 "为多个信号贴标签 "程序给信号贴上标签后,导出标签并探索如何存储它们。2.4.1 设置打开包含标记信号的 Ground Truth Labeler 应用程序会话。 可以从 MATLAB命令行打开会话。例如,如果将该会话保存到名为groundTruthLabelingSession,输入此命令。groundTruthLabelergroundTruthLabelingSession.mat在应用程序工具条上,选择 "导出标签">"到工作区"。在 "导出到工作空间 "窗口中,使用默认的导出变量名称 gTruth,然后单击确定。应用程序会将 groundTruthMultisignal 对象 gTruth 导出到 MATLAB 工作区。该对象包含从应用程序会话中捕获的地面真值标签。如果没有将groundTruthMultisignal对象导出到工作区,请从变量gTruth中加载一个预定义对象。用于加载该对象的函数作为辅助文件附在本例中。如果使用自己的对象,标签位置等数据可能与本例中显示的数据不同。if (~exist('gTruth','var'))gTruth= helperLoadGTruthGetStarted;end显示groundTruthMultisignal对象gTruth的属性。该对象包含有关信号数据源、标签定义以及 ROI 和场景标签的信息。这些信息存储在对象的单独属性中。gTruth =groundTruthMultisignal with properties:DataSource: [1x2vision.labeler.loading.MultiSignalSource]LabelDefinitions: [3x7 table]ROILabelData: [1x1 vision.labeler.labeldata.ROILabelData]SceneLabelData: [1x1 vision.labeler.labeldata.SceneLabelData]在这个例子中, 将检查每个属性的内容,以了解对象如何存储地面真值标签。2.4.2数据源DataSource 属性包含有关数据源的信息。此属性包含两个 MultiSignalSource 对象:一个用于视频源,一个用于点云序列源。显示DataSource属性的内容。ans = 1x2 heterogeneous MultiSignalSource(VideoSource, PointCloudSequenceSource) array with propertSourceNameSourceParamsSignalNameSignalTypeTimestampNumSignals这些对象中存储的信息包括数据源的路径、它们所包含的信号名称以及这些信号的时间戳。显示数据源的信号名称。gTruth.DataSource.SignalNameans = "video_01_city_c2s_fcw_10s"ans="lidarSequence"标签定义LabelDefinitions 属性包含了一个关于标签定义的信息表。显示标签定义表。每一行都包含有关 ROI 或场景标签定义的信息。汽车标签定义有两行:一行用于在图像信号上绘制矩形标签,另一行用于在点云信号上绘制立方体标签。gTruth.LabelDefinitionsans =3x7 tableName SignalType LabelType Group Description LabelColor Hierarchy___________ __________ _________ ____________ ___________ ____________ ____________{'car' } Image Rectangle {'Vehicles'} {0x0 char} {1x3 double} {1x1 struct}{'car' } PointCloud Cuboid {'Vehicles'} {0x0 char} {1x3 double} {1x1 struct}{'daytime'} Time Scene {'None' } {0x0 char} {1x3 double} {0x0 double}层次列存储了父ROI标签的子标签和属性定义的信息。当汽车标签绘制为矩形时,显示它的子标签和属性信息。该标签包含一个子标签brakeLight,没有属性。gTruth.LabelDefinitions.Hierarchy{1}ans =struct with fields:brakeLight: [1x1 struct]Type: RectangleDescription: ''显示父车标签的刹车灯子标签的信息。子标签包含一个属性isOn。子标签不能有自己的子标签。gTruth.LabelDefinitions.Hierarchy{1}.brakeLightans =struct with fields:Type: RectangleDescription: ''LabelColor: [0.5862 0.8276 0.3103]isOn: [1x1 struct]显示刹车灯子标签的 isOn 属性的信息。这个属性没有默认值,所以DefaultValue字段为空。gTruth.LabelDefinitions.Hierarchy{1}.brakeLight.isOnans =struct with fields:DefaultValue: []Description: ''ROI标签数据ROILlabelData 属性包含一个 ROILabelData 对象,其属性包含每个信号的 ROI 标签数据。属性的名称与信号的名称相匹配。显示对象属性名。gTruth.ROILabelDataans =ROILabelData with properties:video_01_city_c2s_fcw_10s: [204x1 timetable]lidarSequence: [34x1 timetable]每个属性都包含在每个信号时间戳处绘制的 ROI 标签的时间表,每个标签有一列。查看部分视频和激光雷达点云序列时间表。设置一个时间间隔,从8到8.5秒。该时间间隔对应于程序中"为多个信号标注地面真值 "中标注的时间间隔的开始。视频时间表比点云序列时间表包含更多行,因为视频包含更多标签帧。timeInterval = timerange(seconds(8),seconds(8.5));videoLabels = gTruth.ROILabelData.video_01_city_c2s_fcw_10s(timeInterval,:)lidarLabels = gTruth.ROILabelData.lidarSequence(timeInterval,:)videoLabels =10x1 timetableTime car________ ____________8 sec {1x1 struct}8.05 sec {1x1 struct}8.1 sec {1x1 struct}8.15 sec {1x1 struct}8.2 sec {1x1 struct}8.25 sec {1x1 struct}8.3 sec {1x1 struct}8.35 sec {1x1 struct}8.4 sec {1x1 struct}8.45 sec {1x1 struct}lidarLabels =2x1 timetableTime car__________ ____________8.0495 sec {1x1 struct}8.3497 sec {1x1 struct}查看时间间隔内第一帧视频的矩形车标签。标签数据存储在一个结构中。videoLabels.car{1}ans =struct with fields:Position: [296 203 203 144]brakeLight: [1x2 struct]Position(位置)字段存储汽车标签的位置。这个框架只包含一个车标,所以在这种情况下,Position只包含一个矩形边界框。边界框位置的形式为[x y w h],其中。- x和y表示矩形的左上角。- w指定矩形的宽度,也就是矩形沿x轴的长度。- h指定矩形的高度,也就是矩形沿y轴的长度,其中:x和y指定矩形的左上角,w指定矩形的宽度,也就是矩形沿x轴的长度。汽车标签在这个框架上还包含两个刹车灯子标签。查看brakeLight子标签。子标签存储在一个结构数组中,每个子标签在框架上绘制一个结构。videoLabels.car{1}.brakeLightans =1x2 struct array with fields:Position isOn查看子标签的边界框位置。videoLabels.car{1}.brakeLight.Positionans =304 245 50 46ans =435 243 54 51查看每个子标签中isOn属性的值。对于两个子标签,此属性被设置为逻辑1(true)。videoLabels.car{1}.brakeLight.isOnans = logical1ans = logical1现在查看时间间隔内第一个点云序列帧的立方体车标签。点云序列不支持子标签或属性。立方体车标签不存储在结构的位置字段中,而是存储在一个M乘9的矩阵中,其中M是立方体标签的数量。因为这个框架只包含一个立方体标签,在这种情况下,M为1。lidarLabels.car{1}ans =struct with fields:Position: [-1.1559 -0.7944 1.2012 12.6196 5.9278 3.0010 0 0 0]brakeLight: []1乘9的边界盒位置的形式为[xctr,yctr,zctr,xlen,ylen,zlen,xrot,yrot,zrot],其中。- xctr, yctr, andzctr specify the center of the cuboid. xlen, ylen, and zlen, xrot, yrot, zrot],其中:- xlen, ylen, 和 zlen 分别指定了立方体在应用旋转之前沿 x-, y-, 和 z-轴的长度。- xrot、yrot和zrot分别指定了立方体沿x轴、y轴和z轴的旋转角度。这些角度在相应轴的正向看时为顺时针正值。此图显示了这些值如何指定立方体的位置。

场景标签数据SceneLabelData 属性包含一个 SceneLabelData 对象,其属性包含所有信号的场景标签数据。属性的名称与场景标签的名称相匹配。显示对象属性名gTruth.SceneLabelDataans =SceneLabelData with properties:daytime: [0 sec 10.15 sec]日间标签适用于整个时间间隔,约为10秒。使用 "地面真值 "标签本例中显示的标签仅用于说明目的。对于自己的标签,在 导出标签后,可以使用它们作为对象探测器的训练数据。要从groundTruthMultisignal对象中收集标签数据用于训练,请使用gatherLabelData函数。要共享已标记的地真数据,请共享包含groundTruthMultisignal对象的地真MAT-文件,而不是包含应用程序会话的MAT-文件。2.5 地面真实标签中的来源与信号在 Ground Truth Labeler 应用中,源是包含要加载的数据的文件或文件夹。信号是指来自该源的、 要标记的数据。一个源可以包含一个或多个信号。在许多情况下,一个信号源只包含一个信号。考虑一个AVI视频文件。信号源是AVI文件,信号是 从该文件中加载的视频。其他只有一个信号的信号源包括Velodyne®数据包捕获(PCAP)文件和包含图像或点云序列的文件夹。rosbag等源可以包含多个信号。考虑一个名为 cal_loop.bag 的 rosbag。该rosbag包含从安装在车辆上的四个传感器获得的数据。源是rosbag文件。rosbag中的信号是sensor_msgs主题,对应于四个传感器的数据。这些主题有这些名称。- /center_camera/image_color - 从中心摄像机获得的图像序列。- /left_camera/image_color - 从左侧摄像头获取的图像序列。- /right_camera/image_color - 从右侧摄像头获取的图像序列。- /velodyne_points - 从Velodyne激光雷达传感器获得的点云序列。这张图描述了信号源与其四个信号之间的关系。

2.6 Ground Truth Labeler的键盘快捷键和鼠标动作2.6.1 标签定义任务执行在 "ROI 标签定义 "窗格中,浏览 ROI 标签及其组。上箭头或下箭头在 "场景标签定义 "窗格中,浏览场景标签及其组。按住Alt键,按向上箭头或向下箭头。在组内重新排列标签或在组间移动标签。点击并拖动标签重新排列组别点击并拖动组2.6.2 帧导航和时间间隔设置在帧之间导航并更改信号的时间间隔。这些控件位于应用程序的底部窗格中。任务执行转到下一帧右箭头转到上一帧左箭头到最后一格·      - PC。结束·      - Mac。按住Fn,然后按右箭头去第一帧·      - PC: 首页·       - Mac。按住Fn,然后按左箭头在时间间隔框和框架导航按钮中导航Tab时间间隔设置在活动的时间间隔框内按  Enter 键(开始时间、当前时间或结束时间)。2.6.3 标签窗口执行标签操作,如添加、移动和删除感兴趣区域(ROI)。ROI可以是像素标签,也可以是非像素ROI标签,包括直线、矩形、立方体和投影立方体。任务执行撤销贴标动作Ctrl+Z重做贴标动作Ctrl+Y选择所有非像素ROICtrl+A选择特定的非像素ROIHold Ctrl and click the ROIs you want to select切割选定的非像素ROICtrl+X将选定的非像素ROI复制到剪贴板上。Ctrl+C粘贴复制的非像素ROI- 如果子标签被复制,则子标签和它的父标签都会被粘贴。- 如果复制了父标签,则只粘贴父标签,不粘贴其子标签。有关详细信息,请参见 "使用子标签和属性来标记地面真值数据"(计算机视觉工具箱)。Ctrl+V在选定的非像素ROI标签之间切换。只能在相同类型的标签之间进行切换。例如,如果 选择一个矩形ROI,  只能在其他矩形ROI之间切换。Tab or Shift+Tab移动绘制的非像素ROI标签。Hold Ctrl and press the  up, down, left or right arrows统一调整矩形ROI的尺寸。Ctrl+Plus (+) or Ctrl+Minus (-)删除选定的非像素ROIDelete复制所有像素ROICtrl+Shift+C切断所有像素ROICtrl+Shift+X粘贴复制或剪切的像素ROI。Ctrl+Shift+V删除所有像素ROICtrl+Shift+Delete填充所有或所有剩余像素Shift+click2.6.4 调整立方体大小和移动绘制立方体来标注激光雷达点云。关于如何有效地使用这些快捷键来标注激光雷达点云的例子,请参见"为物体探测标注激光雷达点云"。要启用这些快捷键, 必须先在点云框内点击选择它。任务执行在将立方体应用到点云之前,在所有维度上均匀地调整其大小。按住A,向上移动滚轮增大尺寸或向下移动滚轮减小尺寸。在将立方体应用于点云之前,仅沿X维度调整其大小。按住X,向上移动滚轮以增大尺寸或向下移动滚轮以减小尺寸。在将立方体应用到点云之前,只沿y维度调整其大小。按住Y键,向上移动滚轮以增大尺寸或向下移动滚轮以减小尺寸。在将立方体应用于点云之前,仅沿Z维度调整其大小。按住Z键,向上移动滚轮以增大尺寸,向下移动滚轮以减小尺寸。将立方体应用于点云后,调整其大小。点击并拖动其中一个立方体面移动一个立方体按住Shift键,点击并拖动其中一个立方体面。立方体将沿着所选面的尺寸进行转换。同时移动多个立方体按照以下步骤进行操作。1 按住Ctrl键,点击你想移动的立方体。2 按住Shift键,点击并拖动所选立方体中的一个面。立方体会沿着所选面的维度进行转换。多线图在框架上绘制ROI线标签。ROI线标签是多条线,也就是说它们是由一条或多条线段组成的。任务执行将一条多段线提交到帧中,不包括当前活动的线段。繪製多段線時,按Enter鍵或右鍵。将一条多段线提交给框架,包括当前活动的线段。在绘制多段线时双击。新的线段将在  双击的位置被提交。删除之前在多段线中创建的线段。Backspace取消绘图并删除整个多段线Escape2.6.5 多边形绘图绘制多边形来标记框架上的像素。任务执行将一个多边形提交到帧中,不包括当前活动的线段。绘制多边形时,按 Enter 或右键。多边形通过在之前提交的点和多边形的第一个点之间形成一条线来关闭。将一个多边形提交到帧中,包括当前活动的线段。绘制多边形时双击。在双击的点和多边形中的第一个点之间形成一条线,多边形就会关闭。从多边形中删除之前创建的线段。Backspace取消绘图并删除整个多边形Escape2.6.6 缩放、平移和旋转任务执行放大或缩小图像框架向上移动滚轮可放大或向下移动可缩小。如果画面处于平移模式,则不支持缩放。要启用缩放,在框架的右上角,单击 "平移 "按钮以禁用平移,或单击其中一个缩放按钮。放大图像框架的特定部分在框架的右上角,单击 "放大 "按钮,然后在框架内单击并拖动,在 要放大的部分周围绘制一个框。不支持放大点云的特定部分。平移整个图像框按上、下、左或右箭头。放大或缩小点云框架。在显示屏的左上角,单击 "放大 "或  "缩小 "按钮。然后,向上(放大)或向下(缩小)移动滚轮。或者,向上或向右(放大)或向下或向左(缩小)移动光标。所有模式(平移、缩放和旋转)都支持放大和缩小。在点云框架上平移按住Shift键,然后按上、下、左或右箭头旋转一个点云框架按住R键,点击并拖动点云框架。注:只允许偏航旋转。2.6.7 应用程序会话任务执行保存当前任务Ctrl+S2.7 控制信号帧的回放以进行标签化处理Ground Truth Labeler应用可以同时标注多个图像或激光雷达点云信号。当播放信号或在帧之间导航时,可以控制哪个通过改变信号显示的帧率来显示每个信号的帧数。2.7.1 信号帧所标注的信号是由帧组成的。每一帧都有一个与之相关的离散时间戳,但应用程序将每一帧视为[t0,t1)的持续时间,其中。- t0是当前帧的时间戳。- t1是下一帧的时间戳。当为应用中显示的帧打上标签时,该标签适用于该帧的持续时间。帧之间的时间间隔是时间单位,如秒。这个时间间隔就是信号的帧速率。将信号的时间戳指定为持续时间向量。每个时间戳对应于一个帧的开始。2.7.2 主信号当将多个信号加载到一个新的应用程序会话中时,默认情况下,应用程序会将具有最高帧率的信号指定为主信号。当 回放信号或在帧之间导航时,应用程序将显示主信号的所有帧。在应用程序中, 只能标记主信号时间范围内的信号。当查看主信号中的一帧时,应用程序会显示该时间戳处的所有其他信号的帧。在这种情况下,当在帧之间导航时,来自帧率较低的信号的帧有时会重复。考虑一个包含两个信号的应用会话:一个视频v,和一个激光雷达点云序列pc。- 视频的帧率为每秒4帧,每帧持续时间为0.25秒。该信号为主信号。- 点云序列的帧率为每秒2.5帧,每帧持续时间为0.4秒。本图显示了本方案中第一秒内显示的帧。

在时间0时,应用程序会显示每个信号的初始帧:v1代表视频,pc1代表点云序列。当单击 "下一帧 "按钮时,时间会跳转到0.25秒。- 对于视频,应用程序会显示下一帧,v2。- 对于点云序列,应用程序再次显示pc1。应用程序重复点云帧,因为下一帧点云帧,pc2,不会开始,直到0.4秒。要显示此帧,必须将 "当前时间 "参数设置为0.4秒,或者再次单击 "下一帧 "按钮,导航到0.5秒的时间。当你想显示和标注所有信号的所有帧时,请保留帧率最高的信号作为主信号。2.7.3 改变主信号在加载信号后, 可以从 "播放控制设置 "对话框中更改主信号。要打开这个对话框,在滑块下方,点击时钟设置按钮。然后,选择主信号,将主信号更改为加载到应用程序中的不同信号。当将主信号更改为帧率较低的信号时,来自帧率较高的信号的帧有时会被跳过。考虑上一节所述的应用会话,除了用点云序列作为主信号。

当从pc2跳到pc3时,应用程序会完全跳过v3。只有当将 "当前时间 "设置为[0.5,0.75)范围内的时间时,才能看到v3。当想只在同步时间标记信号时,指定帧率最低的信号作为主信号。开始标注后更改主信号会影响现有的场景标签。例如,假设将一个场景标签应用于主信号的整个时间范围。如果 改变主信号,时间范围就会改变。如果新的主信号具有更长的持续时间,那么场景标签就不再适用于整个时间范围。如果 将新信号加载到应用会话中,而该信号的帧率高于现有信号,则应用不会自动将新信号指定为主信号。只有在第一次将信号加载到会话中时,应用程序才会选择一个主信号。要将新信号指定为主信号 信号,从 "播放控制设置 "对话框中的主信号列表中选择该信号。2.7.4 显示所有时间戳在 "播放控制设置 "对话框中, 可以选择所有时间戳来显示所有信号。选择此选项可以验证和可视化加载的帧。不要选择此选项进行标注。当 显示所有时间戳时,帧之间的导航是不均匀的,并且多个信号的帧是重复的。考虑前几节中描述的应用会话,除了显示所有时间戳。本图显示了显示的帧。

2.7.5 指定时间戳可以指定自己的时间戳向量,并使用这些时间戳作为应用程序用于在帧之间导航的时间戳。在"播放控制设置 "对话框中,选择 "来自工作区的时间戳",单击 "来自工作区 "按钮,并从MATLAB工作空间中指定一个持续时间向量。。2.7.6 框架显示和自动化当 选择一个信号进行自动化时,在自动化会话中,应用程序将显示所选信号在指定时间间隔内的所有帧。因为 一次只能自动处理一个信号,所以应用程序会以该信号的帧速率播放信号帧。2.8 标签激光雷达点云用于物体探测通过Ground Truth Labeler应用, 可以对从激光雷达传感器获得的点云数据进行标注。要对点云进行标注, 需要使用立方体,立方体是在点云中的点周围绘制的三维边界框。可以使用立方体标签来创建用于训练物体探测器的地面真实数据。这个例子将引导 使用立方体标记激光雷达点云数据。2.8.1 设置激光雷达点云标签将点云序列加载到应用程序中,并定义一个立方体标签。1 打开 "地面真值标签器 "应用程序。在 MATLAB 命令提示符下,输入此命令。GroundTruthLabeler2 在应用程序工具条上,选择打开 > 添加信号。3 在 "添加/删除信号 "对话框中,将 "源类型 "设置为 "点云序列"。4 在 "文件夹名称 "参数中,浏览包含点云序列的 lidarSequence 文件夹。Matlabroot 是 的 MATLAB 安装文件夹的完整路径,如由matlabroot函数。matlabroot/toolbox/driving/drivingdata/lidarSequence5 单击添加源加载点云序列,使用默认的时间戳。然后,单击 "确定 "关闭 "添加/删除信号 "对话框。应用程序将显示序列中的第一个点云。6 在应用程序左侧的 ROI 标签窗格中,单击 "标签"。7 创建一个名为汽车的矩形/立方体标签。单击 "确定"。

本图显示了遵循这些步骤后的GroundTruth Labeler应用程序设置。2.8.2 缩放、平移和旋转框架缩放、平移和三维旋转选项可帮助在点云中定位和标记感兴趣的对象。使用这些工具放大并居中于第一个点云框架中的被控车辆。被控车辆位于点云的原点。1在框架的右上角,点击放大按钮。2点击被控车辆,直到你放大到足以看到构成它的点。

可选地, 可以使用平移按钮或旋转3D按钮来帮助 查看更多的被控车辆点。要查看查看或旋转点云的其他选项,请单击旋转3D按钮,然后右键单击点云框架。提供的选项与pcshow功能提供的选项相同。2.8.3 隐藏地面点云数据包含了来自地面的点,这可能会增加隔离被控车辆点的难度。应用提供了一个选项,通过使用segroundFromLidarData功能来隐藏地面。将地面点从点云中隐藏起来。在应用工具条上,在Lidar选项卡上,点击隐藏地面。此设置适用于点云中的所有帧。

此选项仅将地面从显示器中隐藏起来,不会从点云中删除地面数据。它不会从点云中删除地面数据。如果在点云中标注了包含隐藏地面点的部分,当 导出地面真值标签时,这些地面点就是该标签的一部分。要配置地面隐藏算法,请单击 "地面设置",并调整 "隐藏地面 "对话框中的选项。标签立方体使用立方体标签为被控车辆贴上标签。1 在左侧的ROI标签窗格中,单击汽车标签。2 通过点击lidarSequence标签选择激光雷达点序列框架。

要启用标签键盘快捷键,必须先选择信号框。3 将指针移动到被控车辆上,直到灰色的预览立方体将被控车辆的点包围起来。包围在预览立方体中的点会以黄色高亮显示。要调整预览立方体的大小,按住A键并向上或向下移动鼠标滚轮。

可选地,要仅在x-、y-或z方向上调整预览立方体的大小,可在按住x、y或z键的同时分别上下移动滚轮。4  单击信号框,绘制立方体。由于应用工具条上默认选择了 "收缩以适应 "选项,因此立方体会收缩以适应其中的点。

要想对点云的标签进行更多控制,请在应用工具条上单击 "卡入集群"。当 在选择此选项的情况下进行标注时,立方体会通过使用segmentLidarData功能卡接到最近的点云集群。要配置点云集群,请单击 "集群设置 "并在对话框中调整选项。要在帧之间导航时查看点云簇,请在此对话框中选择 "查看簇"。在回放信号期间,点云簇的可视化将被禁用。修改立方体标签绘制完立方体标签后,可以调整立方体的大小或移动立方体,使标签更精确。例如,在前面的过程中,"缩小以适应 "选项将立方体标签缩小以适应探测到的被控车辆点。实际的被控车辆比这个立方体稍大。扩大尺寸的这个立方体,直到它更准确地反映被控车辆的尺寸。1 要启用点云标签键盘快捷键,请确认选择lidarSequence标签。2 在信号框中,单击绘制的立方体标签。拖动面来展开立方体。

3  移动立方体,直到它在被控车辆上居中。按住Shift键,拖动立方体的面。2.8.4 将立方体应用于多个框架在帧之间标注对象时,可以复制立方体标签并粘贴到其他帧。1 选择被控车辆的立方体,按Ctrl+C复制。2  在应用程序的底部,单击 "下一帧 "按钮以导航到下一个框架。3 按Ctrl+V将立方体粘贴到帧上。还可以使用自动化算法将一个标签应用于多个帧。该应用程序提供了一个内置的时间插值算法,用于标记中间帧中的点云。2.8.5 配置显示该应用程序为配置信号帧的显示提供了其他选项。2.8.4.1更改彩色地图为了对点云显示进行额外的控制,在Lidar选项卡上, 可以更改colormap选项。也可以通过改变Colormap Value参数来改变colormap值,该参数有以下选项。- Z高度 - Colormap值沿Z轴增加。在寻找高于地面的物体(如交通标志)时选择此选项。- Radial Distance(径向距离)--Colormap值会在远离点云原点的地方增加。在寻找远离原点的物体时选择此选项。2.8.4.2 改变视图在应用程序工具条的激光雷达选项卡上,"相机视图 "部分包含了用于更改查看点云的视角的选项。这些视图以点云原点为中心。这就是被控车辆的假定位置。可以从这些视图中选择。- 鸟瞰图 -- 从被控车车的正上方查看点云。- 追逐视图--从被控车辆后方几米处查看点云。- 被控视图--从被控车辆内部查看点云。这些视图假定车辆沿着点云的正x方向行驶。如果车辆以不同的方向行驶,请在 "被控方向 "参数中设置适当的选项。在验证 的点云标签时,请使用这些视图。在标注时避免使用这些视图。相反,使用默认视图,并通过使用平移、缩放和旋转选项来定位要标记的对象。2.9 创建用于加载自定义Ground Truth数据源的类在Ground Truth Labeler应用中, 可以对来自图像和点云数据源的信号进行标记。这些数据源包括视频、图像序列、点云序列、Velodyne数据包捕获、视频、图像和点云数据。(PCAP)文件和rosbags。要加载应用程序不原生支持的数据源,可以创建一个类来将该源加载到应用程序中。此示例展示了如何使用预定义的数据源类之一,将数据源的信号加载到Ground Truth Labeler应用程序中:vision.labeleler.loading.PointCloudSequenceSource类。该应用程序使用这个特定的类以从文件夹中加载点云数据 (PCD) 或多边形 (PLY) 文件的序列。要开始使用,请打开vision.labeleler.loading.PointCloudSequenceSource 类。使用该类描述的属性和方法来帮助 编写自己的自定义类。edit vision.labeler.loading.PointCloudSequenceSource2.9.1 自定义类文件夹Ground Truth Labeler应用程序仅在这些文件处于+vision/的情况下才会识别数据源类。MATLAB搜索路径上的+labeler/+loading文件夹。vision.labeler.loading.PointCloudSequenceSource类和其他预定义的数据源类都存储在这个文件夹中。matlabroot/toolbox/vision/vision+vision/+labeler/+loading在这个路径中,matlabroot是你的MATLAB文件夹的根目录。将你创建的数据源类保存到这个文件夹中。或者,创建你自己的+vision/+labeler/+loading文件夹,将其添加到MATLAB搜索路径,并将你的类保存到这个文件夹中。2.9.2 类别定义数据源类必须继承自vision.labeleler.loading.MultiSignalSource类。查看vision.labeleler.loading.PointCloudSequenceSource 类的类定义。classdef PointCloudSequenceSource <vision.labeleler.loading.MultiSignalSource当把一个点云序列信号加载到Ground Truth Labeler应用中时,应用会创建一个类的实例,即PointCloudSequenceSource对象。在将此信号标记在app,当导出标签时,导出的groundTruthMultisignal对象会存储这个PointCloudSequenceSource对象的DataSource属性中。在定义你的数据源类时,用你的自定义数据源类的名称来代替PointCloudSequenceSource。2.9.3 类属性数据源类必须定义这些抽象的常量属性。- 名称 - 一个字符串标量,指定数据源的类型。- 描述 - 描述该类的一个字符串标量。在Ground Truth Labeler应用中,当你从 "添加/删除信号 "对话框中加载信号时,Name字符串会作为一个选项出现在Source Type参数中。本图显示了ision.labeleler.loading.PointCloudSequenceSource类的Name字符串。

描述字符串不会出现在对话框中。但是,名称和描述字符串在这个类的实例中被存储为只读属性。这段代码显示了类的名称和属性字符串。vision.labeleler.loading.PointCloudSequenceSourceClass。properties (Constant)Name = "PointCloud Sequence"Description = "A PointCloud sequence reader"end在定义的数据源类时,定义名称和描述属性值以匹配 的自定义数据源的名称和描述。还可以定义任何特定于加载 的数据源的附加私有属性。vision.labeleler.loading.PointCloudSequenceSource 类的特定数据源属性在本示例中没有显示,但 可以在类文件中查看它们。自定义加载面板的方法在数据源类中,customizeLoadPanel方法控制了应用程序的 "添加/删除信号 "对话框中加载信号的面板的显示。这个面板是使用uipanel函数创建的Panel对象。该面板包含从数据源加载信号所需的参数和控件。本图显示了vision.labeleler.loading.PointCloudSequenceSource类的加载面板。在 "源类型 "列表中,当选择点云序列时,应用程序会调用customizeLoadPanel方法,并加载到 点云序列的面板。

这段代码显示了vision.labeleler.loading.PointCloudSequenceSource类的customizeLoadPanel方法。该方法使用uicontrol函数来定义面板中的文本、按钮和参数。function customizeLoadPanel(this,panel) this.Panel = panel;computePositions(this);this.FolderPathText = uicontrol('Parent',this.Panel,... 'Style','text',...'String', 'Folder Name: ',... 'Position',this.FolderPathTextPos,... 'HorizontalAlignment','left',... 'Tag','fileText');this.FolderPathBox = uicontrol('Parent',this.Panel,... 'Style','edit',...'String', '',...'Position', this.FolderPathBoxPos,... 'Tag', 'fileEditBox');this.FolderTextBox = uicontrol('Parent',this.Panel,... 'Style','Text',...'String', 'Only PCD/PLY files are supported.',... 'Position',this.FolderTextPos,...'Tag', 'fileText');this.FolderBrowseButton = uicontrol('Parent',this.Panel,... 'Style','togglebutton',...'String', 'Browse',...'Position',this.FolderBrowseButtonPos,... 'Callback',@this.browseButtonCallback,... 'Tag','browseBtn');this.TimeStampsText = uicontrol('Parent',this.Panel,... 'Style','text',...'String', 'Timestamps: ',... 'Position',this.TimeStampsTxtPos,... 'HorizontalAlignment', 'left',... 'Tag', 'timeStampTxt');this.TimeStampsDropDown= uicontrol('Parent', this.Panel,...'Style', 'popupmenu',...'String', ["Use Default", "From Workspace"],... 'Position',this.TimeStampsDropDownPos,... 'Callback', @this.timeStampsDropDownCallback,... 'Tag', 'timeStampSourceSelectList');this.TimeStampsNote = uicontrol('Parent',this.Panel,... 'Style','text',...'String', 'Default timestamps =(0:numPointClouds-1) s',... 'Position', this.TimeStampsNotePos,... 'HorizontalAlignment','left',...'Tag', 'timeStampNote');end在开发该方法或其他数据源方法时,可以使用静态方法loadPanelChecker来预览 的自定义数据源的加载对话框的显示和功能。这个方法不需要打开一个应用程序会话来使用它。例如,将loadPanelChecker方法与vision.labeleler.loading.PointCloudSequence类一起使用。vision.labeleler.loading.PointCloudSequenceSource.loadPanelChecker2.9.4 获取负载面板数据和负载数据源的方法在 "添加/删除信号 "对话框中,浏览一个信号,设置必要的参数,并点击添加信号源后,应用程序会相继调用这两个方法。- getLoadPanelData--获取输入面板的数据。- loadSource--将数据加载到app中。本图显示了这些方法与添加源头按钮之间的关系,当通过加载点云序列信号时,通过 vision.labeleler.loading.PointCloudSequenceSource类。

当定义一个自定义的数据源时,必须定义getLoadPanelData方法,它将返回这些输出。- sourceName - 数据源的名称- sourceParams - 一个包含加载数据源所需信息的字段的结构。这段代码显示的是vision.labeleler.load.PointCloudSequenceSource类。该方法将sourceName设置为在对话框的文件夹名称参数中输入的名称,将sourceParams设置为一个空结构。如果将Timestamps参数设置为From Workspace并加载了时间戳,那么应用程序用这些时间戳填充这个结构。function [sourceName, sourceParams] = getLoadPanelData(this);sourceName = string(this.FolderPathBox.String); sourceParams = struct();end还必须在自定义数据类中定义loadSource方法。该方法必须将从 getLoadPanelData 方法返回的 sourceName 和 sourceParams 作为输入。该方法还必须填充这些属性,这些属性存储在应用程序创建的数据源对象实例中。- SignalName - 数据源中每个信号的字符串标识符。- SignalType -vision.labeleler.loading.SignalType枚举的数组,定义了数据源中每个信号的类型。- 时间戳 - 数据源中每个信号的时间戳的向量或单元格阵列- SourceName - 数据源的名称- SourceParams - 一个包含加载数据源所需信息的字段的结构。这段代码显示了vision.labeleler.loading.PointCloudSequenceSource类的loadSource方法。该方法执行这些操作。1 检查点云序列的扩展名是否正确,并将读取点云所需的信息保存到fileDatastore对象中。2 设置数据源对象的时间戳属性。- 如果时间戳是从工作区变量中加载的(Timestamps = From workpace),那么该方法将Timestamp设置为存储在sourceParams输入中的时间戳。- 如果时间戳是从点云序列本身导出的(Timestamps = Use Default),那么该方法将Timestamp设置为秒的持续时间向量,有一个每个点云的秒数。3 验证加载的点云序列。4 将SignalName属性设置为数据源文件夹的名称。5 将SignalType属性设置为点云信号类型。6 将 SourceName 和 SourceParams 属性设置为 SourceName 和 SourceParams。分别为:function loadSource(this, sourceName,sourceParams)% Load fileext = {'.pcd','.ply'};this.Pcds = fileDatastore(sourceName,'ReadFcn', @pcread, 'FileExtensions',ext);% Populate timestampsif isempty(this.Timestamp)if isfield(sourceParams, 'Timestamps')setTimestamps(this, sourceParams.Timestamps); elsethis.Timestamp= {seconds(0:1:numel(this.Pcds.Files)-1)'};end elseif ~iscell(this.Timestamp)this.Timestamp = {this.Timestamp};endendimport vision.internal.labeler.validation.* checkPointCloudSequenceAndTimestampsAgreement(this.Pcds,this.Timestamp{1});% Populate signal names and types[~, folderName, ~] =fileparts(sourceName);this.SignalName = makeValidName(this, string(folderName),"pointcloudSequence_");this.SignalType = vision.labeler.loading.SignalType.PointCloud;this.SourceName= sourceName; this.SourceParams = sourceParams;end2.9.5 读取帧的方法最后一个必须定义的方法是readFrame方法。该方法从数据源中存储的信号中读取一个帧。每次导航到一个新的帧时,应用程序都会调用这个方法。Timestamp属性中特定时间戳的索引被传递给这个方法。这段代码显示了 vision.labeleler.loading.PointCloudSequenceSource 类的 readFrame 方法。该方法通过使用pcread函数从点云序列中读取帧。function frame = readFrame(this,signalName, index) if ~strcmpi(signalName, this.SignalName)frame = []; elseframe = pcread(this.Pcds.Files{index});endend还可以定义任何特定于加载数据源的附加私有属性。vision.labeleler.loading.PointCloudSequenceSource类的特定源方法在本例中没有显示,但 可以在类文件中查看它们。2.9.6 使用预定义的数据源类这个例子展示了如何使用vision.labeleler.loading.PointCloudSequenceSource类来帮助 创建自己的自定义类。这个表格显示了完整的数据源类列表,可以将其作为 自己的类的起点。ClassData Source Loaded by ClassCommand to View  Class Source Codevision.labeler.loading.V  ideoSourceVideo fileeditvision.labeler.loading.vision.labeler.loading.I  mageSequenceSourceImage sequence  foldereditvision.labeler.loading.vision.labeler.loading.V elodyneLidarSourceVelodyne packet capture (PCAP) fileeditvision.labeler.loading.vision.labeler.loading.R  osbagSourceRosbag fileeditvision.labeler.loading.vision.labeler.loading.P  ointCloudSequenceSourcePoint cloud  sequence foldereditvision.labeler.loading.vision.labeler.loading.C  ustomImageSourceCustom image formateditvision.labeler.loading.点赞超过10个本周更新第三讲

(0)

相关推荐