Этот пример показывает, как оценить свободное пространство и создать сетку заполнения с помощью семантической сегментации и глубокого обучения. Вы затем используете эту сетку заполнения, чтобы создать автомобиль costmap.
Оценка свободного пространства идентифицирует области в среде, где автомобиль, оборудованный датчиком может управлять, не поражая препятствий, таких как пешеходы, ограничения или другие автомобили. Автомобиль может использовать множество датчиков, чтобы оценить свободное пространство, такое как радар, лазерный дальномер или камеры. Этот пример фокусируется на оценке свободного пространства от формирователя изображения с помощью семантической сегментации.
В этом примере вы учитесь как:
Используйте семантическую сегментацию изображений, чтобы оценить свободное пространство.
Создайте сетку заполнения с помощью оценки свободного пространства.
Визуализируйте сетку заполнения на видимом с большого расстояния графике.
Создайте автомобиль costmap использование сетки заполнения.
Проверяйте, заняты ли местоположения в мире или свободны.
Этот пример использует предварительно обученную семантическую сеть сегментации, которая может классифицировать пиксели в 11 различных классов, включая Road
, Pedestrian
, Car
и Sky
. Свободное пространство в изображении может быть оценено путем определения пикселей изображения, классифицированных как Road
как свободное пространство. Все другие классы заданы как несвободное пространство или препятствия.
Полную процедуру для того, чтобы обучить эту сеть показывают в Семантической Сегментации Используя Глубокое обучение (Computer Vision Toolbox) пример. Загрузите предварительно обученную сеть.
% Download the pretrained network. pretrainedURL = 'https://www.mathworks.com/supportfiles/vision/data/segnetVGG16CamVid.mat'; pretrainedFolder = fullfile(tempdir,'pretrainedSegNet'); pretrainedSegNet = fullfile(pretrainedFolder,'segnetVGG16CamVid.mat'); if ~exist(pretrainedFolder,'dir') mkdir(pretrainedFolder); disp('Downloading pretrained SegNet (107 MB)...'); websave(pretrainedSegNet,pretrainedURL); disp('Download complete.'); end % Load the network. data = load(pretrainedSegNet); net = data.net;
Примечание: время Загрузки данных зависит от вашего Интернет-соединения. Команды, используемые выше блока MATLAB до загрузки, завершены. Также можно использовать веб-браузер, чтобы сначала загрузить набор данных на локальный диск. В этом случае чтобы использовать файл вы загрузили с сети, замените переменную pretrainedFolder
выше к местоположению загруженного файла.
Оцените, что свободное пространство путем обработки изображения с помощью загрузило семантическую сеть сегментации. Сеть возвращает классификации для каждого пикселя изображения в изображении. Свободное пространство идентифицировано как пиксели изображения, которые были классифицированы как Road
.
Изображение, используемое в этом примере, является одним кадром от последовательности изображений в наборе данных CamVid [1]. Процедура, показанная в этом примере, может быть применена к последовательности кадров, чтобы оценить свободное пространство, когда автомобиль едет. Однако, потому что очень глубокая сверточная архитектура нейронной сети используется в этом примере (SegNet с энкодером VGG-16), требуется приблизительно 1 секунда, чтобы обработать каждый кадр. Поэтому для целесообразности, обработайте один кадр.
% Read the image. I = imread('seq05vd_snap_shot.jpg'); % Segment the image. [C,scores,allScores] = semanticseg(I,net); % Overlay free space onto the image. B = labeloverlay(I,C,'IncludedLabels',"Road"); % Display free space and image. figure imshow(B)
Чтобы понять уверенность в оценке свободного пространства, отобразите выходной счет к классу Road
для каждого пикселя. Значения уверенности могут использоваться, чтобы сообщить нисходящим алгоритмам валидности оценки. Например, даже если сеть классифицирует пиксель как Road
, счет уверенности может быть достаточно низким, чтобы игнорировать ту классификацию из соображений безопасности.
% Use the network's output score for Road as the free space confidence. roadClassIdx = 4; freeSpaceConfidence = allScores(:,:,roadClassIdx); % Display the free space confidence. figure imagesc(freeSpaceConfidence) title('Free Space Confidence Scores') colorbar
Несмотря на то, что начальный результат сегментации для пикселей Road
показал, что большинство пикселей на дороге было классифицировано правильно, визуализация очков обеспечивает более богатую деталь об уверенности классификатора в тех классификациях. Например, уверенность уменьшается, когда вы становитесь ближе к контуру автомобиля.
Оценка свободного пространства сгенерирована на пробеле изображений. Чтобы упростить генерацию сетки заполнения, которая полезна для навигации, оценка свободного пространства должна быть преобразована в систему координат автомобиля. Это может быть сделано путем преобразования оценки свободного пространства к изображению вида с высоты птичьего полета.
Чтобы создать изображение вида с высоты птичьего полета, сначала задайте настройку датчика камеры. Функция поддержки, перечисленная в конце этого примера, camvidMonoCameraSensor
, возвращается, объект monoCamera
, представляющий монокулярную камеру раньше, собирал данные CamVid [1]. Конфигурирование monoCamera
требует камеры intrinsics и extrinsics, которые были оценены данные об использовании, обеспеченные в наборе данных CamVid. Чтобы оценить камеру intrinsics, функция использовала калибровочные изображения шахматной доски CamVid и приложение Camera Calibrator. Оценки камеры extrinsics, такие как высота и подача, были выведены от внешних данных, оцененных авторами набора данных CamVid.
% Create monoCamera for CamVid data.
sensor = camvidMonoCameraSensor();
Учитывая настройку камеры, объект birdsEyeView
преобразовывает оригинальное изображение к виду с высоты птичьего полета. Этот объект позволяет вам задать область, что вы хотите преобразованные координаты автомобиля использования. Обратите внимание на то, что модули координаты автомобиля были установлены объектом monoCamera
, когда высота монтирования камеры была задана в метрах. Например, если бы высота была задана в миллиметрах, остальная часть симуляции использовала бы миллиметры.
% Define bird's-eye-view transformation parameters. distAheadOfSensor = 20; % in meters, as previously specified in monoCamera height input spaceToOneSide = 3; % look 3 meters to the right and left bottomOffset = 0; outView = [bottomOffset, distAheadOfSensor, -spaceToOneSide, spaceToOneSide]; outImageSize = [NaN, 256]; % output image width in pixels; height is chosen automatically to preserve units per pixel ratio birdsEyeConfig = birdsEyeView(sensor,outView,outImageSize);
Сгенерируйте изображение вида с высоты птичьего полета для уверенности свободного пространства и изображения.
% Resize image and free space estimate to size of CamVid sensor. imageSize = sensor.Intrinsics.ImageSize; I = imresize(I,imageSize); freeSpaceConfidence = imresize(freeSpaceConfidence,imageSize); % Transform image and free space confidence scores into bird's-eye view. imageBEV = transformImage(birdsEyeConfig,I); freeSpaceBEV = transformImage(birdsEyeConfig,freeSpaceConfidence); % Display image frame in bird's-eye view. figure imshow(imageBEV)
Преобразуйте изображение в вид с высоты птичьего полета и сгенерируйте уверенность свободного пространства.
figure
imagesc(freeSpaceBEV)
title('Free Space Confidence')
Области дальше от датчика являются более расплывчатыми, из-за наличия меньшего количества пикселей и таким образом требования большего объема интерполяции.
Сетки заполнения используются, чтобы представлять среду автомобиля как дискретную сетку в координатах автомобиля и используются для планирования пути. Каждая ячейка в сетке заполнения имеет значение, представляющее вероятность заполнения той ячейки. Предполагаемое свободное пространство может быть использовано, чтобы заполнить значения сетки заполнения.
Процедура, чтобы заполнить сетку заполнения с помощью оценки свободного пространства следующие:
Задайте размерности сетки заполнения в координатах автомобиля.
Сгенерируйте ряд (X, Y) точки для каждой ячейки сетки. Эти точки находятся в системе координат автомобиля.
Преобразуйте точки от координатного пространства автомобиля (X, Y) в вид с высоты птичьего полета отображают координатное пространство (x, y), использование vehicleToImage
преобразовывает.
Выберите значения уверенности свободного пространства в (x, y) местоположения с помощью griddedInterpolant
, чтобы интерполировать значения уверенности свободного пространства, которые не являются точно в пиксельных центрах в изображении.
Заполните ячейку сетки заполнения со средним значением уверенности свободного пространства для всех (x, y) точки, которые соответствуют той ячейке сетки.
Для краткости процедура, показанная выше, реализована в функции поддержки, createOccupancyGridFromFreeSpaceEstimate
, который перечислен в конце этого примера. Задайте размерности сетки заполнения с точки зрения настройки вида с высоты птичьего полета и создайте сетку заполнения путем вызова createOccupancyGridFromFreeSpaceEstimate
.
% Define dimensions and resolution of the occupancy grid. gridX = distAheadOfSensor; gridY = 2 * spaceToOneSide; cellSize = 0.25; % in meters to match units used by CamVid sensor % Create the occupancy grid from the free space estimate. occupancyGrid = createOccupancyGridFromFreeSpaceEstimate(... freeSpaceBEV, birdsEyeConfig, gridX, gridY, cellSize);
Визуализируйте сетку заполнения с помощью birdsEyePlot
. Создайте birdsEyePlot
и добавьте сетку заполнения на верхней части с помощью pcolor
.
% Create bird's-eye plot. bep = birdsEyePlot('XLimits',[0 distAheadOfSensor],'YLimits', [-5 5]); % Add occupancy grid to bird's-eye plot. hold on [numCellsY,numCellsX] = size(occupancyGrid); X = linspace(0, gridX, numCellsX); Y = linspace(-gridY/2, gridY/2, numCellsY); h = pcolor(X,Y,occupancyGrid); title('Occupancy Grid (probability)') colorbar delete(legend) % Make the occupancy grid visualization transparent and remove grid lines. h.FaceAlpha = 0.5; h.LineStyle = 'none';
Видимый с большого расстояния график может также отобразить данные из нескольких датчиков. Например, добавьте радарную зону охвата с помощью coverageAreaPlotter
.
% Add coverage area to plot. caPlotter = coverageAreaPlotter(bep, 'DisplayName', 'Coverage Area'); % Update it with a field of view of 35 degrees and a range of 60 meters mountPosition = [0 0]; range = 15; orientation = 0; fieldOfView = 35; plotCoverageArea(caPlotter, mountPosition, range, orientation, fieldOfView); hold off
Отображение данных из нескольких датчиков полезно для диагностирования и отладки решений, принятых автономными автомобилями.
vehicleCostmap
обеспечивает функциональность, чтобы проверять, заняты ли местоположения, в автомобиле или мировых координатах, или свободны. Эта проверка требуется для любого алгоритма планирования пути или принятия решений. Создайте vehicleCostmap
с помощью сгенерированного occupancyGrid
.
% Create the costmap. costmap = vehicleCostmap(flipud(occupancyGrid), ... 'CellSize',cellSize, ... 'MapLocation',[0,-spaceToOneSide], ... 'InflationRadius',0.01); % Display the costmap. figure plot(costmap,'Inflation','off') colormap(parula) colorbar title('Vehicle Costmap') % Orient the costmap so that it lines up with the vehicle coordinate % system, where the X-axis points in front of the ego vehicle and the % Y-axis points to the left. view(gca,-90,90)
Чтобы проиллюстрировать, как использовать vehicleCostmap
, создайте набор местоположений в мировых координатах. Эти местоположения представляют путь, который мог пересечь автомобиль.
% Create a set of locations in vehicle coordinates.
candidateLocations = [
8 0.375
10 0.375
12 2
14 0.375
];
Используйте checkOccupied
, чтобы проверять, занято ли каждое местоположение или свободно. На основе результатов за потенциальным путем может быть невозможно следовать, потому что он сталкивается с препятствиями, заданными в costmap
.
% Check if locations are occupied. isOccupied = checkOccupied(costmap,candidateLocations); % Partition locations into free and occupied for visualization purposes. occupiedLocations = candidateLocations(isOccupied,:); freeLocations = candidateLocations(~isOccupied,:); % Display free and occupied points on top of costmap. hold on markerSize = 100; scatter(freeLocations(:,1),freeLocations(:,2),markerSize,'g','filled') scatter(occupiedLocations(:,1),occupiedLocations(:,2),markerSize,'r','filled'); legend(["Free" "Occupied"]) hold off
Использование occupancyGrid
, vehicleCostmap
и checkOccupied
, показанного выше, иллюстрирует основные операции, используемые планировщиками пути, такими как pathPlannerRRT
. Learn
больше о планировании пути в Автоматизированном Камердинере Парковки (Automated Driving Toolbox) пример.
[1] Brostow, Габриэль Дж., Жюльен Фокер и Роберто Сиполья. "Семантические Классы объектов в Видео: наземная база данных истины высокой четкости". Буквы Распознавания образов. Издание 30, Выпуск 2, 2009, стр 88-97.
function sensor = camvidMonoCameraSensor() % Return a monoCamera camera configuration based on data from the CamVid % data set[1]. % % The cameraCalibrator app was used to calibrate the camera using the % calibration images provided in CamVid: % % http://web4.cs.ucl.ac.uk/staff/g.brostow/MotionSegRecData/data/CalibrationSeq_and_Files_0010YU.zip % % Calibration pattern grid size is 28 mm. % % Camera pitch is computed from camera pose matrices [R t] stored here: % % http://web4.cs.ucl.ac.uk/staff/g.brostow/MotionSegRecData/data/EgoBoost_trax_matFiles.zip % References % ---------- % [1] Brostow, Gabriel J., Julien Fauqueur, and Roberto Cipolla. "Semantic Object % Classes in Video: A high-definition ground truth database." _Pattern Recognition % Letters_. Vol. 30, Issue 2, 2009, pp. 88-97. calibrationData = load('camera_params_camvid.mat'); % Describe camera configuration. focalLength = calibrationData.cameraParams.FocalLength; principalPoint = calibrationData.cameraParams.PrincipalPoint; imageSize = calibrationData.cameraParams.ImageSize; % Camera height estimated based on camera setup pictured in [1]: % http://mi.eng.cam.ac.uk/~gjb47/tmp/prl08.pdf height = 0.5; % height in meters from the ground % Camera pitch was computed using camera extrinsics provided in data set. pitch = 0; % pitch of the camera, towards the ground, in degrees camIntrinsics = cameraIntrinsics(focalLength,principalPoint,imageSize); sensor = monoCamera(camIntrinsics,height,'Pitch',pitch); end
function occupancyGrid = createOccupancyGridFromFreeSpaceEstimate(... freeSpaceBEV,birdsEyeConfig,gridX,gridY,cellSize) % Return an occupancy grid that contains the occupancy probability over % a uniform 2-D grid. % Number of cells in occupancy grid. numCellsX = ceil(gridX / cellSize); numCellsY = ceil(gridY / cellSize); % Generate a set of (X,Y) points for each grid cell. These points are in % the vehicle's coordinate system. Start by defining the edges of each grid % cell. % Define the edges of each grid cell in vehicle coordinates. XEdges = linspace(0,gridX,numCellsX); YEdges = linspace(-gridY/2,gridY/2,numCellsY); % Next, specify the number of sample points to generate along each % dimension within a grid cell. Use these to compute the step size in the % X and Y direction. The step size will be used to shift the edge values of % each grid to produce points that cover the entire area of a grid cell at % the desired resolution. % Sample 20 points from each grid cell. Sampling more points may produce % smoother estimates at the cost of additional computation. numSamplePoints = 20; % Step size needed to sample number of desired points. XStep = (XEdges(2)-XEdges(1)) / (numSamplePoints-1); YStep = (YEdges(2)-YEdges(1)) / (numSamplePoints-1); % Finally, slide the set of points across both dimensions of the grid % cells. Sample the occupancy probability along the way using % griddedInterpolant. % Create griddedInterpolant for sampling occupancy probability. Use 1 % minus the free space confidence to represent the probability of occupancy. occupancyProb = 1 - freeSpaceBEV; sz = size(occupancyProb); [y,x] = ndgrid(1:sz(1),1:sz(2)); F = griddedInterpolant(y,x,occupancyProb); % Initialize the occupancy grid to zero. occupancyGrid = zeros(numCellsY*numCellsX,1); % Slide the set of points XEdges and YEdges across both dimensions of the % grid cell. for j = 1:numSamplePoints % Increment sample points in the X-direction X = XEdges + (j-1)*XStep; for i = 1:numSamplePoints % Increment sample points in the Y-direction Y = YEdges + (i-1)*YStep; % Generate a grid of sample points in bird's-eye-view vehicle coordinates [XGrid,YGrid] = meshgrid(X,Y); % Transform grid of sample points to image coordinates xy = vehicleToImage(birdsEyeConfig,[XGrid(:) YGrid(:)]); % Clip sample points to lie within image boundaries xy = max(xy,1); xq = min(xy(:,1),sz(2)); yq = min(xy(:,2),sz(1)); % Sample occupancy probabilities using griddedInterpolant and keep % a running sum. occupancyGrid = occupancyGrid + F(yq,xq); end end % Determine mean occupancy probability. occupancyGrid = occupancyGrid / numSamplePoints^2; occupancyGrid = reshape(occupancyGrid,numCellsY,numCellsX); end