Оценка положения камеры: как интерпретировать матрицы поворота и перемещения?

Предположим, у меня есть хорошее соответствие между двумя изображениями, и я попытаюсь восстановить движение камеры между ними. Я могу использовать для этого новые возможности OpenCV 3, например:

 Mat E = findEssentialMat(imgpts1, imgpts2, focal, principalPoint, RANSAC, 0.999, 1, mask);

 int inliers = recoverPose(E, imgpts1, imgpts2, R, t, focal, principalPoint, mask);

 Mat mtxR, mtxQ;
 Mat Qx, Qy, Qz;
 Vec3d angles = RQDecomp3x3(R, mtxR, mtxQ, Qx, Qy, Qz);

 cout << "Translation: " << t.t() << endl;
 cout << "Euler angles [x y z] in degrees: " << angles.t() << endl;

Теперь мне трудно понять, что на самом деле означают R и t. Являются ли они преобразованием, необходимым для отображения координат из пространства камеры 1 в пространство камеры два, как в p_2 = R * p_1 + t?

Рассмотрим этот пример с достоверными соответствиями, помеченными вручную.

введите описание изображения здесь

Результат, который я получаю, таков:

Translation: [-0.9661243151855488, -0.04921320381132761, 0.253341406362796]
Euler angles [x y z] in degrees: [9.780449804801876, 46.49315494782735, 15.66510133665445]

Я пытаюсь сопоставить это с тем, что я вижу на изображении, и придумываю интерпретацию, которая [-0.96,-0.04,0.25] говорит мне, что я переместился вправо, поскольку координаты переместились вдоль отрицательной оси x, но это также скажет мне, Я отошел еще дальше, так как координаты сместились по положительной оси z.

Я также повернул камеру вокруг оси Y (влево, что, я думаю, было бы вращением против часовой стрелки вокруг отрицательной оси Y, потому что в OpenCV ось Y указывает вниз, не так ли?)

Вопрос: Я правильно понимаю, и если нет, то какое?


person oarfish    schedule 16.07.2015    source источник


Ответы (4)


На самом деле ваша интерпретация верна.

Во-первых, вы правы относительно ориентации оси y. Для иллюстрации системы координат камеры OpenCV см. здесь .

Ваш код вернет R и t со второй камеры на первую. Это означает, что если x1 - это точка на первом изображении, а x2 - это точка на втором изображении, следующее уравнение выполняется x1 = R*x2 + t. Теперь в вашем случае правое изображение (вид спереди) с камеры 1 и левое изображение (вид сбоку) автомобиля с камеры 2.

Глядя на это уравнение, мы видим, что в первую очередь применяется вращение. Таким образом, ваша камера в настоящее время изображает левый кадр. Теперь ваш R определяет поворот примерно на 46 градусов вокруг оси y. Поскольку поворот точки на угол альфа совпадает с поворотом оси координат на этот угол в противоположную сторону, ваш R говорит вам повернуть влево. Как вы сами заметили, это кажется правильным, если смотреть на картинки. Поскольку вращения вокруг других осей небольшие и их трудно отобразить, давайте их здесь опустим. Таким образом, после применения поворота вы все еще стоите в том же положении, из которого был взят левый кадр, но ваша камера более или менее указывает на заднюю часть автомобиля или пространство непосредственно за автомобилем.

Теперь посмотрим на вектор трансляции. Ваша интерпретация движения вправо и дальше тоже верна. Позвольте мне попытаться объяснить почему. Представьте себе из вашего текущего положения, с новым направлением камеры вы двигаетесь только вправо. вы можете прямо столкнуться с автомобилем или будете держать камеру над капотом двигателя. Таким образом, после перемещения вправо вам также необходимо отодвинуться еще дальше, чтобы добраться до позиции, из которой вы сделали правильный снимок.

Я надеюсь, что это объяснение помогло вам представить движение, описываемое вашими буквами R и t.

person Ann    schedule 17.07.2015

Оказывается, моя интерпретация верна, соотношение p2 = R * p1 + t действительно выполняется. В этом можно убедиться, используя cv::triangulatePoints() и cv::convertPointsFromHomogeneous для получения трехмерных координат из соответствующих точек (относительно камеры 1), а затем применив указанное выше уравнение. Затем умножение на матрицу камеры 2 дает p2 координаты изображения.

person oarfish    schedule 08.08.2015

Ваша интерпретация кажется мне правильной. Я не на 100% говорю об ориентации оси в OpenCV, но я считаю, что вы правы относительно оси Y.

Вывод также имеет смысл, не только с точки зрения кода, но если вы посмотрите на два изображения, вы можете примерно представить, куда будет указывать полный поворот на 90 градусов (по сути, это будет тот же угол, но на противоположной стороне автомобиля. )

Это довольно приличное объяснение концепции с помощью механики движения твердого тела: http://nghiaho.com/?page_id=671

person Mike K    schedule 16.07.2015

Посмотрим. Координатная рамка камеры OpenCV: «X по направлению к изображению вправо, Y по направлению к низу изображения, Z = X x Y по направлению к сцене». Q = [R | t] - это преобразование координат от камеры 2 к камере 1, так что t - вектор с корнем в камере 1 с вершиной в камере 2, выраженный в кадре камеры 1. Таким образом, ваш вектор трансляции подразумевает, что камера 2 находится слева от камеры 1, что с учетом ваших изображений возможно только в том случае, если вид сбоку автомобиля находится в камере 2, а вид спереди автомобиля находится в камере 1. Это согласуется с положительным Z-компонентом. перевода, так как при виде сбоку машина кажется дальше от камеры.

Эта идентификация также согласуется с вычисленными вами углами Эйлера: они возвращаются в соответствии с соглашением OpenGL, таким образом выражая поворот от источника к месту назначения. В вашем случае поворот на 46 градусов вокруг вертикальной оси камеры 1 против часовой стрелки относительно вертикальной оси камеры. направленная вниз ось Y приближает вас к тому виду сбоку, который у вас есть.

person Francesco Callari    schedule 16.07.2015
comment
Но положительный z-компонент сказал бы мне, что камера 2 переместилась к машине, но это не соответствует интерпретации, что камера 2 - это левое изображение. Что мне не хватает? - person oarfish; 17.07.2015
comment
Перечитайте то, что я написал: это вектор с корнем в camera1, с вершиной в camera2. Положительный Z-компонент t означает только, что центр камеры 2 находится перед плоскостью XY камеры 1, то есть перед центром камеры 1. Это вполне правдоподобно, учитывая ваши изображения: просто представьте, что вы увеличиваете плоскость изображения в обзоре, глядя на переднюю часть автомобиля, а затем решите, с какой стороны от этой плоскости должна быть камера бокового обзора. Кроме того, проголосуйте за / примите ответ, если вы сочтете его полезным. - person Francesco Callari; 17.07.2015
comment
Если я это сделаю, мне кажется, что центр камеры 2 находится позади камеры 1, поэтому z должно быть отрицательным. Но это не очень понятно из-за ротации. - person oarfish; 17.07.2015