exponenta event banner

Структура из движения из двух видов

Структура из движения (SfM) - процесс оценки 3-D структуры сцены по набору 2-D изображений. В этом примере показано, как оценить позы калиброванной камеры по двум изображениям, восстановить 3-D структуру сцены до неизвестного масштабного коэффициента, а затем восстановить действительный масштабный коэффициент путем обнаружения объекта известного размера.

Обзор

В этом примере показано, как восстановить сцену 3-D из пары изображений 2-D сделанных с помощью камеры, откалиброванной с помощью калибратора камеры. Алгоритм состоит из следующих этапов:

  1. Сопоставление разреженного набора точек между двумя изображениями. Существует несколько способов нахождения точечных соответствий между двумя изображениями. Этот пример определяет углы на первом изображении с помощью detectMinEigenFeatures и отслеживает их во второе изображение с помощью vision.PointTracker. Кроме того, можно использовать extractFeatures за которым следует matchFeatures.

  2. Оценка фундаментальной матрицы с помощью estimateFundamentalMatrix.

  3. Вычислите движение камеры с помощью cameraPose функция.

  4. Сопоставьте плотный набор точек между двумя изображениями. Повторное обнаружение точки с помощью detectMinEigenFeatures с уменьшенным 'MinQuality' чтобы получить больше баллов. Затем отследить плотные точки на втором изображении с помощью vision.PointTracker.

  5. Определение 3-D местоположений совпадающих точек с помощью triangulate.

  6. Обнаружение объекта известного размера. В этой сцене есть земной шар, радиус которого, как известно, составляет 10 см. Использовать pcfitsphere чтобы найти земной шар в облаке точек.

  7. Восстановите фактический масштаб, что приведет к метрической реконструкции.

Прочитайте пару изображений

Загрузите пару изображений в рабочую область.

imageDir = fullfile(toolboxdir('vision'), 'visiondata','upToScaleReconstructionImages');
images = imageDatastore(imageDir);
I1 = readimage(images, 1);
I2 = readimage(images, 2);
figure
imshowpair(I1, I2, 'montage'); 
title('Original Images');

Загрузить параметры камеры

В этом примере используются параметры камеры, рассчитанные с помощью приложения «Калибратор камеры». Параметры сохраняются в cameraParams объект, и включают характеристику камеры и коэффициенты искажения объектива. helpview (fullfile (docroot, 'toolbox', 'matlab _ prog', 'matlab _ prog.map'), 'nested _ functions')

% Load precomputed camera parameters
load upToScaleReconstructionCameraParameters.mat

Удаление искажения объектива

Искажение объектива может повлиять на точность окончательной реконструкции. Можно удалить искажение из каждого изображения с помощью undistortImage функция. Этот процесс выпрямляет линии, которые изгибаются радиальным искажением линзы.

I1 = undistortImage(I1, cameraParams);
I2 = undistortImage(I2, cameraParams);
figure 
imshowpair(I1, I2, 'montage');
title('Undistorted Images');

Поиск соответствий точек между изображениями

Определите хорошие функции для отслеживания. Уменьшить 'MinQuality' для обнаружения меньшего количества точек, которые были бы более равномерно распределены по всему изображению. Если движение камеры не очень большое, то отслеживание с помощью алгоритма KLT является хорошим способом установления точечных соответствий.

% Detect feature points
imagePoints1 = detectMinEigenFeatures(im2gray(I1), 'MinQuality', 0.1);

% Visualize detected points
figure
imshow(I1, 'InitialMagnification', 50);
title('150 Strongest Corners from the First Image');
hold on
plot(selectStrongest(imagePoints1, 150));

% Create the point tracker
tracker = vision.PointTracker('MaxBidirectionalError', 1, 'NumPyramidLevels', 5);

% Initialize the point tracker
imagePoints1 = imagePoints1.Location;
initialize(tracker, imagePoints1, I1);

% Track the points
[imagePoints2, validIdx] = step(tracker, I2);
matchedPoints1 = imagePoints1(validIdx, :);
matchedPoints2 = imagePoints2(validIdx, :);

% Visualize correspondences
figure
showMatchedFeatures(I1, I2, matchedPoints1, matchedPoints2);
title('Tracked Features');

Оценка фундаментальной матрицы

Используйте estimateFundamentalMatrix функция для вычисления фундаментальной матрицы и нахождения внутренних точек, удовлетворяющих эпиполярному ограничению.

% Estimate the fundamental matrix
[fMatrix, epipolarInliers] = estimateFundamentalMatrix(...
  matchedPoints1, matchedPoints2, 'Method', 'MSAC', 'NumTrials', 10000);

% Find epipolar inliers
inlierPoints1 = matchedPoints1(epipolarInliers, :);
inlierPoints2 = matchedPoints2(epipolarInliers, :);

% Display inlier matches
figure
showMatchedFeatures(I1, I2, inlierPoints1, inlierPoints2);
title('Epipolar Inliers');

Вычисление позы камеры

Вычислите поворот и перемещение между позициями камеры, соответствующими двум изображениям. Обратите внимание, что t является единичным вектором, поскольку преобразование может быть вычислено только до масштаба.

[R, t] = cameraPose(fMatrix, cameraParams, inlierPoints1, inlierPoints2);

Восстановление 3-D расположений согласованных точек

Повторное обнаружение точек на первом изображении с помощью нижнего 'MinQuality' чтобы получить больше баллов. Отслеживание новых точек на втором изображении. Оцените местоположения 3-D, соответствующие согласованным точкам, используя triangulate функция, реализующая алгоритм прямого линейного преобразования (DLT) [1]. Поместите начало координат в оптический центр камеры, соответствующий первому изображению.

% Detect dense feature points
imagePoints1 = detectMinEigenFeatures(im2gray(I1), 'MinQuality', 0.001);

% Create the point tracker
tracker = vision.PointTracker('MaxBidirectionalError', 1, 'NumPyramidLevels', 5);

% Initialize the point tracker
imagePoints1 = imagePoints1.Location;
initialize(tracker, imagePoints1, I1);

% Track the points
[imagePoints2, validIdx] = step(tracker, I2);
matchedPoints1 = imagePoints1(validIdx, :);
matchedPoints2 = imagePoints2(validIdx, :);

% Compute the camera matrices for each position of the camera
% The first camera is at the origin looking along the X-axis. Thus, its
% rotation matrix is identity, and its translation vector is 0.
camMatrix1 = cameraMatrix(cameraParams, eye(3), [0 0 0]);
camMatrix2 = cameraMatrix(cameraParams, R', -t*R');

% Compute the 3-D points
points3D = triangulate(matchedPoints1, matchedPoints2, camMatrix1, camMatrix2);

% Get the color of each reconstructed point
numPixels = size(I1, 1) * size(I1, 2);
allColors = reshape(I1, [numPixels, 3]);
colorIdx = sub2ind([size(I1, 1), size(I1, 2)], round(matchedPoints1(:,2)), ...
    round(matchedPoints1(:, 1)));
color = allColors(colorIdx, :);

% Create the point cloud
ptCloud = pointCloud(points3D, 'Color', color);

Отображение облака точек 3-D

Используйте plotCamera для визуализации местоположений и ориентаций камеры и pcshow для визуализации облака точек.

% Visualize the camera locations and orientations
cameraSize = 0.3;
figure
plotCamera('Size', cameraSize, 'Color', 'r', 'Label', '1', 'Opacity', 0);
hold on
grid on
plotCamera('Location', t, 'Orientation', R, 'Size', cameraSize, ...
    'Color', 'b', 'Label', '2', 'Opacity', 0);

% Visualize the point cloud
pcshow(ptCloud, 'VerticalAxis', 'y', 'VerticalAxisDir', 'down', ...
    'MarkerSize', 45);

% Rotate and zoom the plot
camorbit(0, -30);
camzoom(1.5);

% Label the axes
xlabel('x-axis');
ylabel('y-axis');
zlabel('z-axis')

title('Up to Scale Reconstruction of the Scene');

Поместите сферу в облако точек, чтобы найти глобус

Найдите глобус в облаке точек, подгоняя сферу к 3-D точкам с помощью pcfitsphere функция.

% Detect the globe
globe = pcfitsphere(ptCloud, 0.1);

% Display the surface of the globe
plot(globe);
title('Estimated Location and Size of the Globe');
hold off

Метрическая реконструкция сцены

Действительный радиус земного шара составляет 10 см. Теперь можно определить координаты точек 3-D в сантиметрах.

% Determine the scale factor
scaleFactor = 10 / globe.Radius;

% Scale the point cloud
ptCloud = pointCloud(points3D * scaleFactor, 'Color', color);
t = t * scaleFactor;

% Visualize the point cloud in centimeters
cameraSize = 2; 
figure
plotCamera('Size', cameraSize, 'Color', 'r', 'Label', '1', 'Opacity', 0);
hold on
grid on
plotCamera('Location', t, 'Orientation', R, 'Size', cameraSize, ...
    'Color', 'b', 'Label', '2', 'Opacity', 0);

% Visualize the point cloud
pcshow(ptCloud, 'VerticalAxis', 'y', 'VerticalAxisDir', 'down', ...
    'MarkerSize', 45);
camorbit(0, -30);
camzoom(1.5);

% Label the axes
xlabel('x-axis (cm)');
ylabel('y-axis (cm)');
zlabel('z-axis (cm)')
title('Metric Reconstruction of the Scene');

Резюме

В этом примере показано, как восстановить движение камеры и восстановить 3-D структуру сцены по двум изображениям, сделанным калиброванной камерой.

Ссылки

[1] Хартли, Ричард и Эндрю Зиссерман. Геометрия нескольких видов в компьютерном видении. Второе издание. Кембридж, 2000.