MATLAB - 激光雷达 - 相机联合标定(Lidar-Camera Calibration)(一)+https://developer.aliyun.com/article/1585282
三、开始使用激光雷达相机标定器
激光雷达相机标定程序可让您通过估算激光雷达传感器和相机之间的刚性变换,以交互方式在两者之间执行标定。
本专题将向您展示 Lidar Camera Calibrator 应用程序的工作流程,以及您可以用来分析和改进结果的功能。标定过程的第一个也是最重要的部分是获取准确有用的数据。有关获取数据的指南和技巧,请参阅标定指南。
3.1 加载数据
要打开 Lidar Camera Calibrator 应用程序,请在 MATLAB® 命令提示符下输入此命令。
lidarCameraCalibrator
或者,也可以从 "应用程序 "选项卡的 "图像处理和计算机视觉 "下打开该应用程序。
应用程序打开时是一个空会话。该程序可读取 PLY 和点云数据 (PCD) 格式的点云数据,以及 imformats 支持的任何格式的图像。如果您的数据存储在 rosbag 文件中,请参阅 "从 Rosbag 文件读取激光雷达和相机数据 "教程进行相应转换。
将标定数据加载到应用程序中。
- 在应用程序工具条上,选择导入 > 导入数据,打开导入数据对话框。
- 在图像文件夹框中,输入包含要加载的图像文件的文件夹路径。或者,选择 "浏览 "导航到包含图像的文件夹,然后单击 "选择文件夹"。
- 在点云文件夹框中,输入包含要加载的 PCD 或 PLY 文件序列的文件夹路径。或者,选择 "浏览 "导航到包含文件的文件夹,然后单击 "选择文件夹"。
- 在 "棋盘格设置 "部分,输入标定棋盘格参数。在 "方格尺寸 "框中指定每个棋盘方格的尺寸,并从框旁边的列表中选择测量单位。
- 在填充框中,输入棋盘的填充值。有关填充的更多信息,请参阅棋盘填充。单击 "确定 "导入数据。
输入的图像和点云文件必须具有相同的名称。应用程序会使用文件名将图像和点云数据配对。它会将图像与具有相同文件名的相应点云进行比较。
提示
要在会话中的任意位置向会话添加更多图像和点云,请选择导入 > 向会话添加数据。
3.2 检测特征
加载图像和点云数据后,应用程序会对其执行自动特征检测。应用程序会使用指定的棋盘格参数,从图像数据中检测棋盘格角,从点云数据中检测棋盘格面。
当应用程序在图像和点云中都检测到棋盘格特征时,会将其显示在 "接受数据 "窗格中,并接受图像和点云数据对进行标定。
如果应用程序在图像、点云或两者中均未检测到特征,则会将其显示在 "拒绝数据 "窗格中。您可以使用 "选择感兴趣区域 "或 "选择棋盘格区域 "工具来检测剔除数据中的特征。
从数据浏览器的 "接受数据 "或 "剔除数据 "窗格中选择数据对,将其显示在可视化窗格中。
您可以在应用程序工具条的 "操作 "部分使用这些工具来处理接受和剔除的数据对。
- 移动到已接受数据 - 将数据对从已拒绝数据移动到已接受数据。
- 移动到拒绝数据 - 将数据对从接受数据移动到拒绝数据。
- 删除 - 删除选定的数据对。
有关在数据浏览器中使用的键盘快捷键列表,请参阅数据浏览器。
加载相机固有参数
默认情况下,应用程序会在内部计算输入图像数据中的相机固有参数,以执行特征检测。您也可以在应用程序工具条的 "相机固有参数 "部分选择 "使用固定固有参数",将相机固有参数加载到应用程序中。在打开的对话框中,指定相机固有参数的位置并将其加载到应用程序中。您可以从文件或 MATLAB 工作区加载固有参数。然后,在 "检测特征 "部分,选择 "检测 "以使用新的固有参数重新检测输入数据中的特征。
要将相机固有参数重置为应用程序计算的默认值,请选择计算固有参数。要加载不同的固有参数值,请选择使用固定固有参数,然后选择加载固有参数。
选择感兴趣的区域
指定感兴趣区域来检测特征可以改善特征检测结果,尤其是在剔除数据中。要指定感兴趣区域,首先要从应用工具条中选择编辑 ROI。这将打开 "编辑 ROI "选项卡。
在 "编辑 ROI "选项卡中,应用程序会显示带有 ROI 立方体的点云数据。调整 ROI 立方体,使其与包含棋盘格的区域更加匹配。这样可以将特征检测限制在特定区域内,从而减少数据剔除并提高性能。
使用以下步骤,使用 "编辑 ROI "微调点云数据中的棋盘格检测。
- 选择任意数据对。您可以选择一个被剔除的数据对来调整 ROI。
- 要调整 ROI,请在 "编辑 ROI "选项卡的点云窗格中,暂停 ROI 立方体。指针会变成一个手形符号。单击 ROI 的任意一侧并拖动,调整长方体尺寸。要锁定长方体尺寸,请右键单击长方体并选择锁定尺寸。您还可以撤销和重做对 ROI 的修改。
- 选择 "捕捉到 ROI "可视化 ROI 长方体内的棋盘格点,并相应调整长方体大小。要查看整个点云,请清除 "捕捉到 ROI"。
- 您可以更新每个单独坐标系的 ROI,也可以一次性更新所有坐标系的 ROI。
- 选择 "应用 "保存更改,或选择 "取消 "放弃更改。
更新点云帧的 ROI 后,在应用程序工具条的 "标定 "选项卡上的 "检测特征 "部分,选择 "检测 "以重新检测所选 ROI 内输入数据中的特征。
提示
使用键盘快捷键可以更加交互式地执行这些任务。有关 "编辑 ROI "键盘快捷键,请参阅 "编辑 ROI"。
选择棋盘格区域
要进一步调整特征检测,请单击应用程序工具条上的 "选择棋盘区域"。应用程序会打开 "选择棋盘 "选项卡,您可以在其中手动选择任意点云坐标系中的棋盘点。
在 "选择棋盘 "选项卡中
- 选择任意数据对。您可以选择一个被剔除的数据对,然后在点云中找到棋盘格。
- 使用点云显示轴工具栏中的缩放和旋转选项来定位棋盘格。
- 单击 "选择棋盘格",光标将变为十字准线。
- 在棋盘上单击并拖动光标。这时会出现一个矩形选区,选区内的点以红色高亮显示。或者,也可以选择坐标轴工具栏上的刷子/选择数据。
- 选择点后,旋转点云,检查是否有背景点被选中。如果您的选择包含不需要的点,请选择 "擦除 "重新开始。
- 选择 "应用 "保存选中的点,或选择 "取消 "放弃选中的点。
棋盘格选择只适用于所选点云。更新棋盘格点后,选择 "检测 "可使用更新后的棋盘格点重新检测输入数据中的地物。
特征检测设置
应用程序提供了这些特征检测设置,您可以利用它们调整检测参数。
- 移除地面 - 从点云中移除地面点。该应用程序使用 pcfitplane 函数估算地平面。移除地平面功能默认已启用。选择 "移除地面 "可将其清除。
- 聚类阈值 - 以米为单位指定点云中两个相邻点的聚类阈值。聚类过程基于相邻点之间的欧氏距离。如果相邻两点之间的距离小于聚类阈值,则两点属于同一聚类。低分辨率激光雷达传感器需要较高的聚类阈值,而高分辨率激光雷达传感器则需要较低的聚类阈值。
- 维度容差 - 矩形平面维度的不确定性容差,指定范围为 [0,1]。尺寸公差越大,表示矩形平面尺寸的公差范围越大。
更新新的检测参数后,选择 "检测 "以重新检测输入数据中的特征。
3.3 标定
对检测结果满意后,选择标定按钮对传感器进行标定。如果您有估计的变换矩阵,请选择初始变换从文件或工作区加载变换矩阵。本应用程序假定激光雷达传感器和相机之间的旋转角度在 [-45 45 ]范围内,单位为度,沿每个轴。如果旋转角度超出此范围,请使用初始变换指定初始变换以提高标定精度。
标定完成后,应用程序界面会显示图像,并将点云中的棋盘格点投射到图像上。应用程序使用 projectLidarPointsOnImage 函数将激光雷达点投射到图像上。使用 fuseCameraToLidar 函数将图像的颜色信息与点云数据融合。
该程序还利用误差图提供转换矩阵的不准确度指标。图中说明了每个数据对中的这些误差:
- 平移误差 - 点云中棋盘格平面的中心点坐标与相应图像中的中心点坐标之差。应用程序以米为单位返回误差值。
- 旋转误差 - 点云中棋盘格平面所定义的法线角度与相应图像中的法线角度之间的差值。应用程序使用棋盘格角坐标估算图像中的平面。应用程序会以度数为单位返回误差值。
- 重投影误差-- 点云中棋盘格平面的投影(变换)中心点坐标与相应图像中棋盘格平面的投影(变换)中心点坐标之差。应用程序以像素为单位返回误差值。
在数据浏览器中选择一个数据对时,误差图中的相应条形图将以深蓝色突出显示。您可以通过删除异常值来调整标定结果。垂直拖动每个图上的红线可设置误差限值。应用程序会选择误差值大于误差限值的所有数据对作为异常值,并在数据浏览器中以蓝色高亮显示误差条及其对应的数据对。右键单击数据浏览器中任何选定的数据对,然后选择删除和重新校准,即可删除异常值并重新校准传感器。删除异常值可以提高标定精度。有关误差图的键盘快捷键列表,请参阅误差图。
3.4 导出结果
您可以将转换矩阵和误差指标作为变量导出到工作区或 MAT 文件中。您可以生成完整应用工作流程的 MATLAB 脚本,以便在项目中使用。
3.5 局限性
激光雷达相机标定程序有以下限制:
- 从 "导出">"生成 MATLAB 脚本 "生成的脚本不包括使用 "选择棋盘格 "功能手动选择的任何棋盘格区域。在脚本中,棋盘格区域是在指定的 ROI 中检测到的。
- 使用 "选择棋盘格 "功能手动选择棋盘格区域后,返回 "标定 "选项卡时,只能在查看整个点云时(清除 SnapToROI 时)看到选定的点(红色突出显示)。
四、从 Rosbag 文件读取激光雷达和相机数据
本例演示了如何从 rosbag 文件中读取并保存图像和点云数据。本例还展示了如何为激光雷达相机标定准备数据。
使用本示例末尾定义的 helperDownloadRosbag 辅助函数下载 rosbag 文件。
path = helperDownloadRosbag;
从 bag 文件中读取信息。
bag = rosbag(path);
从 rosbag 中选择图像和点云消息,并通过使用相应的话题名称从文件中选择消息子集。您还可以使用时间戳过滤数据。更多信息,请参阅选择(ROS 工具箱)功能。
imageBag = select(bag,'Topic','/camera/image/compressed'); pcBag = select(bag,'Topic','/points');
阅读所有消息。
imageMsgs = readMessages(imageBag); pcMsgs = readMessages(pcBag);
要为激光雷达相机标定准备数据,必须对两个传感器的数据进行时间同步。为选定的话题创建时间序列(ROS 工具箱)对象并提取时间戳。
ts1 = timeseries(imageBag); ts2 = timeseries(pcBag); t1 = ts1.Time; t2 = ts2.Time;
要进行准确的标定,必须以相同的时间戳采集图像和点云。根据时间戳匹配两个传感器的相应数据。为考虑不确定性,使用 0.1 秒的余量。
k = 1; if size(t2,1) > size(t1,1) for i = 1:size(t1,1) [val,indx] = min(abs(t1(i) - t2)); if val <= 0.1 idx(k,:) = [i indx]; k = k + 1; end end else for i = 1:size(t2,1) [val,indx] = min(abs(t2(i) - t1)); if val <= 0.1 idx(k,:) = [indx i]; k = k + 1; end end end
创建保存有效图像和点云的目录。
pcFilesPath = fullfile(tempdir,'PointClouds'); imageFilesPath = fullfile(tempdir,'Images'); if ~exist(imageFilesPath,'dir') mkdir(imageFilesPath); end if ~exist(pcFilesPath,'dir') mkdir(pcFilesPath); end
提取图像和点云。将文件命名并保存在各自的文件夹中。将相应的图像和点云保存在同一编号下。
for i = 1:length(idx) I = readImage(imageMsgs{idx(i,1)}); pc = pointCloud(readXYZ(pcMsgs{idx(i,2)})); n_strPadded = sprintf('%04d',i) ; pcFileName = strcat(pcFilesPath,'/',n_strPadded,'.pcd'); imageFileName = strcat(imageFilesPath,'/',n_strPadded,'.png'); imwrite(I,imageFileName); pcwrite(pc,pcFileName); end
启动激光雷达相机标定器应用程序,使用界面将数据加载到应用程序中。您也可以从 MATLAB® 命令行加载数据并启动应用程序。
checkerSize = 81; %毫米
padding = [0 0 0 0];
lidarCameraCalibrator(imageFilesPath,pcFilesPath,checkerSize,padding)
4.1 支持功能
function rosbagFile = helperDownloadRosbag() % Download the data set from the given URL. rosbagZipFile = matlab.internal.examples.downloadSupportFile( ... 'lidar','data/lccSample.zip'); [outputFolder,~,~] = fileparts(rosbagZipFile); rosbagFile = fullfile(outputFolder,'lccSample.bag'); if ~exist(rosbagFile,'file') unzip(rosbagZipFile,outputFolder); end end