主要内容

激光雷达和相机校准

这个例子向你展示了如何估算三维激光雷达和相机之间的刚性转换。在本例的最后,您将能够使用刚性变换矩阵来融合激光雷达和相机数据。

此图解释了激光雷达和相机校准(LCC)过程的工作流程。

概述

激光雷达和摄像机传感器是自动驾驶应用中最常见的视觉传感器。摄像机提供丰富的颜色信息和其他特征,可以用来提取被检测物体的不同特征。另一方面,激光雷达传感器可以提供物体的精确三维位置和结构。为了增强目标检测和分类流水线,可以将两个传感器的数据融合在一起,获得更详细、更准确的目标信息。

两个传感器之间以方向和相对位置为形式的变换矩阵是融合两个传感器数据的前兆。激光雷达摄像机校准有助于估计3-D激光雷达和安装在自动驾驶汽车上的摄像机之间的转换矩阵。在本例中,您将使用来自两个不同的激光雷达传感器的数据,HDL64VLP16HDL64数据是从一个露台环境中收集的,如图所示。

数据以一组PNG图像和对应的PCD点云的形式捕获。这个例子假设摄像机的固有参数是已知的。有关提取相机固有参数的更多信息,请参见单相机校准。

加载数据

从Gazebo加载Velodyne HDL-64传感器数据。

imagePath = fullfile (toolboxdir (激光雷达的),“lidardata”低成本航空的“HDL64”“图像”);ptCloudPath = fullfile (toolboxdir (激光雷达的),“lidardata”低成本航空的“HDL64”“pointCloud”);cameraParamsPath = fullfile (imagePath,“calibration.mat”);内在=负载(cameraParamsPath);加载相机固有功能imd = imageDatastore (imagePath);%使用imageDatastore加载图像pcd = fileDatastore (ptCloudPath,“ReadFcn”, @pcread);%加载点云文件imageFileNames = imds.Files;ptCloudFileNames = pcds.Files;squareSize = 200;%棋盘的正方形大小%设置随机种子以产生可重复的结果。rng(“默认”);

棋盘角点检测

本例使用了棋盘模式作为比较特性。棋盘边缘估计使用激光雷达和相机传感器。使用estimateCheckerboardCorners3d计算棋盘转角的坐标和中实际棋盘的大小毫米。角是根据相机的坐标系统进行三维估计的。有关相机坐标系统的更多细节,请参见激光雷达工具箱中的坐标系统

[imageCorners3d, checkerboardDimension, dataUsed] =...estimateCheckerboardCorners3d (imageFileNames内在。cameraParams squareSize);imageFileNames = imageFileNames (dataUsed);%删除不使用的映像文件

可以使用helper函数将结果可视化helperShowImageCorners

%显示棋盘角helperShowImageCorners (imageCorners3d imageFileNames intrinsic.cameraParams);

图中包含一个轴和一个uipanel类型的对象。轴包含9个类型为image、line的对象。

激光雷达中的棋盘格检测

同样,使用detectRectangularPlanePoints函数用于检测激光雷达数据中的棋盘格。该函数根据输入的维数检测点云中的矩形物体。在本例中,它使用前一节中计算的棋盘尺寸来检测棋盘。

%从检测到的图像角提取感兴趣区域roi = helperComputeROI(imageCorners3d, 5);%过滤被检测图像对应的点云文件ptCloudFileNames=ptCloudFileNames(使用的数据);[lidarCheckerboardPlanes,使用的框架,索引]=...detectRectangularPlanePoints (ptCloudFileNames checkerboardDimension,“投资回报”,投资回报率);%删除不使用的ptCloud文件ptCloudFileNames = ptCloudFileNames (framesUsed);%删除图像文件imageFileNames = imageFileNames (framesUsed);%从图像中删除三维角点imageCorners3d = imageCorners3d(:,:, framesUsed);

要可视化检测到的棋盘,请使用helperShowCheckerboardPlanes函数。

helperShowCheckerboardPlanes (ptCloudFileNames指标);

图包含一个轴和一个uipanel类型的对象。坐标轴包含一个散点类型的对象。

激光雷达和照相机的校准

使用estimateLidarCameraTransform来估计激光雷达与摄像机之间的刚性变换矩阵。

[tform, errors] = estimatelidarcamertransform (lidarCheckerboardPlanes,...imageCorners3d,“CameraIntrinsic”, intrinsic.cameraParams);

校准完成后,校准矩阵有两种使用方式:

  • 在图像上投射激光雷达点云。

  • 利用图像中的颜色信息增强激光雷达点云。

使用helperFuseLidarCamera函数将激光雷达和图像数据融合在一起。

helperFuseLidarCamera (imageFileNames ptCloudFileNames指数,...内在。cameraParams tform);

图中包含2个轴和其他uipanel类型的对象。Axes 1包含一个类型为scatter的对象。axis 2包含两个类型为image, line的对象。

误差可视化

定义了三种类型的误差来估计校准的精度:

  • 平移误差:激光雷达中棋盘格角的质心与图像中三维投影角之间的差异平均值。

  • 旋转误差:点云棋盘格法线与图像三维投影角点之间的平均差。

  • 重投影误差:图像角的质心与投影在图像上的激光雷达角的差的平均值。

使用helperShowError绘制估计的误差值。

helperShowError(错误)

图错误图包含3个轴和其他类型的uipanel对象。axis 1包含两个类型为bar, line的对象。这个对象表示总体平均平移误差:0.0033408,单位为m。坐标轴2包含两个类型为bar, line的对象。这个对象代表总体平均旋转误差:0.7986在deg. axis 3包含2个类型为bar, line的对象。该对象表示总体平均重投影误差:0.99477像素。

结果

校准后,检查具有高校准误差的数据,并重新运行校准。

outlierIdx =错误。RotationError <意味着(errors.RotationError);[newTform, newErrors] = estimateLidarCameraTransform(lidarCheckerboardPlanes(outlierIdx),...imageCorners3d (:,:, outlierIdx),“CameraIntrinsic”,固有的。cameraParams);HelpersowError(新错误);

图错误图包含3个轴和其他类型的uipanel对象。axis 1包含两个类型为bar, line的对象。这个对象表示总体平均平移误差:0.0036375 m。坐标轴2包含两个类型为bar, line的对象。这个对象表示总体平均旋转误差:0.39698在deg. axis 3包含2个类型为bar, line的对象。该对象表示总体平均重投影误差:1.1785像素。

真实数据测试

在实际VLP-16激光雷达数据上测试LCC工作流,以评估其性能。

清晰;imagePath = fullfile (toolboxdir (激光雷达的),“lidardata”低成本航空的“vlp16”“图像”);ptCloudPath = fullfile (toolboxdir (激光雷达的),“lidardata”低成本航空的“vlp16”“pointCloud”);cameraParamsPath = fullfile (imagePath,“calibration.mat”);内在=负载(cameraParamsPath);加载相机的固有功能imd = imageDatastore (imagePath);%使用imageDatastore加载图像pcd = fileDatastore (ptCloudPath,“ReadFcn”, @pcread);加载点云文件imageFileNames = imds.Files;ptCloudFileNames = pcds.Files;squareSize = 81;%棋盘的正方形大小%设置随机种子以产生可重复的结果。rng(“默认”);%从图像中提取棋盘角[imageCorners3d, checkerboardDimension, dataUsed] =...estimateCheckerboardCorners3d (imageFileNames内在。cameraParams squareSize);imageFileNames = imageFileNames (dataUsed);%删除不使用的映像文件%过滤被检测图像对应的点云文件ptCloudFileNames=ptCloudFileNames(使用的数据);%从检测到的图像角提取感兴趣区域roi = helperComputeROI(imageCorners3d, 5);%激光雷达数据中棋盘格的提取[lidarCheckerboardPlanes, framesUsed, indices] = detectRectangularPlanePoints(...ptcloudfilename、checkboarddimension、,“RemoveGround”符合事实的“投资回报”,投资回报率);imageCorners3d=imageCorners3d(:,:,帧使用);%删除不使用的ptCloud文件ptCloudFileNames = ptCloudFileNames (framesUsed);%删除图像文件imageFileNames = imageFileNames (framesUsed);[tform, errors] = estimatelidarcamertransform (lidarCheckerboardPlanes,...imageCorners3d,“CameraIntrinsic”,固有的。cameraParams);helperFuseLidarCamera(图像文件名、ptCloudFileName、索引、,...内在。cameraParams tform);

图中包含2个轴和其他uipanel类型的对象。Axes 1包含一个类型为scatter的对象。axis 2包含两个类型为image, line的对象。

%绘制估计误差值helperShowError(错误);

图错误图包含3个轴和其他类型的uipanel对象。axis 1包含两个类型为bar, line的对象。这个对象表示总体平均翻译误差:0.010932 m。坐标轴2包含两个类型为bar, line的对象。这个对象代表总体平均旋转误差:1.7377 deg. axis 3包含2个类型为bar, line的对象。该对象表示总体平均重投影误差:4.1914像素。

总结

这个例子概述了如何开始激光雷达摄像机校准工作流程,以提取两个传感器之间的刚性转换。这个示例还向您展示了如何使用刚性变换矩阵来融合激光雷达和相机数据。

工具书类

李子模、周力普,“基于直线和平面通信的相机和三维激光雷达的自动外部标定”,“IEEE/RSJ Intl.”智能机器人与系统大会,IROS”,2018年10月。

[2] K. S. Arun, T. S. Huang, S. D. Blostein,“两个三维点集的最小二乘拟合”,《IEEE模式分析与机器智能学报》,vol. 9, no. 1, no. 1, no. 1, no. 1, no. 1,5、第698-700页,1987年9月。