Сконфигурируйте и используйте объект monoCamera
отобразить информацию, предоставленную в координатах автомобиля о видеодисплее.
Отображение данных, зарегистрированных в координатах автомобиля на записанном видео, является неотъемлемой частью разметки достоверных данных и анализирующий отслеживающие результаты. Используя двумерный вид с высоты птичьего полета может помочь вам понять полную среду, но иногда трудно коррелировать видео с отображением вида с высоты птичьего полета. В частности, эта проблема становится хуже при использовании стороннего датчика, где вы не можете получить доступ к необработанному видео, записанному датчиком, и необходимо использовать видео, записанное отдельной камерой.
Automated Driving Toolbox™ обеспечивает объект
, который упрощает преобразование между координатами автомобиля и координатами изображений. Этот пример считывает данные, зарегистрированные видео датчиком, установленным на тестовом автомобиле. Затем это отображает данные по видео, записанному отдельной видеокамерой, установленной на том же автомобиле. Данные и видео были зарегистрированы на следующих уровнях:monoCamera
Сообщенная информация маршрута: 20 раз в секунду
Объекты видения, о которых сообщают: 10 раз в секунду
Частота видеокадров: 20 кадров в секунду
Отобразите кадр с видео аннотациями
Выбранный кадр соответствует 5,9 секундам в видеоклип, когда существует несколько объектов показать на видео.
% Set up video reader and player
videoFile = '01_city_c2s_fcw_10s.mp4';
videoReader = VideoReader(videoFile);
videoPlayer = vision.DeployableVideoPlayer;
% Jump to the desired frame
time = 5.9;
videoReader.CurrentTime = time;
frameWithoutAnnotations = readFrame(videoReader);
imshow(frameWithoutAnnotations);
title('Original Video Frame')
Получите соответствующие записанные данные.
recordingFile = '01_city_c2s_fcw_10s_sensor.mat';
[visionObjects, laneReports, timeStep, numSteps] = readDetectionsFile(recordingFile);
currentStep = round(time / timeStep) + 1;
videoDetections = processDetections(visionObjects(currentStep));
laneBoundaries = processLanes(laneReports(currentStep));
% Set up the monoCamera object for on-video display
sensor = setupMonoCamera(videoReader);
frameWithAnnotations = updateDisplay(frameWithoutAnnotations, sensor, videoDetections, laneBoundaries);
imshow(frameWithAnnotations);
title('Annotated Video Frame')
Отобразите клип с видео аннотациями
Чтобы отобразить видеоклип с аннотациями, просто повторите покадровую аннотацию. Видео показывает, что автомобиль делает подачу немного вверх и вниз, который изменяет угол подачи. Никакая попытка не была предпринята, чтобы компенсировать это движение подачи. В результате преобразование из координат автомобиля, чтобы отобразить координаты немного неточно на некоторых кадрах.
% Reset the time back to zero
currentStep = 0; % Reset the recorded data timestep
videoReader.CurrentTime = 0; % Reset the video reader time
while currentStep < numSteps && hasFrame(videoReader)
% Update scenario counters
currentStep = currentStep + 1;
% Get the current time
tic
% Prepare the detections to the tracker
videoDetections = processDetections(visionObjects(currentStep), videoDetections);
% Process lanes
laneBoundaries = processLanes(laneReports(currentStep));
% Update video frame with annotations from the reported objects
frameWithoutAnnotations = readFrame(videoReader);
frameWithAnnotations = updateDisplay(frameWithoutAnnotations, sensor, videoDetections, laneBoundaries);
% The recorded data was obtained at a rate of 20 frames per second.
% Pause for 50 milliseconds for a more realistic display rate. If you
% process data and form tracks in this loop, you do not need this
% pause.
pause(0.05 - toc);
% Display annotated frame
videoPlayer(frameWithAnnotations);
end
Создайте моно камеру для на видеодисплее
Функция
setupMonoCamera
возвращает объект датчика monoCamera
, который используется для преобразования положений в координатах автомобиля, чтобы отобразить координаты.
Знание внутренних и внешних калибровочных параметров камеры очень важно для точного преобразования между координатами автомобиля и пикселем.
Запустите путем определения камеры внутренние параметры. Параметры в этой функции были оценены на основе модели камеры. Чтобы получить параметры для вашей камеры, используйте приложение Camera Calibrator.
Поскольку данные в этом примере имеют мало искажения, эта функция игнорирует коэффициенты искажения объектива. Параметры затем хранятся в объекте
cameraIntrinsics
.
Затем, задайте камеру extrinsics. Камера extrinsics относится к способу, которым камера смонтирована на автомобиле. Монтирование включает следующие свойства:
Высота: Монтирование высоты над землей, в метрах.
Подача: Подача камеры, в градусах, где положительный повернута ниже горизонта и к земле. В большинстве случаев камера передается немного ниже горизонта.
Список: Список камеры о ее оси. Например, если видео инвертируется перевернутым, используйте список = 180.
Отклонение от курса: Угол камеры боком, где положительный в направлении положительной оси Y (налево). Например, камера по ходу движения имеет угол отклонения от курса 0 градусов, и назад стоящая камера имеет угол отклонения от курса 180 градусов.
function sensor = setupMonoCamera(vidReader)
% Define the camera intrinsics from the video information
focalLength = [1260 1100]; % [fx, fy] % pixels
principalPoint = [360 245]; % [cx, cy] % pixels
imageSize = [vidReader.height, vidReader.width]; % [numRows, numColumns] % pixels
intrinsics = cameraIntrinsics(focalLength, principalPoint, imageSize);
% Define the camera mounting (camera extrinsics)
mountingHeight = 1.45; % height in meters from the ground
mountingPitch = 1.25; % pitch of the camera in degrees
mountingRoll = 0.15; % roll of the camera in degrees
mountingYaw = 0; % yaw of the camera in degrees
sensor = monoCamera(intrinsics, mountingHeight, ...
'Pitch', mountingPitch, ...
'Roll', mountingRoll, ...
'Yaw', mountingYaw);
end
Используя моно объект камеры обновить отображение
Функция
updateDisplay
отображает все объектные аннотации сверху кадра видео.
Обновление отображения включает следующие шаги:
Используя датчик
monoCamera
, чтобы преобразовать обнаружения, о которых сообщают, в ограничительные рамки и аннотирование кадра.
Используя метод
insertLaneBoundary
объекта parabolicLaneBoundary
вставить аннотации маршрута.
function frame = updateDisplay(frame, sensor, videoDetections, laneBoundaries)
% Allocate memory for bounding boxes
bboxes = zeros(numel(videoDetections), 4);
% Create the bounding boxes
for i = 1:numel(videoDetections)
% Use monoCamera sensor to convert the position in vehicle coordinates
% to the position in image coordinates.
% Notes:
% 1. The width of the object is reported and is used to calculate the
% size of the bounding box around the object (half width on each
% side). The height of the object is not reported. Instead, the
% function uses a height/width ratio of 0.85 for cars and 3 for
% pedestrians.
% 2. The reported location is at the center of the object at ground
% level, i.e., the bottom of the bounding box.
xyLocation1 = vehicleToImage(sensor, videoDetections(i).positions' + [0,videoDetections(i).widths/2]);
xyLocation2 = vehicleToImage(sensor, videoDetections(i).positions' - [0,videoDetections(i).widths/2]);
dx = xyLocation2(1) - xyLocation1(1);
% Define the height/width ratio based on object class
if strcmp(videoDetections(i).labels, 'Car')
dy = dx * 0.85;
elseif strcmp(videoDetections(i).labels, 'Pedestrian')
dy = dx * 3;
else
dy = dx;
end
% Estimate the bounding box around the vehicle. Subtract the height of
% the bounding box to define the top-left corner.
bboxes(i,:) =[(xyLocation1 - [0, dy]), dx, dy];
end
% Add labels
labels = {videoDetections(:).labels}';
% Add bounding boxes to the frame
if ~isempty(labels)
frame = insertObjectAnnotation(frame, 'rectangle', bboxes, labels,...
'Color', 'yellow', 'FontSize', 10, 'TextBoxOpacity', .8, 'LineWidth', 2);
end
% Display the lane boundary on the video frame
xRangeVehicle = [1, 100];
xPtsInVehicle = linspace(xRangeVehicle(1), xRangeVehicle(2), 100)';
frame = insertLaneBoundary(frame, laneBoundaries(1), sensor, xPtsInVehicle, ...
'Color', 'red');
frame = insertLaneBoundary(frame, laneBoundaries(2), sensor, xPtsInVehicle, ...
'Color', 'green');
end
Сводные данные
Этот пример показал, как создать объект датчика
monoCamera
и использовать его для экранных объектов, описанных в координатах автомобиля на видео, записанном отдельной камерой. Попытайтесь использовать зарегистрированные данные и собственную видеокамеру. Попытайтесь калибровать свою камеру, чтобы создать monoCamera
, который позволяет, чтобы преобразование от автомобиля отобразило координаты, и наоборот.
Поддерживание функций
readDetectionsFile - Читает записанный файл данных датчика. Записанные данные находятся в одной структуре, которая разделена на четыре массива
struct
. Этот пример использует только следующие два массива:
laneReports
, массив struct
, который сообщает о контурах маршрута. Это имеет эти поля: left
и right
. Каждый элемент массива соответствует различному такту. И left
и right
являются структурами с этими полями: isValid
, confidence
, boundaryType
, offset
, headingAngle
и curvature
.
visionObjects
, массив структур, который сообщает об обнаруженных объектах видения. Это имеет поля numObjects
(integer
) и object
(struct
). Каждый элемент массива соответствует различному такту. object
является массивом struct
, где каждый элемент является отдельным объектом с этими полями: id
, classification
, position (x;y;z)
, velocity(vx;vy;vz)
, size(dx;dy;dz)
. Примечание: z=vy=vz=dx=dz=0
function [visionObjects, laneReports, timeStep, numSteps] = readDetectionsFile(filename)
A = load(strcat(filename));
visionObjects = A.vision;
laneReports = A.lane;
% Prepare some time variables
timeStep = 0.05; % Lane data is provided every 50 milliseconds
numSteps = numel(visionObjects); % Number of recorded timesteps
end
processDetections - Читает записанные обнаружения видения. Этот пример извлекает только следующие свойства:
Положение: двумерный массив
[x, y]
в координатах автомобиля
Width: ширина объекта, как сообщается видео датчиком (Примечание: датчик не сообщает ни о какой другой размерности размера объекта.)
Метки: классификация, о которой сообщают, объекта
function videoDetections = processDetections(visionData, videoDetections)
% The video sensor reports a classification value as an integer
% according to the following enumeration (starting from 0)
ClassificationValues = {'Unknown', 'Unknown Small', 'Unknown Big', ...
'Pedestrian', 'Bike', 'Car', 'Truck', 'Barrier'};
% The total number of objects reported by the sensor in this frame
numVideoObjects = visionData.numObjects;
% The video objects are reported only 10 times per second, but the video
% has a frame rate of 20 frames per second. To prevent the annotations from
% flickering on and off, this function returns the values from the previous
% timestep if there are no video objects.
if numVideoObjects == 0
if nargin == 1 % Returning a result even if there is no previous value
videoDetections = struct('positions', {}, 'labels', {}, 'widths', {});
end
return;
else
% Prepare a container for the relevant properties of video detections
videoDetections = struct('positions', [], 'labels', [], 'widths', []);
for i = 1:numVideoObjects
videoDetections(i).widths = visionData.object(i).size(2);
videoDetections(i).positions = visionData.object(i).position(1:2);
videoDetections(i).labels = ClassificationValues{visionData.object(i).classification + 1};
end
end
end
processLanes - Считывает информацию маршрута, о которой сообщают, и преобразовывает его в объекты
parabolicLaneBoundary
.
Контуры маршрута обновляются на основе
laneReports
от записей. Датчик сообщает о маршрутах как о параметрах параболической модели: %
function laneBoundaries = processLanes(laneReports)
% Return processed lane boundaries
% Boundary type information
types = {'Unmarked', 'Solid', 'Dashed', 'Unmarked', 'BottsDots', ...
'Unmarked', 'Unmarked', 'DoubleSolid'};
% Read the recorded lane reports for this frame
leftLane = laneReports.left;
rightLane = laneReports.right;
% Create parabolicLaneBoundary objects for left and right lane boundaries
leftParams = cast([leftLane.curvature, leftLane.headingAngle, leftLane.offset], 'double');
leftBoundaries = parabolicLaneBoundary(leftParams);
leftBoundaries.BoundaryType = types{leftLane.boundaryType};
rightParams = cast([rightLane.curvature, rightLane.headingAngle, rightLane.offset], 'double');
rightBoundaries = parabolicLaneBoundary(rightParams);
rightBoundaries.BoundaryType = types{rightLane.boundaryType};
laneBoundaries = [leftBoundaries, rightBoundaries];
end
Смотрите также
Приложения
Функции
Объекты
Похожие темы