Создайте сетку заполнения Используя монокулярную камеру и Семантическую Сегментацию

В этом примере показано, как оценить свободное пространство вокруг транспортного средства и создать сетку заполнения с помощью семантической сегментации и глубокого обучения. Вы затем используете эту сетку заполнения, чтобы создать транспортное средство 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 Объект (Automated Driving Toolbox), представляющий монокулярную камеру раньше, собирал данные CamVid [1]. Конфигурирование monoCamera (Automated Driving Toolbox) требует внутренних параметров камеры и значений внешних параметров, которые были оценены данные об использовании, обеспеченные в наборе данных CamVid. Чтобы оценить внутренние параметры камеры, функция использовала калибровочные изображения шахматной доски CamVid и Camera Calibrator (Computer Vision Toolbox) приложение. Оценки значений внешних параметров камеры, таких как высота и тангаж, были выведены из внешних данных, оцененных авторами набора данных CamVid.

% Create monoCamera for CamVid data.
sensor = camvidMonoCameraSensor();

Учитывая настройку камеры, birdsEyeView Объект (Automated Driving Toolbox) преобразовывает оригинальное изображение к виду с высоты птичьего полета. Этот объект позволяет вам определить площадь, что вы хотите преобразованные координаты транспортного средства использования. Обратите внимание на то, что модули координаты транспортного средства были установлены monoCamera Объект (Automated Driving Toolbox), когда высота монтирования камеры была задана в метрах. Например, если бы высота была задана в миллиметрах, остальная часть симуляции использовала бы миллиметры.

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

Области дальше от датчика являются более расплывчатыми, из-за наличия меньшего количества пикселей и таким образом требования большего объема интерполяции.

Создайте сетку заполнения на основе оценки свободного пространства

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

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

  1. Задайте размерности сетки заполнения в координатах транспортного средства.

  2. Сгенерируйте ряд (X, Y) точки для каждой ячейки сетки. Эти точки находятся в системе координат транспортного средства.

  3. Преобразуйте точки от координатного пространства транспортного средства (X, Y) в вид с высоты птичьего полета отображают координатное пространство (x, y) использование vehicleToImage (Automated Driving Toolbox) преобразовывает.

  4. Произведите значения доверия свободного пространства в (x, y) местоположения с помощью griddedInterpolant интерполировать значения доверия свободного пространства, которые не являются точно в пиксельных центрах в изображении.

  5. Заполните ячейку сетки заполнения средним значением доверия свободного пространства для всех (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 (Automated Driving Toolbox). Создайте birdsEyePlot (Automated Driving Toolbox) и добавляет сетку заполнения на верхней части с помощью 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 (Automated Driving Toolbox).

% 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

Отображение данных из нескольких датчиков полезно для диагностирования и отладки решений, принятых автономными транспортными средствами.

Создайте транспортное средство Costmap Используя сетку заполнения

vehicleCostmap (Automated Driving Toolbox) обеспечивает функциональность, чтобы проверять, заняты ли местоположения, в транспортном средстве или мировых координатах, или свободны. Эта проверка требуется для любого алгоритма планирования пути или принятия решений. Создайте vehicleCostmap (Automated Driving Toolbox) с помощью сгенерированного occupancyGrid.

% Create the costmap.
costmap = vehicleCostmap(flipud(occupancyGrid), ...
    'CellSize',cellSize, ...
    'MapLocation',[0,-spaceToOneSide]);
costmap.CollisionChecker.InflationRadius = 0;

% 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 (Automated Driving Toolbox), создайте набор местоположений в мировых координатах. Эти местоположения представляют путь, который могло пересечь транспортное средство.

% Create a set of locations in vehicle coordinates.
candidateLocations = [
    8 0.375
    10 0.375
    12 2
    14 0.375   
    ];

Используйте checkOccupied (Automated Driving Toolbox), чтобы проверять, занято ли каждое местоположение или свободно. На основе результатов за потенциальным путем может быть невозможно следовать, потому что он сталкивается с препятствиями, заданными в 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 (Automated Driving Toolbox) и checkOccupied (Automated Driving Toolbox), показанный выше, иллюстрирует основные операции, используемые планировщиками пути, такими как pathPlannerRRT (Automated Driving Toolbox). Узнайте больше о планировании пути в Автоматизированном Камердинере Парковки (Automated Driving Toolbox) пример.

Ссылки

[1] Brostow, Габриэль Дж., Жюльен Фокер и Роберто Сиполья. "Семантические Классы объектов в Видео: база данных основной истины высокой четкости". Pattern Recognition Letters. Vol. 30, Issue 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].
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