°
Изображение птичьего глаза вокруг транспортного средстваВ этом примере показано, как создать изображение вида птицы на 360 ° вокруг транспортного средства для использования в системе мониторинга вида вокруг.
Мониторинг объемного обзора является важной функцией безопасности, предоставляемой передовыми системами помощи водителю (ADAS). Эти системы мониторинга уменьшают слепые зоны и помогают драйверам понять относительное положение своего транспортного средства относительно окружающей среды, делая плотные маневры парковки более легкими и безопасными. Типичная система контроля кругового обзора состоит из четырёх fisheye-камер» с полем зрения 180 °, установленных на четырех сторонах транспортного средства. На дисплее в автомобиле показан вид автомобиля спереди, слева, справа, сзади и птичьего полета. В то время как четыре вида с четырех камер являются тривиальными для отображения, создание вида птичьего полета окружающей среды транспортного средства требует внутренней и внешней калибровки камеры и сшивания изображения, чтобы объединить несколько поля зрения камеры.
В этом примере вы сначала калибруете многокамерную систему, чтобы оценить параметры камеры. Затем вы используете калиброванные камеры, чтобы создать изображение окружения с видом на птицу путем сшивания изображений с нескольких камер.
Во-первых, калибруйте многокамерную систему путем оценки внутренних и внешних параметров камеры путем построения monoCamera
объект для каждой камеры в многокамерной системе. В целях рисунка этот пример использует изображения, сделанные с восьми направлений одной камерой с 78˚ полем зрения, покрывающим 360˚ вокруг транспортного средства. Настройка имитирует многокамерную систему, установленную на крыше транспортного средства.
Калибровка камеры является важным шагом в процессе создания вида птичьего полета. Он оценивает внутренние параметры камеры, которые требуются для оценки внешности камеры, удаления искажений в изображениях, измерения реальных расстояний и, наконец, генерации изображения с видом на глаз птицы.
В этом примере камера была калибрована с помощью шахматного калибровочного шаблона в приложении Single Camera Calibrator, и параметры камеры были экспортированы в cameraParams.mat
. Загрузите эти предполагаемые внутренние параметры камеры.
ld = load("cameraParams.mat");
Поскольку этот пример имитирует восемь камер, скопируйте загруженные признаки восемь раз. Если вы используете восемь различных камер, калибруйте каждую камеру отдельно и сохраните их собственные параметры в массиве ячеек с именем intrinsics
.
numCameras = 8; intrinsics = cell(numCameras, 1); intrinsics(:) = {ld.cameraParams.Intrinsics};
На этом шаге вы оцениваете внешнюю составляющую каждой камеры, чтобы определить ее положение в системе координат транспортного средства. Оценка внешности включает захват калибровочного шаблона из восьми камер в определенной ориентации относительно дороги и транспортного средства. В этом примере используется горизонтальная ориентация калибровочного шаблона. Для получения дополнительной информации о процессе оценки внешней модели камеры и ориентации шаблона, смотрите Калибровка Монокулярной Камеры.
Поместите калибровочный шаблон в горизонтальную ориентацию параллельно земле и на соответствующую высоту так, чтобы все угловые точки массива были видны. Измерьте высоту после размещения калибровочного шаблона и размера квадрата в шахматной доске. В этом примере шаблон был размещен горизонтально на высоте 62,5 см, чтобы сделать шаблон видимым для камеры. Размер квадрата в шахматном порядке составлял 29 мм.
% Measurements in meters
patternOriginHeight = 0.625;
squareSize = 29e-3;
Следующий рисунок иллюстрирует правильную ориентацию калибровочного шаблона для камер вдоль четырех основных направлений относительно осей транспортного средства. Однако для генерации вида птичьего полета в этом примере используются четыре дополнительные камеры, ориентированные вдоль направлений, которые отличаются от основных направлений. Чтобы оценить внешнюю составляющую для этих камер, выберите и присвойте предпочтительную ориентацию среди четырех основных направлений. Для примера, если вы снимаете с фронтальной камеры, выровняйте оси X - и Y шаблона как показано на следующем рисунке.
Переменная patternPositions
сохраняет предпочтительные варианты ориентации для всех восьми камер. Эти варианты определяют относительную ориентацию между осями шаблона и осями транспортного средства для estimateMonoCameraParameters
функция. Отобразите изображения, расположенные по положениям их камеры относительно транспортного средства.
patternPositions = ["front", "left" , "left" , "back" ,... "back" , "right", "right", "front"]; extrinsicsCalibrationImages = cell(1, numCameras); for i = 1:numCameras filename = "extrinsicsCalibrationImage" + string(i) + ".jpg"; extrinsicsCalibrationImages{i} = imread(filename); end helperVisualizeScene(extrinsicsCalibrationImages, patternPositions)
Чтобы оценить внешние параметры одной монокулярной камеры, выполните следующие шаги:
Удалите искажения в изображении.
Обнаружение углов шахматного квадрата на изображении.
Сгенерируйте мировые точки шахматной доски.
Использование estimateMonoCameraParameters
функция для оценки внешних параметров.
Используйте внешние параметры, чтобы создать monoCamera
объект, принимая, что расположение датчика в источник системы транспортного средства.
В этом примере в настройке используется одна камера, которая была повернута вручную вокруг подставки камеры. Хотя фокальный центр камеры перемещался во время этого движения, для простоты, этот пример принимает, что датчик остался в том же месте (в источник). Однако расстояния между камерами на реальном транспортном средстве могут быть измерены и введены в свойство местоположения датчика monoCamera
.
monoCams = cell(1, numCameras); for i = 1:numCameras % Undistort the image. undistortedImage = undistortImage(extrinsicsCalibrationImages{i}, intrinsics{i}); % Detect checkerboard points. [imagePoints, boardSize] = detectCheckerboardPoints(undistortedImage,... "PartialDetections", false); % Generate world points of the checkerboard. worldPoints = generateCheckerboardPoints(boardSize, squareSize); % Estimate extrinsic parameters of the monocular camera. [pitch, yaw, roll, height] = estimateMonoCameraParameters(intrinsics{i}, ... imagePoints, worldPoints, patternOriginHeight,... "PatternPosition", patternPositions(i)); % Create a monoCamera object, assuming the camera is at origin. monoCams{i} = monoCamera(intrinsics{i}, height, ... "Pitch", pitch, ... "Yaw" , yaw, ... "Roll" , roll, ... "SensorLocation", [0, 0]); end
°
Изображение вида птичьего глазаИспользуйте monoCamera
объекты, сконфигурированные с помощью предполагаемых параметров камеры, чтобы генерировать отдельные изображения вида птицы с восьми камер. Сшить их, чтобы создать 360 °
изображение с видом на птицу.
Снимите сцену с камер и загрузите изображения в рабочем пространстве MATLAB.
sceneImages = cell(1, numCameras); for i = 1:numCameras filename = "sceneImage" + string(i) + ".jpg"; sceneImages{i} = imread(filename); end helperVisualizeScene(sceneImages)
Укажите прямоугольную область вокруг транспортного средства, которую вы хотите преобразовать в вид птичьего полета, и размер выходного изображения. В этом примере самые дальние объекты на захваченных изображениях находятся на расстоянии около 4,5 м.
Создайте квадратный выходной вид, который покрывает радиус 4,5 м вокруг транспортного средства.
distFromVehicle = 4.5; % in meters outView = [-distFromVehicle, distFromVehicle, ... % [xmin, xmax, -distFromVehicle, distFromVehicle]; % ymin, ymax] outImageSize = [640, NaN];
Чтобы создать изображение вида птицы из каждого monoCamera
объект, следуйте этим шагам.
Удалите искажения в изображении.
Создайте birdsEyeView
объект.
Преобразуйте неискаженное изображение в изображение с видом на птичий глаз с помощью transformImage
функция.
bevImgs = cell(1, numCameras); birdsEye = cell(1, numCameras); for i = 1:numCameras undistortedImage = undistortImage(sceneImages{i}, monoCams{i}.Intrinsics); birdsEye{i} = birdsEyeView(monoCams{i}, outView, outImageSize); bevImgs{i} = transformImage(birdsEye{i}, undistortedImage); end helperVisualizeScene(bevImgs)
Проверьте точность процесса оценки внешних данных с помощью helperBlendImages
функция, которая смешивает восемь изображений с видом на глаз птицы. Затем отобразите изображение.
tiled360DegreesBirdsEyeView = zeros(640, 640, 3); for i = 1:numCameras tiled360DegreesBirdsEyeView = helperBlendImages(tiled360DegreesBirdsEyeView, bevImgs{i}); end figure imshow(tiled360DegreesBirdsEyeView)
В данном примере начальные результаты процесса оценки внешних данных содержат некоторые несоответствия. Однако они могут быть связаны с неправильным предположением, что камера была расположена в источник системы транспортного средства. Исправление расхождения требует регистрации изображения.
Во-первых, соответствовать функциям. Сравнение и визуализация результатов использования matchFeatures
с matchFeaturesInRadius
, что позволяет ограничивать контуры поиска с помощью геометрических ограничений. Согласование функции с ограничениями может улучшить результаты, когда шаблоны повторяются, например, на дорогах, где разметка дорожного покрытия и дорожные знаки являются стандартными. В заводских настройках можно разработать более подробное строение калибровочных шаблонов и текстурированного фона, которая дополнительно улучшает процесс калибровки и регистрации. Пример Feature Based Panoramic Image Stitching подробно объясняет, как зарегистрировать несколько изображений и сшить их, чтобы создать панораму. Результаты показывают, что ограничение функции соответствие с использованием matchFeaturesInRadius
соответствует только соответствующим парам функций в этих двух изображениях и отбрасывает любые функции, соответствующие несвязанным репититивным шаблонам.
% The last two images of the scene best demonstrate the advantage of % constrained feature matching as they have many repetitive pavement % markings. I = bevImgs{7}; J = bevImgs{8}; % Extract features from the two images. grayImage = rgb2gray(I); pointsPrev = detectKAZEFeatures(grayImage); [featuresPrev, pointsPrev] = extractFeatures(grayImage, pointsPrev); grayImage = rgb2gray(J); points = detectKAZEFeatures(grayImage); [features, points] = extractFeatures(grayImage, points); % Match features using the two methods. indexPairs1 = matchFeaturesInRadius(featuresPrev, features, points.Location, ... pointsPrev.Location, 15, ... "MatchThreshold", 10, "MaxRatio", 0.6); indexPairs2 = matchFeatures(featuresPrev, features, "MatchThreshold", 10, ... "MaxRatio", 0.6); % Visualize the matched features. tiledlayout(1,2) nexttile showMatchedFeatures(I, J, pointsPrev(indexPairs1(:,1)), points(indexPairs1(:,2))) title(sprintf('%d pairs matched\n with spatial constraints', size(indexPairs1, 1))) nexttile showMatchedFeatures(I, J, pointsPrev(indexPairs2(:,1)), points(indexPairs2(:,2))) title(sprintf('%d pairs matched\n without spatial constraints', size(indexPairs2,1)))
Функции helperRegisterImages
и helperStitchImages
были написаны на основе примера Feature Based Panoramic Image Stitching с использованием matchFeaturesInRadius
. Обратите внимание, что традиционного панорамного сшивания недостаточно для этого приложения, поскольку каждое изображение регистрируется только относительно предыдущего изображения. Следовательно, последнее изображение может не выровняться точно с первым изображением, получая плохо выровненное объемное изображение 360 ° .
Этот недостаток в процессе регистрации можно преодолеть, зарегистрировав изображения пакетно:
Зарегистрируйте и сшейте первые четыре изображения, чтобы сгенерировать изображение левой стороны транспортного средства.
Зарегистрируйте и сшейте последние четыре изображения, чтобы сгенерировать изображение правой стороны транспортного средства.
Зарегистрируйте и сшейте левую и правую сторону, чтобы получить полное 360 ° изображения сцены с видом на птицу.
Обратите внимание на использование большего радиуса соответствия для сшивания изображений на шаге 3 по сравнению с шагами 1 и 2. Это происходит из-за изменения относительных положений изображений во время первых двух шагов регистрации.
% Combine the first four images to get the stitched leftSideview and the % spatial reference object Rleft. radius = 15; leftImgs = bevImgs(1:4); tforms = helperRegisterImages(leftImgs, radius); [leftSideView, Rleft] = helperStitchImages(leftImgs, tforms); % Combine the last four images to get the stitched rightSideView. rightImgs = bevImgs(5:8); tforms = helperRegisterImages(rightImgs, radius); rightSideView = helperStitchImages(rightImgs, tforms); % Combine the two side views to get the 360° bird's-eye-view in % surroundView and the spatial reference object Rsurround radius = 50; imgs = {leftSideView, rightSideView}; tforms = helperRegisterImages(imgs, radius); [surroundView, Rsurround] = helperStitchImages(imgs, tforms); figure imshow(surroundView)
Одно из преимуществ использования изображений для измерения расстояний в виде птичьего глаза заключается в том, что расстояния могут быть вычислены на изображении благодаря планарной природе земли. Можно измерить различные расстояния, которые применяются для приложений ADAS, такие как указания по близости области значений чертежам и автомобилю , оборудованному датчиком контуров. Измерение расстояния включает преобразование мировых точек в системе координат транспортного средства в изображение вида птицы, которое можно сделать с помощью vehicleToImage
функция. Однако обратите внимание, что каждое из восьми изображений вида птичьего глаза претерпело два геометрических преобразования в процессе регистрации изображения. Таким образом, в дополнение к использованию vehicleToImage
функция, вы должны применить эти преобразования к точкам изображения. The helperVehicleToBirdsEyeView
функция применяет эти преобразования. Точки проецируются на первое изображение вида птицы, поскольку это изображение претерпело наименьшее количество преобразований в процессе регистрации.
Правила круговой области значений вокруг транспортного средства могут помочь драйверам маневрировать в плотных парковочных местах. Нарисуйте круговые инструкции на 2, 3 и 4 метрах на изображении с видом на птичий глаз 360 °:
Преобразуйте центр транспортного средства и точку в круговом руководстве в системе координат транспортного средства в изображение вида птицы на 360 ° с помощью helperVehicleToBirdsEyeView
функция.
Вычислите радиус круговой направляющей в пикселях, найдя расстояние между двумя преобразованными точками.
Нарисуйте инструкции, используя insertShape
и пометьте инструкции, используя insertText
функция.
proximityRange = [2, 3, 4]; % in meters colors = ["red", "yellow", "green"]; refBirdsEye = birdsEye{1}; Rout = {Rleft, Rsurround}; vehicleCenter = [0, 0]; vehicleCenterInImage = helperVehicleToBirdsEyeView(refBirdsEye, vehicleCenter, Rout); for i = 1:length(proximityRange) % Estimate the radius of the circular guidelines in pixels given its % radius in meters. circlePoint = [0, proximityRange(i)]; circlePointInImage = helperVehicleToBirdsEyeView(refBirdsEye, circlePoint, Rout); % Compute radius using euclidean norm. proximityRangeInPixels = norm(circlePointInImage - vehicleCenterInImage, 2); surroundView = insertShape(surroundView, "Circle", [vehicleCenterInImage, proximityRangeInPixels], ... "LineWidth", 1, ... "Color", colors(i)); labelText = string(proximityRange(i)) + " m"; surroundView = insertText(surroundView, circlePointInImage, labelText,... "TextColor", "White", ... "FontSize", 14, ... "BoxOpacity", 0); end imshow(surroundView)
Граничные линии для транспортного средства помогают драйверу понять относительное положение транспортного средства относительно окружающей среды. Нарисуйте автомобиль , оборудованный датчиком контура с помощью такой же процедуры, как и в руководствах по близости чертежа. The helperGetVehicleBoundaryOnBEV
функция возвращает угловые точки контура транспортного средства на изображении вида птицы на 360 °, учитывая положение и размер транспортного средства. Отображение инструкций на сцене с помощью showShape
функция.
vehicleCenter = [0, 0]; vehicleSize = [5.6, 2.4]; % length-by-width in meters [polygonPoints, vehicleLength, vehicleWidth] = helperGetVehicleBoundaryOnBEV(refBirdsEye, ... vehicleCenter, ... vehicleSize, ... Rout); showShape("polygon", polygonPoints, "Label", "Ego Vehicle")
Кроме того, вы также можете наложить моделируемое транспортное средство на сцену для визуально приятных результатов.
% Read the picture of the simulation vehicle. egoVehicle = imread("vehicle.png", "BackgroundColor", [0 0 0]); % Bring the simulation vehicle into the vehicle coordinate system. egoVehicle = imresize(egoVehicle, [vehicleLength, vehicleWidth]); vehicle = zeros(size(surroundView), "uint8"); xIdx = polygonPoints(1,1) + (1:vehicleWidth); yIdx = polygonPoints(1,2) + (1:vehicleLength); vehicle(yIdx, xIdx, :) = egoVehicle; % Overlay the simulation vehicle on the 360° bird's-eye-view image. sceneBirdsEyeView = helperOverlayImage(vehicle, surroundView);
Наконец, давайте исключим черные границы на изображении, выбрав меньшую область значений от источника системы координат транспортного средства.
distFromVehicle = 4.25; % in meters
[x, y, h, w] = helperGetImageBoundaryOnBEV(refBirdsEye, distFromVehicle, Rout);
croppedSceneBirdsEyeView = imcrop(sceneBirdsEyeView, [x, y, h, w]);
imshow(croppedSceneBirdsEyeView)
Процедура, показанная в этом примере, может быть расширена, чтобы создать систему контроля кругового обзора производственного класса. Это требует точной калибровки камеры, чтобы оценить положения монокулярной камеры с минимальными ошибками и настроить регистрационные гиперпараметры. Пример также может быть изменен, чтобы использовать fisheye-камеры.
helperVisualizeScene
ФункцияThe helperVisualizeScene
Функция отображает изображения, расположенные по положениям их камер относительно транспортного средства на размещении мозаичного графика 3 на 3, и опционально показывает текст заголовка для каждой плитки.
function helperVisualizeScene(images, varargin) numImages = numel(images); if nargin == 2 titleText = varargin{1}; else titleText = strings(numImages,1); end % Define index locations to simulate the camera positions relative to the vehicle. cameraPosInFigureWindow = [1, 4, 7, 8, 9, 6, 3, 2]; egoVehiclePosInFigureWindow = 5; figure t = tiledlayout(3, 3, "TileSpacing", "compact", "Padding", "compact"); for i = 1:numImages nexttile(cameraPosInFigureWindow(i)) imshow(images{i}) title(titleText(i)) end % Visualize the vehicle on the scene. egoVehicle = imread("vehicle.png", "BackgroundColor", [1 1 1]); nexttile(egoVehiclePosInFigureWindow) imshow(egoVehicle) if nargin == 2 title("Ego Vehicle") title(t, "Pattern positions"); end end
helperBlendImages
Function
The helperBlendImages
функция выполняет альфа-смешение с заданными двумя входными изображениями, I1
и I2
, со значениями альфа, которые пропорциональны центральному шву каждого изображения. Область выхода Iout
является линейной комбинацией входных изображений:
function outputImage = helperBlendImages(I1, I2) arguments I1 uint8 I2 uint8 end % Identify the image regions in the two images by masking out the black % regions. mask1 = sum(I1, 3) ~= 0; mask2 = sum(I2, 3) ~= 0; maskc = mask1 & mask2; % Compute alpha values that are proportional to the center seam of the two % images. alpha1 = ones(size(mask1,1:2)); alpha2 = ones(size(mask2,1:2)); dist1 = bwdist(edge(mask1)); dist2 = bwdist(edge(mask2)); alpha1(maskc) = double(dist1(maskc) > dist2(maskc)); alpha2(maskc) = double(dist1(maskc) <= dist2(maskc)); I1 = double(I1); I2 = double(I2); outputImage = alpha1.*I1 + alpha2.*I2; outputImage = uint8(outputImage); end
helperRegisterImages
ФункцияThe helperRegisterImages
функция регистрирует массив ячеек images
последовательно используя радиус поиска для matchFeaturesInRadius
и возвращает преобразования, tforms
.
function tforms = helperRegisterImages(images, radius) params.Radius = radius; params.MatchThreshold = 10; params.MaxRatio = 0.6; params.Confidence = 99.9; params.MaxDistance = 2; params.MaxNumTrials = 2000; numImages = numel(images); % Store points and features for all images. features = cell(1,numImages); points = cell(1,numImages); for i = 1:numImages grayImage = rgb2gray(images{i}); points{i} = detectKAZEFeatures(grayImage); [features{i}, points{i}] = extractFeatures(grayImage, points{i}); end % Initialize all the transforms to the identity matrix. tforms(numImages) = affine2d(eye(3)); % Set the seed for reproducibility. rng(0); % Find the relative transformations between each image pair. for i = 2:numImages % Find correspondences between images{i} and images{i-1} using % constrained feature matching. indexPairs = matchFeaturesInRadius(features{i-1}, features{i}, points{i}.Location, ... points{i-1}.Location, params.Radius, ... "MatchThreshold", params.MatchThreshold, ... "MaxRatio", params.MaxRatio); % Estimate the transformation between images{i} and images{i-1}. matchedPointsPrev = points{i-1}(indexPairs(:,1), :); matchedPoints = points{i}(indexPairs(:,2), :); tforms(i) = estimateGeometricTransform2D(matchedPoints, matchedPointsPrev,"similarity",... "Confidence" , params.Confidence, ... "MaxDistance", params.MaxDistance, ... "MaxNumTrials",params.MaxNumTrials); % Compute the transformation that maps images{i} to the stitched % image as T(i)*T(i-1)*...*T(1). tforms(i).T = tforms(i).T*tforms(i-1).T; end end
helperStitchImages
ФункцияThe helperStitchImages
функция применяет преобразования tforms
к входу изображениям и смешивает их, чтобы создать outputImage
. Это дополнительно возвращает outputView,
который можно использовать, чтобы преобразовать любую точку из первого изображения в заданной последовательности изображений в выходное изображение.
function [outputImage, outputView] = helperStitchImages(images, tforms) numImages = numel(images); imageSize = zeros(numImages,2); xlim = zeros(numImages,2); ylim = zeros(numImages,2); % Compute the output limits for each transform. for i = 1:numel(images) imageSize(i,:) = size(images{i}, 1:2); [xlim(i,:), ylim(i,:)] = outputLimits(tforms(i), ... [1 imageSize(i,2)], ... [1 imageSize(i,1)]); end % Find the minimum and maximum output limits. maxImageSize = max(imageSize); xMin = min([1; xlim(:)]); xMax = max([maxImageSize(2); xlim(:)]); yMin = min([1; ylim(:)]); yMax = max([maxImageSize(1); ylim(:)]); % Width and height of panorama. width = round(xMax - xMin); height = round(yMax - yMin); % Initialize the "empty" panorama. outputImage = zeros([height width 3], "like", images{1}); % Create a 2-D spatial reference object defining the size of the panorama. xLimits = [xMin xMax]; yLimits = [yMin yMax]; outputView = imref2d([height width], xLimits, yLimits); % Step 7 - Stitch the images. for i = 1:numel(tforms) % Apply transformation. warpedImage = imwarp(images{i}, tforms(i), "OutputView", outputView); % Blend the images. outputImage = helperBlendImages(warpedImage, outputImage); end end
helperVehicleToBirdsEyeView
ФункцияThe helperVehicleToBirdsEyeView
функция преобразует заданные мировые точки в системе координат транспортного средства в точки на изображении вида птицы на 360 °.
function tranformedImagePoints = helperVehicleToBirdsEyeView(birdsEye, vehiclePoints, Rout) % Transform the 3D worldPoints in vehicle coordinate system to 2D % imagePoints in the Bird's-Eye-View (BEV) image. imagePoints = vehicleToImage(birdsEye, vehiclePoints); % Transform these imagePoints from single BEV image to 360° bird's-eye-view images. [xPoints, yPoints] = worldToIntrinsic(Rout{1}, imagePoints(:,1), imagePoints(:,2)); [xPoints, yPoints] = worldToIntrinsic(Rout{2}, xPoints, yPoints); tranformedImagePoints = [xPoints, yPoints]; end
helperGetImageBoundaryOnBEV
ФункцияThe helperGetImageBoundaryOnBEV
функция возвращает положение и размер ограничивающего прямоугольника на изображении в виде птичьего полета, который задает квадратную площадь, которая покрывает distFromVehicle
метры вокруг транспортного средства.
function [x, y, h, w] = helperGetImageBoundaryOnBEV(birdsEye, distFromVehicle, Rout) % Define three corner points of the vehicle's bounding box. vehiclePoints = [ distFromVehicle, distFromVehicle; -distFromVehicle, distFromVehicle; -distFromVehicle,-distFromVehicle]; % Flip the x and y axes between the world and vehicle coordinate % systems. vehiclePoints = fliplr(vehiclePoints); imagePoints = helperVehicleToBirdsEyeView(birdsEye, vehiclePoints, Rout); x = imagePoints(1,1); y = imagePoints(1,2); h = abs(imagePoints(1,1) - imagePoints(2,1)); w = abs(imagePoints(2,2) - imagePoints(3,2)); end
helperGetVehicleBoundaryOnBEV
ФункцияThe helperGetVehicleBoundaryOnBEV
функция возвращает угловые точки контура транспортного средства, учитывая его положение и размер.
function [polygonPoints, vehicleLength, vehicleWidth] = ... helperGetVehicleBoundaryOnBEV(birdsEye, vehicleCenter, vehicleSize, Rout) x = vehicleCenter(1); y = vehicleCenter(2); % Find half length and half width in a and b respectively. a = vehicleSize(1)/2; b = vehicleSize(2)/2; % Define vehiclePoints in the world coordinate system. vehiclePoints = [ x+b, y+a; x+b, y-a; x-b, y-a; x-b, y+a ]; % Flip the x and y axes between the world and vehicle coordinate % systems. vehiclePoints = fliplr(vehiclePoints); imagePoints = helperVehicleToBirdsEyeView(birdsEye, vehiclePoints, Rout); xPoints = ceil(imagePoints(:,1)); yPoints = ceil(imagePoints(:,2)); vehicleLength = abs(yPoints(1) - yPoints(2)); vehicleWidth = abs(xPoints(2) - xPoints(3)); % x,y points as points on a polygon for showShape. polygonPoints = [xPoints , yPoints;... % Close the polygon by setting the last point as first point. xPoints(1), yPoints(1)]; end
helperOverlayImage
ФункцияThe helperOverlayImage
функция накладывает topImage
на bottomImage
и возвращает результат в outputImage
.
function outputImage = helperOverlayImage(topImage, bottomImage) blender = vision.AlphaBlender("Operation", "Binary mask", ... "MaskSource", "Input port"); mask = sum(topImage, 3) ~= 0; outputImage = step(blender, bottomImage, topImage, mask); end
detectKAZEFeatures
| estimateGeometricTransform2D
| estimateMonoCameraParameters
| matchFeatures
| matchFeaturesInRadius
| undistortImage