Калибровка лидара и камеры

В этом примере показано, как оценить твердое преобразование между 3-D лидаром и камерой. В конце этого примера вы сможете использовать твердую матрицу преобразования, чтобы сплавить данные лидара и камеры.

Эта схема объясняет рабочий процесс для процесса лидара и калибровки камеры (LCC).

Обзор

Лидары и камеры являются наиболее распространенными датчиками зрения в автономных ведущих приложениях. Камеры обеспечивают богатую цветовую информацию и другие функции, которые могут использоваться для извлечения различных характеристик обнаруженных объектов. Датчики Лидара, с другой стороны, обеспечивают точное 3-D расположение и структуру объектов. Чтобы улучшить трубопровод обнаружения и классификации объектов, данные с этих двух датчиков могут быть объединены вместе, чтобы получить более подробную и точную информацию об объектах.

Матрица преобразования в виде ориентации и относительных положений между двумя датчиками является предшественником сплавления данных с этих двух датчиков. Калибровка камеры Lidar помогает в оценке матрицы преобразования между 3-D лидаром и камерой, установленной на автономном транспортном средстве. В этом примере вы будете использовать данные из двух разных датчиков лидара, HDL64 и VLP16. HDL64 данные собираются из окружения Gazebo, как показано на этом рисунке.

Данные получаются в виде набора изображений PNG и соответствующих облаков точек PCD. Этот пример принимает, что внутренние параметры камеры известны. Дополнительные сведения о извлечении внутренних параметров камеры см. в разделе Калибровка одиночной камеры.

Загрузка данных

Загрузите данные датчика HDL-64 Velodyne от Gazebo.

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'); 

Checkerboard Угловое обнаружение

Этот пример использует шахматный шаблон в качестве функции сравнения. Шахматные ребра оцениваются с помощью датчиков лидара и камеры. Использование estimateCheckerboardCorners3d для вычисления координат шахматных углов и размера фактической шахматной доски в мм. Значения углов оцениваются в 3-D относительно системы координат камеры. Для получения дополнительной информации о системах координат камеры см. «Системы координат» в Lidar Toolbox

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

Результаты могут быть визуализированы с помощью функции helper helperShowImageCorners.

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

Figure contains an axes and an object of type uipanel. The axes contains 9 objects of type image, line.

Обнаружение шашек в лидаре

Точно так же используйте detectRectangularPlanePoints функция для обнаружения шахматной доски в лидарных данных. Функция обнаруживает прямоугольные объекты в облаке точек на основе входа размеров. В этом случае он обнаруживает шахматную доску с помощью размерностей платы, рассчитанных в предыдущем разделе.

% 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);

Чтобы визуализировать обнаруженную шахматную доску, используйте helperShowCheckerboardPlanes функция.

helperShowCheckerboardPlanes(ptCloudFileNames, indices);

Figure contains an axes and an object of type uipanel. The axes contains an object of type scatter.

Калибровка лидара и камеры

Использование estimateLidarCameraTransform to оцените твердую матрицу преобразования между лидаром и камерой.

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

После завершения калибровки можно использовать калибровочную матрицу двумя способами:

  • Проецируйте облако точек лидар на изображение.

  • Улучшите облако точек лидар, используя искажение цвета изображения.

Использование helperFuseLidarCamera function чтобы визуализировать лидар и данные изображения, сросшиеся между собой.

helperFuseLidarCamera(imageFileNames, ptCloudFileNames, indices, ...
    intrinsic.cameraParams, tform);

Figure contains 2 axes and other objects of type uipanel. Axes 1 contains an object of type scatter. Axes 2 contains 2 objects of type image, line.

Визуализация ошибок

Для оценки точности калибровки заданы три типа ошибок:

  • Ошибка преобразования: Среднее значение различия центроида поворотов шахматной доски в лидаре и проектируемых углов в 3-D от изображения.

  • Ошибка поворота: Среднее значение различия нормалей шахматной доски в облаке точек и проектируемых углов в 3-D от изображения.

  • Ошибка репроекции: Среднее значение различия между центроидом углов изображения и проективными углами лидара на изображении.

Постройте график предполагаемых значений ошибок с помощью helperShowError.

helperShowError(errors)

Figure Error Plots contains 3 axes and other objects of type uipanel. Axes 1 contains 2 objects of type bar, line. This object represents Overall Mean Translation Error:0.0033408 in m. Axes 2 contains 2 objects of type bar, line. This object represents Overall Mean Rotation Error:0.7986 in deg. Axes 3 contains 2 objects of type bar, line. This object represents Overall Mean Reprojection Error:0.99477 in pixel.

Результаты

После калибровки проверьте данные с высокими ошибками калибровки и повторно запустите калибровку.

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

Figure Error Plots contains 3 axes and other objects of type uipanel. Axes 1 contains 2 objects of type bar, line. This object represents Overall Mean Translation Error:0.0036375 in m. Axes 2 contains 2 objects of type bar, line. This object represents Overall Mean Rotation Error:0.39698 in deg. Axes 3 contains 2 objects of type bar, line. This object represents Overall Mean Reprojection Error:1.1785 in pixel.

Проверка на реальных данных

Протестируйте рабочий процесс LCC на фактических данных VLP-16 Lidar, чтобы оценить его эффективность.

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);

Figure contains 2 axes and other objects of type uipanel. Axes 1 contains an object of type scatter. Axes 2 contains 2 objects of type image, line.

% Plot the estimated error values
helperShowError(errors);

Figure Error Plots contains 3 axes and other objects of type uipanel. Axes 1 contains 2 objects of type bar, line. This object represents Overall Mean Translation Error:0.010932 in m. Axes 2 contains 2 objects of type bar, line. This object represents Overall Mean Rotation Error:1.7377 in deg. Axes 3 contains 2 objects of type bar, line. This object represents Overall Mean Reprojection Error:4.1914 in pixel.

Сводные данные

Этот пример дает обзор того, как начать с рабочего процесса калибровки камеры лидара, чтобы извлечь твердое преобразование между этими двумя датчиками. В этом примере также показано, как использовать твердую матрицу преобразования для сплавления данных лидара и камеры.

Ссылки

[1] Lipu Zhou and Zimo Li and Michael Kaess, "Automatic Extrinsic Calibration of a Camera and a 3D LiDAR using Line and Plane Consubsences", "IEEE/RSJ Intl. Conf. on Intelligent Robots and Systems, IROS ", окт. 2018.

[2] К. С. Арун, Т. С. Хуан и С. Д. Blostein, «методом наименьших квадратов подбора кривой из двух наборов 3-D точки», IEEE Transactions on Шаблона Analysis and Machine Intelligence, vol. PAMI-9, no. 5, pp. 698-700, Sept 1987.