Восстановление позы из существенной матрицы дает противоречивый признак вектора перевода

У меня есть три вида с точечными соответствиями, и я хочу вычислить положение камеры на втором и третьем видах. Поэтому я генерирую случайный набор данных (без шума), содержащий точки на разных видах с известным поворотом и перемещением камеры на втором и третьем видах по отношению к первому виду. Сначала я генерирую случайные 2D-точки на первом виде, затем назначаю случайные (положительные) глубины для получения соответствующих 3D-точек и, наконец, использую случайно сгенерированные повороты и сдвиги для проецирования этих 3D-точек на второй и третий виды.

Сначала я вычисляю трифокальный тензор (см. Хартли & Циссерман, Геометрия с множественным обзором, глава 15). Затем я следую подходу, который описан в этом ответ получить вращения R_i и переводы t_i второго и третьего вида.

Расчет всегда дает правильное вращение, но, к сожалению, знак векторов трансляции не всегда корректен. t2а также t3 иметь правильную шкалу, но бывает иногда (!), когда я использую новый случайно сгенерированный набор данных, что знак перевернут по отношению к основному переводу истины, например.:

Основная правда:

R2 = [0.9942   -0.0998    0.0393
0.1069    0.9541   -0.2798
-0.0096    0.2823    0.9593]
t2 = [0.4267
0.3747
0.3544]
R3 = [0.9764   -0.0626    0.2069
0.1358    0.9222   -0.3622
-0.1681    0.3817    0.9089]
t3 = [0.3963
0.0285
0.2093]

Вывод моего алгоритма (с переводом, определенным в масштабе):

R2 = [0.994229 -0.0998196  0.0393062
0.106851   0.954105  -0.279761
-0.00957664   0.282346   0.959265]
t2 = [-0.637428
-0.559842
-0.529398]
R3 = [0.976367 -0.0625748   0.206861
0.135829    0.92217  -0.362151
-0.168099    0.38169   0.908876]
t3 = [-0.591991
-0.0426261
-0.312637]

Сравнивая правду земли и мой вывод t2 а также t3мы видим, что они идентичны в масштабе (и в этом примере инвертированы знаком), то есть поэтапное деление векторов трансляции t2./t3 (используя обозначение Matlab) из наземной истины и мой алгоритм дают:

for ground truth:
[ 1.0768
13.1338
1.6933]

for my algorithm:
[ 1.0768
13.1338
1.6933]

Мой первый вопрос:
Что может быть причиной этого несоответствия знака векторов перевода?
(Особенно учитывая тот факт, что результаты верны в противном случае).

Мой второй вопрос:
Откуда взялись эти формулы, приведенные в связанном выше ответе, Шаг 4? У меня есть книга «Геометрия с несколькими видами» Хартли & Зиссерман, но не смог найти там описанный алгоритм.

Вот фрагмент кода моей реализации шага 4 алгоритма в приведенной выше ссылке (используя библиотеку Eigen, я не хочу использовать OpenCV) для нахождения правильного решения вращения R и вектор перевода t из существенной матрицы Eс учетом однородного 2D точечного соответствия с 3 видами p1, p2, а также p3:

getPoseFromEssentialMat(Matrix3d E)
{
Matrix3d W, U, V;
W << 0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0;

// calculate the SVD of the essential matrix
JacobiSVD<MatrixXd> svdE(E, ComputeThinU | ComputeThinV);
// if det(U) < 0 -> U = -U, if det(V) < 0 -> V = -V
U = svdE.matrixU();
if (U.determinant() < 0.0)
{
U *= -1.0;
}
V = svdE.matrixV();
if (V.determinant() < 0.0)
{
V *= -1.0;
}

R = U * W * V.transpose();
t = U.col(2);

findCorrectSolution(R, t, W, U, V);
}findCorrectSolution(Matrix3d& R, Vector3d& t, Matrix3d W, Matrix3d U, Matrix3d V)
{
MatrixXd P(3, 4); // P = [R | t]
P.block(0, 0, 3, 3) = R;
P.col(3) = t;

Vector3d Rtpt = R.transpose() * t;
Matrix3d M = crossProductMatrix(Rtpt);
Vector3d X_1 = M * K_inv_ * p1; // point in 1. view

Vector3d X_i = M * R.transpose() * K_inv_ * pi; // point in i. view

if (X_1(2) * X_i(2) < 0.0) // depth components
{
R = U * W.transpose() * V.transpose();
Rtpt = R.transpose() * t;
M = crossProductMatrix(Rtpt);
X_1 = M * K_inv_ * p1;
}
if (X_1(2) < 0.0) // depth of 1. 3D point
{
t = -t;
}

1

Решение

Задача ещё не решена.

Другие решения


По вопросам рекламы [email protected]