新手也能做的激光雷达和相机的标定之Matlab;matlab之LiDAR+Camera校准工具箱;Lidar Camera Calibration

it2023-04-11  85

好消息好消息,现在Matlab官方发布了激光雷达+相机的校准工具箱啦!! 如果想使用这个功能,请先升级到MATLAB2020b。然后按照一下教程运行。

使用这个功能需要准备的是

1.安装MATLAB2020b,拥有LiDAR工具箱 2.使用matlab标定好的相机内参矩阵 3.拥有雷达的点云文件PCD或PCL格式(实例所使用的是内置的PCD文件)

2020b的Baidu云链接,提取码:zadk 下面这幅图展示了整个标定的过程,最终两个坐标系的转换使用了刚性变换。

实现步骤

从LiDAR中加载内置点云文件(HDL-64)

imagePath = fullfile(toolboxdir('lidar'), 'lidardata', 'lcc', 'HDL64', 'images'); ptCloudPath = fullfile(toolboxdir('lidar'), 'lidardata', 'lcc', 'HDL64', 'pointCloud'); cameraParamsPath = fullfile(imagePath, 'calibration.mat'); intrinsic = load(cameraParamsPath); % Load camera intrinsics imds = imageDatastore(imagePath); % Load images using imageDatastore pcds = fileDatastore(ptCloudPath, 'ReadFcn', @pcread); % Load point cloud files imageFileNames = imds.Files; ptCloudFileNames = pcds.Files; squareSize = 200; % Square size of the checkerboard % Set random seed to generate reproducible results. rng('default');

执行棋盘角点检测

[imageCorners3d, checkerboardDimension, dataUsed] = ... estimateCheckerboardCorners3d(imageFileNames, intrinsic.cameraParams, squareSize); imageFileNames = imageFileNames(dataUsed); % Remove image files that are not used

结果可以使用helperShowImageCorners函数进行可视化。

% Display Checkerboard corners helperShowImageCorners(imageCorners3d, imageFileNames, intrinsic.cameraParams);

激光雷达中的棋盘检测

% Extract ROI from the detected image corners roi = helperComputeROI(imageCorners3d, 5); % Filter point cloud files corresponding to the detected images ptCloudFileNames = ptCloudFileNames(dataUsed); [lidarCheckerboardPlanes, framesUsed, indices] = ... detectRectangularPlanePoints(ptCloudFileNames, checkerboardDimension, 'ROI', roi); % Remove ptCloud files that are not used ptCloudFileNames = ptCloudFileNames(framesUsed); % Remove image files imageFileNames = imageFileNames(framesUsed); % Remove 3D corners from images imageCorners3d = imageCorners3d(:, :, framesUsed);

可视化检测到的函数,使用helperShowLidarCorners函数

helperShowLidarCorners(ptCloudFileNames, indices);

校准激光雷达和摄像机 使用estimateLidarCameraTransform函数去估计雷达和摄像机之间的刚性变换矩阵。

[tform, errors] = estimateLidarCameraTransform(lidarCheckerboardPlanes, ... imageCorners3d, 'CameraIntrinsic', intrinsic.cameraParams);

校准完成后,可以通过两种方式使用校准矩阵:

使用图像中的色彩表示增强激光雷达点云,即生成彩色点云在图像上投影激光雷达点云。 使用helperFuseLidarCamerafunction函数可视化融合结果 helperFuseLidarCamera(imageFileNames, ptCloudFileNames, indices, ... intrinsic.cameraParams, tform);

使用helperShowError函数绘制估计误差值

helperShowError(errors)

结果 校准后检查具有较高误差值的数据,然后重新运行校准

outlierIdx = errors.RotationError < mean(errors.RotationError); [newTform, newErrors] = estimateLidarCameraTransform(lidarCheckerboardPlanes(outlierIdx), ... imageCorners3d(:, :, outlierIdx), 'CameraIntrinsic', intrinsic.cameraParams); helperShowError(newErrors);

对真实数据进行测试 在实际 VLP-16 激光雷达数据上测试激光雷达相机校准。

clear; imagePath = fullfile(toolboxdir('lidar'), 'lidardata', 'lcc', 'vlp16', 'images'); ptCloudPath = fullfile(toolboxdir('lidar'), 'lidardata', 'lcc', 'vlp16', 'pointCloud'); cameraParamsPath = fullfile(imagePath, 'calibration.mat'); intrinsic = load(cameraParamsPath); % Load camera intrinscs imds = imageDatastore(imagePath); % Load images using imageDatastore pcds = fileDatastore(ptCloudPath, 'ReadFcn', @pcread); % Loadr point cloud files imageFileNames = imds.Files; ptCloudFileNames = pcds.Files; squareSize = 81; % Square size of the checkerboard % Set random seed to generate reproducible results. rng('default'); % Extract Checkerboard corners from the images [imageCorners3d, checkerboardDimension, dataUsed] = ... estimateCheckerboardCorners3d(imageFileNames, intrinsic.cameraParams, squareSize); imageFileNames = imageFileNames(dataUsed); % Remove image files that are not used % Filter point cloud files corresponding to the detected images ptCloudFileNames = ptCloudFileNames(dataUsed); % Extract ROI from the detected image corners roi = helperComputeROI(imageCorners3d, 5); %Extract Checkerboard in lidar data [lidarCheckerboardPlanes, framesUsed, indices] = detectRectangularPlanePoints(... ptCloudFileNames, checkerboardDimension, 'RemoveGround', true, 'ROI', roi); imageCorners3d = imageCorners3d(:, :, framesUsed); % Remove ptCloud files that are not used ptCloudFileNames = ptCloudFileNames(framesUsed); % Remove image files imageFileNames = imageFileNames(framesUsed); [tform, errors] = estimateLidarCameraTransform(lidarCheckerboardPlanes, ... imageCorners3d, 'CameraIntrinsic', intrinsic.cameraParams); helperFuseLidarCamera(imageFileNames, ptCloudFileNames, indices,... intrinsic.cameraParams, tform);

如果运行中有报错,可直接在报错的函数中将参数代入运行一遍,然后将主函数开头的Clear删除,使用运行得到的结果接着在主函数中运行。

最新回复(0)