Вычисление движения камеры из соответствующих наборов трехмерных точек - PullRequest
3 голосов
/ 25 февраля 2012

У меня небольшая проблема. Я написал программу, которая извлекает набор трехмерных точек в каждом кадре, используя камеру и информацию о глубине. Точки находятся в системе координат камеры , что означает, что начало координат находится в центре камеры, x - горизонтальное расстояние, y вертикальное расстояние и z - расстояние от камеры (вдоль оптической оси). Все в метрах. То есть точка (2, -1,5) будет на два метра вправо, на один метр ниже и на пять метров вдоль оптической оси камеры.

Я вычисляю эти точки в каждом временном интервале, а также знаю соответствия, как будто я знаю, какая точка в t-1 принадлежит какой 3d-точке в t.

Моя цель теперь состоит в том, чтобы вычислить движение камеры в каждом временном интервале в моей мировой системе координат (с z, указывающим вверх, представляющим высоту). Я хотел бы рассчитать относительное движение, но также и абсолютное, начиная с некоторой начальной позиции, чтобы визуализировать траекторию движения камеры.


Это пример набора данных из одного кадра с текущим (слева) и предыдущим 3D-расположением (справа) точек в координатах камеры:

-0.174004 0.242901 3.672510 | -0.089167 0.246231 3.646694 
-0.265066 -0.079420 3.668801 | -0.182261 -0.075341 3.634996 
0.092708 0.459499 3.673029 | 0.179553 0.459284 3.636645 
0.593070 0.056592 3.542869 | 0.675082 0.051625 3.509424 
0.676054 0.517077 3.585216 | 0.763378 0.511976 3.555986 
0.555625 -0.350790 3.496224 | 0.633524 -0.354710 3.465260 
1.189281 0.953641 3.556284 | 1.274754 0.938846 3.504309 
0.489797 -0.933973 3.435228 | 0.561585 -0.935864 3.404614 

Поскольку я хотел бы по возможности поработать с OpenCV, я нашел функцию estimateAffine3D() в OpenCV 2.3, которая принимает два точечных вектора ввода и вычисляет аффинное преобразование между ними с помощью RANSAC.

В качестве вывода я получаю матрицу преобразования 3x4.

Я уже пытался сделать расчет более точным, задав параметры RANSAC, но часто матрица тринаформации показывает поступательное движение, которое довольно велико. Как видно из примера данных, движение обычно довольно мало.

Так что я хотел спросить, есть ли у кого-нибудь еще идеи о том, что я могу попробовать? Предлагает ли OpenCV другие решения для этого?

Также, если бы у меня было относительное движение камеры на каждом таймфрейме, как бы я преобразовал ее в мировые координаты? Кроме того, как мне получить абсолютную позицию, начиная с точки (0,0,0), чтобы у меня было положение камеры (и направление) для каждого таймфрейма?

Было бы здорово, если бы кто-нибудь мог дать мне совет!

Спасибо!

ОБНОВЛЕНИЕ 1:

После приятного ответа @Michael Kupchick я попытался проверить, насколько хорошо работает функцияScoreAffine3D () в OpenCV. Поэтому я создал два небольших набора тестов из 6 пар точек, которые имеют только перевод, а не вращение, и взглянули на полученную матрицу преобразования:

Испытательный комплект 1:

1.5 2.1 6.7 | 0.5 1.1 5.7
6.7 4.5 12.4 | 5.7 3.5 11.4
3.5 3.2 1.2 | 2.5 2.2 0.2
-10.2 5.5 5.5 | -11.2 4.5 4.5
-7.2 -2.2 6.5 | -8.2 -3.2 5.5
-2.2 -7.3 19.2 | -3.2 -8.3 18.2

Матрица преобразования:

1           -1.0573e-16  -6.4096e-17  1
-1.3633e-16 1            2.59504e-16  1
3.20342e-09 1.14395e-09  1            1

Тестовый набор 2:

1.5 2.1 0 | 0.5 1.1 0
6.7 4.5 0 | 5.7 3.5 0
3.5 3.2 0 | 2.5 2.2 0
-10.2 5.5 0 | -11.2 4.5 0
-7.2 -2.2 0 | -8.2 -3.2 0
-2.2 -7.3 0 | -3.2 -8.3 0

Матрица преобразования:

1             4.4442e-17  0   1
-2.69695e-17  1           0   1
0             0           0   0

-> Это дает мне две матрицы преобразования, которые выглядят прямо с первого взгляда ...

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

Кто-нибудь какие-нибудь советы или идеи, почему это так плохо?

1 Ответ

3 голосов
/ 29 февраля 2012

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

То, что вы пытаетесь сделать, это зарегистрировать знающее 3d, и, поскольку для всех кадров есть одинаковые 3d точки -> соотношение камеры, вычисленные преобразованияот регистрации будет преобразование движения камеры.

Для решения этой проблемы вы можете использовать PCL.Это родственный проект opencv для задач, связанных с 3D.http://www.pointclouds.org/documentation/tutorials/template_alignment.php#template-alignment Это хороший учебник по выравниванию облаков точек.

В основном это выглядит так:

Для каждой пары последовательных кадров известны 3d-точечные соответствия, поэтому вы можете использовать метод SVD, реализованный в

http://docs.pointclouds.org/trunk/classpcl_1_1registration_1_1_transformation_estimation_s_v_d.html

У вас должно быть как минимум 3 соответствующих пункта.

Вы можете следовать руководству или реализовать свой собственный алгоритм ransac.Это даст вам лишь приблизительную оценку трансформации (может быть достаточно хорошей, если шум не слишком велик), чтобы получить точную трансфомацию, вы должны применить алгоритм ICP с использованием преобразования догадки, рассчитанного на предыдущем шаге.ICP описывается здесь:

http://www.pointclouds.org/documentation/tutorials/iterative_closest_point.php#iterative-closest-point

Эти два шага должны дать вам точную оценку преобразования между кадрами.

Таким образом, вы должны делать попарную регистрацию постепенно - регистрацияПервая пара кадров получает преобразование из первого кадра во второй 1-> 2.Зарегистрируйте второе с помощью третьего (2-> 3), а затем добавьте преобразование 1-> 2 к 2-> 3 и так далее.Таким образом, вы получите преобразования в глобальной системе координат, где первый кадр - начало координат.

...