Этот пример показывает вам, как обнаружить транспортные средства в данных о метке использования лидара из совмещенной камеры известными параметрами лидара к калибровке фотоаппарата. Используйте этот рабочий процесс в MATLAB®, чтобы оценить 3-D ориентированные ограничительные рамки в лидаре на основе 2D ограничительных рамок в соответствующем изображении. Вы будете также видеть, как автоматически сгенерировать основную истину как расстояние для 2D ограничительных рамок в изображении камеры с помощью данных о лидаре. Этот рисунок предоставляет обзор процесса.
Этот пример использует данные о лидаре, собранные по магистрали от Изгнания датчик лидара OS1 и данные изображения от обращенной к передней стороне камеры, смонтированной на автомобиле, оборудованном датчиком. Данные о лидаре и камере приблизительно синхронизируются временем и калибруются, чтобы оценить их внутренние и внешние параметры. Для получения дополнительной информации о калибровке фотоаппарата лидара смотрите Лидар и Калибровку фотоаппарата.
Примечание: время загрузки для данных зависит от скорости вашего интернет-соединения. Во время выполнения этого блока кода MATLAB временно безразличен.
lidarTarFileUrl = 'https://www.mathworks.com/supportfiles/lidar/data/WPI_LidarData.tar.gz'; imageTarFileUrl = 'https://www.mathworks.com/supportfiles/lidar/data/WPI_ImageData.tar.gz'; outputFolder = fullfile(tempdir,'WPI'); lidarDataTarFile = fullfile(outputFolder,'WPI_LidarData.tar.gz'); imageDataTarFile = fullfile(outputFolder,'WPI_ImageData.tar.gz'); if ~exist(outputFolder,'dir') mkdir(outputFolder) end if ~exist(lidarDataTarFile,'file') disp('Downloading WPI Lidar driving data (760 MB)...') websave(lidarDataTarFile,lidarTarFileUrl) untar(lidarDataTarFile,outputFolder) end % Check if lidar tar.gz file is downloaded, but not uncompressed. if ~exist(fullfile(outputFolder,'WPI_LidarData.mat'),'file') untar(lidarDataTarFile,outputFolder) end if ~exist(imageDataTarFile,'file') disp('Downloading WPI Image driving data (225 MB)...') websave(imageDataTarFile,imageTarFileUrl) untar(imageDataTarFile,outputFolder) end % Check if image tar.gz file is downloaded, but not uncompressed. if ~exist(fullfile(outputFolder,'imageData'),'dir') untar(imageDataTarFile,outputFolder) end imageDataLocation = fullfile(outputFolder,'imageData'); images = imageSet(imageDataLocation); imageFileNames = images.ImageLocation; % Load downloaded lidar data into the workspace lidarData = fullfile(outputFolder,'WPI_LidarData.mat'); load(lidarData); % Load calibration data if ~exist('calib','var') load('calib.mat') end % Define camera to lidar transformation matrix camToLidar = calib.extrinsics; intrinsics = calib.intrinsics;
В качестве альтернативы можно использовать веб-браузер, чтобы сначала загрузить наборы данных на локальный диск, и затем распаковать файлы.
Этот пример использует предварительно помеченные данные, чтобы служить основной истиной для 2D обнаружений от изображений камеры. Эти 2D обнаружения могут быть сгенерированы с помощью основанных на глубоком обучении детекторов объектов как vehicleDetectorYOLOv2
, vehicleDetectorFasterRCNN
, и vehicleDetectorACF
. В данном примере 2D обнаружения были сгенерированы с помощью приложения Image Labeler. Эти 2D ограничительные рамки являются векторами из формы: , где представляйте координаты xy верхнего левого угла, и представляйте ширину и высоту ограничительной рамки соответственно.
Считайте фрейм изображения в рабочую область и отобразите ее с наложенными ограничительными рамками.
load imageGTruth.mat im = imread(imageFileNames{50}); imBbox = imageGTruth{50}; figure imshow(im) showShape('rectangle',imBbox)
Чтобы сгенерировать ограничительные рамки кубоида в лидаре от 2D прямоугольных ограничительных рамок в данных изображения, 3-D область предложена, чтобы уменьшать пространство поиска для оценки ограничительной рамки. Углы каждой 2D прямоугольной ограничительной рамки в изображении преобразовываются в 3-D линии с помощью параметров внутреннего параметра камеры и параметров значения внешних параметров камеры к лидару. Эти 3-D линии формируют frustum, становящийся шире из связанной 2D ограничительной рамки в противоположном направлении автомобиля, оборудованного датчиком. Лидар указывает, что падение в этой области сегментируется на различные кластеры на основе Евклидова расстояния. Кластеры оснащены 3-D ориентированными ограничительными рамками, и лучший кластер оценивается на основе размера этих кластеров. Оцените 3-D ориентированные ограничительные рамки в облаке точек лидара, на основе 2D ограничительных рамок в изображении камеры, при помощи bboxCameraToLidar
функция. Этот рисунок показывает, как 2D и 3-D ограничительные рамки относятся друг к другу.
3-D кубоиды представлены как векторы из формы:, где представляйте центроидные координаты кубоида. представляйте длину кубоида вдоль x-, y-, и оси z, и представляйте вращение, в градусах, кубоида вдоль x-, y-, и осей z.
Используйте основную истину изображения, чтобы оценить 3-D ограничительную рамку в облаке точек лидара.
pc = lidarData{50}; % Crop point cloud to process only front region roi = [0 70 -15 15 -3 8]; ind = findPointsInROI(pc,roi); pc = select(pc,ind); lidarBbox = bboxCameraToLidar(imBbox,pc,intrinsics, ... camToLidar,'ClusterThreshold',2,'MaxDetectionRange',[1,70]); figure pcshow(pc.Location,pc.Location(:,3)) showShape('Cuboid',lidarBbox) view([-2.90 71.59])
Чтобы улучшить обнаруженные ограничительные рамки, предварительно обработайте облако точек путем удаления наземной плоскости.
Используйте helperLidarCameraObjectsDisplay
класс, чтобы визуализировать лидар и данные изображения. Эта визуализация предусматривает возможность просмотреть облако точек, изображение, 3-D ограничительные рамки на облаке точек и 2D ограничительные рамки на изображении одновременно. Размещение визуализации, состоит из этих окон:
Изображение — Визуализирует изображение и сопоставило 2D ограничительные рамки
Вид в перспективе — Визуализирует облако точек и сопоставил 3-D ограничительные рамки в виде в перспективе
Вид сверху — Визуализирует облако точек и сопоставил 3-D ограничительные рамки от вида сверху
% Initialize display display = helperLidarCameraObjectsDisplay; initializeDisplay(display) % Update display with point cloud and image updateDisplay(display, im, pc)
Запустите bboxCameraToLidar на 2D этикетках по первым 200 системам координат, чтобы сгенерировать 3-D кубоиды
for i = 1:200 % Load point cloud and image im = imread(imageFileNames{i}); pc = lidarData{i}; % Load image ground truth imBbox = imageGTruth{i}; % Remove ground plane groundPtsIndex = segmentGroundFromLidarData(pc,'ElevationAngleDelta',15, ... 'InitialElevationAngle',10); nonGroundPts = select(pc,~groundPtsIndex); if imBbox [lidarBbox,~,boxUsed] = bboxCameraToLidar(imBbox,nonGroundPts,intrinsics, ... camToLidar,'ClusterThreshold',2,'MaxDetectionRange',[1, 70]); % Display image with bounding boxes im = updateImage(display,im,imBbox); end % Display point cloud with bounding box updateDisplay(display,im,pc); updateLidarBbox(display,lidarBbox,boxUsed) drawnow end
Обнаруженные ограничительные рамки при помощи отслеживания ограничительной рамки, такие как объединенная вероятностная ассоциация данных (JPDA). Для получения дополнительной информации смотрите, что Транспортные средства Дорожки Используют Лидар: От Облака точек до Списка Дорожек.
Для функций безопасности транспортных средств, таких как прямое предупреждение столкновения, точное измерение расстояния между автомобилем, оборудованным датчиком и другими объектами крайне важно. Датчик лидара обеспечивает точное расстояние объектов от автомобиля, оборудованного датчиком в 3-D, и это может также использоваться, чтобы автоматически создать основную истину от 2D ограничительных рамок изображений. Чтобы сгенерировать основную истину для 2D ограничительных рамок, используйте projectLidarPointsOnImage
функционируйте, чтобы спроектировать точки в 3-D ограничительных рамках на изображение. Спроектированные точки сопоставлены с 2D ограничительными рамками путем нахождения ограничительной рамки с минимальным Евклидовым расстоянием от спроектированных 3-D точек. Поскольку спроектированные точки с лидара на камеру, используют инверсию параметров значения внешних параметров камеры к лидару. Этот рисунок иллюстрирует преобразование с лидара на камеру.
% Initialize display display = helperLidarCameraObjectsDisplay; initializeDisplay(display) % Get lidar to camera matrix lidarToCam = invert(camToLidar); % Loop first 200 frames. To loop all frames, replace 200 with numel(imageGTruth) for i = 1:200 im = imread(imageFileNames{i}); pc = lidarData{i}; imBbox = imageGTruth{i}; % Remove ground plane groundPtsIndex = segmentGroundFromLidarData(pc,'ElevationAngleDelta',15, ... 'InitialElevationAngle',10); nonGroundPts = select(pc,~groundPtsIndex); if imBbox [lidarBbox,~,boxUsed] = bboxCameraToLidar(imBbox,nonGroundPts,intrinsics, ... camToLidar,'ClusterThreshold',2,'MaxDetectionRange',[1, 70]); [distance,nearestRect,idx] = helperComputeDistance(imBbox,nonGroundPts,lidarBbox, ... intrinsics,lidarToCam); % Update image with bounding boxes im = updateImage(display,im,nearestRect,distance); updateLidarBbox(display,lidarBbox) end % Update display updateDisplay(display,im,pc) drawnow end
function [distance, nearestRect, index] = helperComputeDistance(imBbox, pc, lidarBbox, intrinsic, lidarToCam) % helperComputeDistance estimates the distance of 2-D bounding box in a given % image using 3-D bounding boxes from lidar. It also calculates % association between 2-D and 3-D bounding boxes % Copyright 2020 MathWorks, Inc. numLidarDetections = size(lidarBbox,1); nearestRect = zeros(0,4); distance = zeros(1,numLidarDetections); index = zeros(0,1); for i = 1:numLidarDetections bboxCuboid = lidarBbox(i,:); % Create cuboidModel model = cuboidModel(bboxCuboid); % Find points inside cuboid ind = findPointsInsideCuboid(model,pc); pts = select(pc,ind); % Project cuboid points to image imPts = projectLidarPointsOnImage(pts,intrinsic,lidarToCam); % Find 2-D rectangle corresponding to 3-D bounding box [nearestRect(i,:),idx] = findNearestRectangle(imPts,imBbox); index(end+1) = idx; % Find the distance of the 2-D rectangle distance(i) = min(pts.Location(:,1)); end end function [nearestRect,idx] = findNearestRectangle(imPts,imBbox) numBbox = size(imBbox,1); ratio = zeros(numBbox,1); % Iterate over all the rectangles for i = 1:numBbox bbox = imBbox(i,:); corners = getCornersFromBbox(bbox); % Find overlapping ratio of the projected points and the rectangle idx = (imPts(:,1) > corners(1,1)) & (imPts(:,1) < corners(2,1)) & ... (imPts(:,2) > corners(1,2)) & (imPts(:,2) < corners(3,1)); ratio(i) = sum(idx); end % Get nearest rectangle [~,idx] = max(ratio); nearestRect = imBbox(idx,:); end function cornersCamera = getCornersFromBbox(bbox) cornersCamera = zeros(4,2); cornersCamera(1,1:2) = bbox(1:2); cornersCamera(2,1:2) = bbox(1:2) + [bbox(3),0]; cornersCamera(3,1:2) = bbox(1:2) + bbox(3:4); cornersCamera(4,1:2) = bbox(1:2) + [0,bbox(4)]; end