主要内容

在多个信号中自动标记地面真相

类同时自动标记多个信号地面真相标签应用程序和AutomationAlgorithm接口。本例中使用的自动化算法使用相机-激光雷达校准参数,根据相应图像帧中车辆的标签位置估计点云帧中车辆的标签位置。

Ground Truth Labeler应用

良好的地面真实数据对于开发驾驶算法和评估其性能至关重要。然而,创建一组丰富多样的带注释的驾驶数据需要大量的时间和资源。Ground Truth Labeler应用程序使这一过程变得高效。你可以使用这个应用程序作为一个完全手动的注释工具来标记车道边界、车辆包围框和其他视觉系统感兴趣的对象。然而,手工标注需要大量的时间和资源。该应用程序还提供了一个框架来创建算法,以扩展和自动化标签过程。您可以创建和使用算法来快速标记整个数据集,然后使用更高效、更短的手动验证步骤进行后续操作。您还可以编辑自动化步骤的结果,以解释自动化算法可能遗漏的具有挑战性的场景。

本示例描述了创建一个算法,该算法可用于Ground Truth Labeler应用程序,自动检测图像中的车辆,并使用相机-激光雷达校准参数估计它们在相应点云中的位置。

使用ACF车辆检测器检测车辆

为了检测图像中的车辆,自动化算法使用预训练的聚合通道特征(ACF)车辆检测器,vehicleDetectorACF.通过加载样本图像和ACF车辆检测器,检测图像中的车辆,并在图像中的车辆周围插入2-D包围框,预览算法的工作原理。

从MAT文件中加载数据并提取图像。数据= load(fullfile(toolboxdir(激光雷达的),“lidardata”低成本航空的“bboxGT.mat”));I = data.im;为车辆装载预先训练好的检测器。。探测器=车辆检测器“front-rear-view”);检测车辆并显示边界框。[imBboxes,~] = detect(检测器,I);Iout = insertShape(I,“矩形”imBboxes,“线宽”4);数字imshow(Iout)标题(检测到车辆的

图中包含一个轴对象。标题为Detected Vehicles的axes对象包含一个image类型的对象。

如果您有可用的相机校准信息,您可以通过过滤检测中的假阳性来改进此检测器。的使用单目摄像机的视觉感知示例描述如何创建一个预训练的车辆检测器,并将其配置为使用校准的单目摄像机配置来检测车辆包围盒。

点云中车辆三维包围盒的估计

为了从图像帧中相应的检测到的车辆中估计点云帧中的车辆,该算法使用bboxCameraToLidar(激光雷达工具箱)函数。该函数使用激光雷达到相机的标定参数,在二维包围盒的基础上估计三维包围盒。为了估计边界框,该函数将相机的固有参数作为输入,cameraIntrinsics,以及摄像头到激光雷达的刚性转换,rigid3d

通过加载图像对应的点云,估计点云中车辆的三维包围盒,并在点云中插入车辆周围的包围盒,预览算法的工作原理。

提取点云。ptCloud = data.pc;提取相机的内在参数。intrinsic = data.cameraParams;提取相机到激光雷达的刚性变换。。tform = data.camToLidar;估计点云中的边界框。pcBboxes = bboxCameraToLidar(imBboxes, ptCloud, intrinsic, tform);显示点云中的包围框。figure ax = pcshow(ptCloud.Location);showShape (“长方体”pcBboxes,“父”ax,“不透明度”, 0.1,“颜色”,[0.06 1.00 1.00],“线宽”, 0.5)变焦(ax, 1.5)标题(“点云的估计边界盒”)举行

准备多信号车辆探测器自动化课程

为了将多信号车辆探测器算法合并到Ground Truth Labeler应用程序的自动化工作流程中,构造一个继承自抽象基类的类,vision.labeler.AutomationAlgorithm.这个基类定义了应用程序用于配置和运行自定义算法的方法的属性和签名。Ground Truth Labeler应用程序提供了一种获取初始自动化类模板的方便方法。详细信息请参见创建自动标记算法.的MultiSignalVehicleDetector类基于此模板,并为您提供了一个可随时使用的自动化类,用于图像中的车辆检测和点云中的车辆包围框估计。类的注释概述了实现每个API调用所需的基本步骤。

步骤1包含定义算法名称和描述以及算法使用方向的属性。

% ---------------------------------------------------------------------- % 步骤1:定义所需的属性描述算法,%,包括名称、描述和UserDirections。properties(Constant) % Name算法名称%指定算法名称的字符向量。名称= '多信号车辆探测器';% Description算法描述%指定算法简短描述的字符向量。描述=['使用ACF车辆检测器检测车辆'…'图像并在点云中估计它们。'];% UserDirections算法使用方向%字符向量的单元格数组,用于指定%算法用户遵循的方向。UserDirections ={['选择一个矩形ROI标签'…’将对象标记为Vehicle。'],……['点击设置和激光雷达相机校准'… 'Parameters tab, load the cameraIntrinsics and rigid3d ' ... 'objects from the workspace.'], ... ['Specify additional parameters under Settings.'], ... ['Click Run to detect vehicles in each image and point cloud.'], ... ['Review automated labels manually. You can modify, delete ', ... 'and add new labels.'], ... ['If you are not satisfied with the results, click Undo ' ... 'Run. Click Settings to modify algorithm settings and click ', ... 'Run again.'] ... ['When you are satisfied with the results, click Accept and ', ... 'return to manual labeling.']}; end

步骤2包含核心算法的自定义属性。

% --------------------------------------------------------------------- % 第二步:定义属性被用来管理算法执行。properties % SelectedLabelName所选标签名称%所选标签名称。算法检测到的车辆将%被分配这个变量名。SelectedLabelName检测器检测器%预训练的车辆检测器,类% acfObjectDetector的对象。检测器% VehicleModelName车辆检测器模型名称%预训练的车辆检测器模型名称。VehicleModelName = 'full-view';% OverlapThreshold重叠阈值%消除参考包围框周围重叠包围框的阈值%,取值范围在0 ~ 1之间。边界框重叠比率分母'RatioType'被设置为% 'Min'。OverlapThreshold = 0.45;% ScoreThreshold分类评分阈值%检测分数低时拒绝检测的阈值。 ScoreThreshold = 20; % ConfigureDetector Detection configuration flag % Boolean value that determines whether the detector is % configured using monoCamera sensor. ConfigureDetector = false; % SensorObj monoCamera sensor % Monocular camera sensor object, monoCamera, used to configure % the detector. A configured detector runs faster and can % potentially result in better detections. SensorObj = []; % SensorStr monoCamera sensor variable name % Character vector specifying the monoCamera object variable name % used to configure the detector. SensorStr = ''; % VehicleWidth Vehicle width % Vehicle width used to configure the detector, specified as % [minWidth, maxWidth], which describes the approximate width of the % object in world units. VehicleWidth = [1.5 2.5]; % VehicleLength Vehicle length % Vehicle length used to configure the detector, specified as % [minLength, maxLength] vector, which describes the approximate % length of the object in world units. VehicleLength = []; % IntrinsicsObj Camera intrinsics % cameraIntrinsics object, which represents a projective % transformation from camera to image coordinates. IntrinsicsObj = []; % IntrinsicsStr cameraIntrinsics variable name % cameraIntrinsics object variable name. IntrinsicsStr = ''; % ExtrinsicsObj Camera-to-lidar rigid transformation % rigid3d object representing the 3-D rigid geometric transformation % from the camera to the lidar. ExtrinsicsObj = []; % ExtrinsicsStr rigid3d variable name % Camera-to-lidar rigid3d object variable name. ExtrinsicsStr = ''; % ClusterThreshold Clustering threshold for two adjacent points % Threshold specifying the maximum distance between two adjacent points % for those points to belong to the same cluster. ClusterThreshold = 1; end

步骤3处理函数定义。

第一个函数,万博1manbetxsupportsMultisignalAutomation检查算法是否支持多个信号。万博1manbetx对于多信号车辆探测器,你同时加载图像和点云信号,所以成功设置为真正的

function success = 万博1manbetxsupportsMultisignalAutomation(~) %支持MultiSignal。成功=真实;结束

下一个函数,checkSignalType检查自动化只支持适当类型的信号。万博1manbetx多信号车辆探测器必须支持不同类型的信号万博1manbetx图像而且PointCloud,所以这个版本的函数检查这两种信号类型。

function isValid = checkSignalType(signalType) %只有视频/图像序列和点云信号数据%有效。isValid = any(signalType == vision. labler .loading. signalType . image) &&…any(signalType == vision. labler .loading. signalType . pointcloud);结束

下一个函数,checkLabelDefinition,检查是否只有适当类型的标签启用了自动化。对于图像和点云信号中的车辆检测,您只检查类型的标签矩形/长方体启用,因此此版本的函数检查类型标签。

只有矩形/长方体ROI标签定义对%车辆检测器有效。isValid = (labelDef。Type == labelType。长方体||labelDef.Type == labelType.Rectangle); end

下一个函数,checkSetup,检查是否只选择了一个ROI标签定义进行自动化。

函数isReady = checkSetup(algObj, ~) %是否有一个选定的ROI标签定义要自动化?isReady = ~isempty(algObj.SelectedLabelDefinitions);结束

接下来,settingsDialog函数获取并修改第2步中定义的属性。此API调用允许您创建一个对话框,当用户单击设置按钮。自动化选项卡。要创建此对话框,请使用对话框函数创建一个模态窗口,以要求用户指定cameraIntrinsics对象和rigid3d对象。的multiSignalVehicleDetectorSettings方法包含用于设置的代码,并添加输入验证步骤。

调用对话框,输入相机的固有值和相机到激光雷达的刚性转换,以及选择预训练模型、重叠阈值、检测分数阈值和聚类阈值的选项。可选地,输入一个%校准的monoCamera传感器来配置检测器。multiSignalVehicleDetectorSettings (algObj);结束

步骤4指定执行函数。的初始化函数根据应用程序中现有的标签填充初始算法状态MultiSignalVehicleDetector类,初始化函数已自定义,以存储所选标签定义的名称,并加载预训练的ACF车辆检测器,并将其保存到探测器财产。

函数initialize(algObj, ~) %存储选定标签定义的名称。使用% name标记检测到的车辆。algObj。SelectedLabelName = algObj.SelectedLabelDefinitions.Name;使用预训练的模型初始化车辆检测器。。algObj。检测器= vehicleDetectorACF(algObj.VehicleModelName);结束

接下来,运行函数定义了该自动化类的核心车辆检测算法。的运行函数为图像和点云序列的每一帧调用,并期望自动化类返回一组标签。的运行函数MultiSignalVehicleDetector包含前面描述的用于检测图像帧中的二维车辆包围盒和估计点云帧中的三维车辆包围盒的逻辑。

function autoLabels = run(algObj, I) % autoLabels标记一个长度与%信号数量相同的单元格数组。autoLabels = cell(size(I,1),1);获取Image和PointCloud帧的索引。if isa(I{1,1},"pointCloud") pcIdx = 1;imIdx = 2;else imIdx = 1;pcIdx = 2;检测图像帧上的包围框。seltedbboxes = detectVehicle(algObj, I{imIdx,1});估计点云框架上的边界框。 if ~isempty(selectedBboxes) % Store labels from the image. imageLabels = struct('Type', labelType.Rectangle, ... 'Name', algObj.SelectedLabelDefinitions.Name, ... 'Position', selectedBboxes); autoLabels{imIdx, 1} = imageLabels; % Remove the ground plane for the point cloud. groundPtsIndex = segmentGroundFromLidarData(I{pcIdx,1}, ... "ElevationAngleDelta", 15, "InitialElevationAngle", 10); nonGroundPts = select(I{pcIdx,1}, ~groundPtsIndex); % Predict 3-D bounding boxes. pcBboxes = bboxCameraToLidar(selectedBboxes, nonGroundPts, algObj.IntrinsicsObj, ... algObj.ExtrinsicsObj, "ClusterThreshold", algObj.ClusterThreshold); % Store labels from the point cloud. if(~isempty(pcBboxes)) pcLabels = struct('Type', labelType.Cuboid,... 'Name', algObj.SelectedLabelDefinitions.Name,... 'Position', pcBboxes); autoLabels{pcIdx, 1} = pcLabels; else autoLabels{pcIdx, 1} = {}; end else autoLabels{imIdx, 1} = {}; autoLabels{pcIdx, 1} = {}; end end

最后,终止函数处理自动化完成后所需的任何清理或删除。该算法不需要任何清理,因此函数为空。

函数终止(~)结束

在应用程序中使用多信号车辆探测器自动化类

上一节中描述的属性和方法在MultiSignalVehicleDetector自动化算法类文件。在应用程序中使用这个类:

创建文件夹结构+视觉/ +贴标签机,并将自动化类复制到其中。

mkdir(“+视觉/ +贴标签机”);拷贝文件(fullfile (matlabroot“例子”,“驾驶”,“主要”,“MultiSignalVehicleDetector.m”),…“+视觉/ +贴标签机”);

下载点云序列(PCD)和图像序列。为了说明问题,本例使用Ouster OS1激光雷达传感器在高速公路上收集的WPI激光雷达数据和安装在ego车辆上的前置摄像头收集的WPI图像数据。执行以下代码块下载并保存激光雷达和图像数据到一个临时文件夹中。根据您的互联网连接,下载过程可能需要一些时间。该代码暂停MATLAB®执行,直到下载过程完成。或者,您可以使用web浏览器将数据集下载到本地磁盘并提取文件。

将图像序列下载到临时位置。

imageURL = '//www.tianjin-qmedu.com/万博1manbetxsupportfiles/lidar/data/WPI_ImageData.tar.gz';imageDataFolder = fullfile(tempdir, 'WPI_ImageData',filesep);imageDataTarFile = imageDataFolder + "WPI_ImageData.tar.gz";if ~exist(imageDataFolder,'dir') mkdir(imageDataFolder) end if ~exist(imageDataTarFile, 'file') disp('下载WPI图像驱动数据(225 MB)…');websave (imageDataTarFile imageURL);解压(imageDataTarFile imageDataFolder);检查image tar.gz文件是否已下载,但未解压。if ~exist(fullfile(imageDataFolder,'imageData'),'dir') untar(imageDataTarFile, imageDataFolder) end

出于说明目的,本示例仅使用WPI图像序列的一个子集,即帧920-940。要将图像子集加载到应用程序中,请将图像复制到一个文件夹中。

创建新文件夹并复制图像。imDataFolder = imageDataFolder + "imageDataSequence";if ~exist(imDataFolder,'dir') mkdir(imDataFolder);文件名= strcat(num2str(I,'%06.0f'),'.jpg');source = fullfile(imageDataFolder,'imageData',filename);destination = fullfile(imageDataFolder,'imageDataSequence',filename);拷贝文件(来源、目的地)

将点云序列下载到临时位置。

lidarURL = '//www.tianjin-qmedu.com/万博1manbetxsupportfiles/lidar/data/WPI_LidarData.tar.gz';lidarDataFolder = fullfile(tempdir,'WPI_LidarData',filesep);lidarDataTarFile = lidarDataFolder + "WPI_LidarData.tar.gz";if ~exist(lidarDataFolder) mkdir(lidarDataFolder) end if ~exist(lidarDataTarFile, 'file') disp('下载WPI激光雷达驾驶数据(760 MB)…');websave (lidarDataTarFile lidarURL);解压(lidarDataTarFile lidarDataFolder);检查lidar tar.gz文件是否下载,但未解压。if ~exist(fullfile(lidarDataFolder,'WPI_LidarData.mat'),'file') untar(lidarDataTarFile,lidarDataFolder);结束

Ground Truth Labeler应用程序支持由PC万博1manbetxD或PLY文件组成的点云序列的加载。将下载的点云数据保存到PCD文件中。出于说明目的,在本例中,只保存WPI点云数据的一个子集,即帧920-940。

将下载的激光雷达数据加载到工作空间。负载(fullfile (lidarDataFolder WPI_LidarData.mat),“lidarData”);lidarData =重塑(lidarData,size(lidarData,2),1);创建新文件夹并将激光雷达数据写入PCD文件。pcdDataFolder = lidarDataFolder + "lidarDataSequence";if ~exist(pcdDataFolder, 'dir') mkdir(fullfile(lidarDataFolder,'lidarDataSequence'));end disp('保存WPI激光雷达驾驶数据到PCD文件…');for i = 920:940 filename = strcat(fullfile(lidarDataFolder,'lidarDataSequence',filesep),…num2str(我,“% 06.0 f”)、“.pcd”);我pcwrite (lidarData{},文件名); end

校准信息预期为中所述的内在和外在(刚性变换)参数的形式激光雷达和相机校准(激光雷达工具箱).加载相机内部函数,这些函数存储在cameraIntrinsics对象,以及相机到激光雷达的刚性变换,其中存储在rigid3d对象添加到工作区。本例中的WPI数据经过校准,内在和外在(相机到激光雷达转换)参数保存在MAT文件中。

data = load(fullfile(toolboxdir('lidar'),'lidardata','lcc','bboxGT.mat'));cameraParams = data.cameraParams;camToLidar = data.camToLidar;

打开Ground Truth Labeler应用。

imageDir = fullfile(tempdir, 'WPI_ImageData', 'imageDataSequence');pointCloudDir = fullfile(tempdir, 'WPI_LidarData', 'lidarDataSequence');groundTruthLabeler

在应用程序工具条上,选择进口然后添加信号.在添加/删除信号窗口中,加载图像序列。

  1. 源类型图像序列

  2. 控件指定的位置上的图像序列文件夹imageDir变量。

  3. 使用默认时间戳,单击添加源.图像序列文件夹,imageDataSequence,添加到信号源表中。

在应用程序工具条上,选择进口然后添加信号.在添加/删除信号窗口中,加载点云序列。

  1. 源类型点云序列

  2. 控件指定的位置上的点云序列文件夹pointCloudDir变量。

  3. 使用默认时间戳,单击添加源.点云序列文件夹,lidarDataSequence,添加到信号源表中。

点击好吧将信号导入到应用程序中。要查看信号并排,在标签选项卡上,单击显示网格,并以1乘2的网格显示信号。

ROI标签选项卡,单击标签,并定义名称为的ROI标签车辆还有一种矩形或长方体,如图所示。可选地,选择颜色,然后单击好吧

选择两个信号进行自动化。在标签选项卡上,选择算法然后选择信号,并选择两个信号。点击好吧

选择算法中,选择刷新列表.然后,选择算法然后多信号车辆探测器.如果没有看到此选项,请验证当前工作文件夹是否有一个名为+视觉/ +贴标签机,文件名为MultiSignalVehicleDetector.m在里面。

AutomateVehicleDetectionSelectAlgorithm.png

点击自动化.该应用程序为所选信号打开一个自动化会话,并显示使用算法的方向。

将内置相机参数加载到自动化会话中。

  1. 自动化选项卡上,单击设置

  2. 激光雷达相机校准参数选项卡上,单击从工作区导入相机intrinsic

  3. 导入相机固有参数,cameraParams,来自MATLAB工作区。点击好吧

AutomateMultiSignalsLoadCameraParams.png

将摄像头到激光雷达的转换加载到自动化会话中。

  1. 激光雷达-相机校准参数选项卡上,单击从工作空间导入相机到激光雷达的转换

  2. 导入转换,camToLidar,来自MATLAB工作区。点击好吧

AutomateMultiSignalsLoadCamToLidar.png

根据需要修改其他车辆检测器设置,单击好吧.然后,在自动化选项卡上,单击运行.所创建的算法在序列的每一帧上执行,并通过使用车辆标签类型。应用程序完成自动化运行后,使用滑块或方向键滚动序列,以定位自动化算法标记错误的帧。通过调整检测到的边界框或添加新的边界框来手动调整结果。

当你对整个序列检测到的车辆包围框感到满意时,单击接受.然后,您可以继续手动调整标签或将标记的基本真理导出到MATLAB工作区。

您可以使用本示例中描述的概念创建自己的自定义多信号自动化算法,并扩展应用程序的功能。

另请参阅

应用程序

功能

对象

相关的话题