Извлечение перевода и поворота из фундаментальной матрицы - программирование
Подтвердить что ты не робот

Извлечение перевода и поворота из фундаментальной матрицы

Я пытаюсь извлечь векторы перевода и вращения из вычисленной базовой матрицы. Я использую OpenCV, а общий подход - из википедии. Мой код выглядит следующим образом:

//Compute Essential Matrix
Mat A = cameraMatrix(); //Computed using chessboard
Mat F = fundamentalMatrix(); //Computed using matching keypoints
Mat E = A.t() * F * A;

//Perfrom SVD on E
SVD decomp = SVD(E);

//U
Mat U = decomp.u;

//S
Mat S(3, 3, CV_64F, Scalar(0));
S.at<double>(0, 0) = decomp.w.at<double>(0, 0);
S.at<double>(1, 1) = decomp.w.at<double>(0, 1);
S.at<double>(2, 2) = decomp.w.at<double>(0, 2);

//V
Mat V = decomp.vt; //Needs to be decomp.vt.t(); (transpose once more)

//W
Mat W(3, 3, CV_64F, Scalar(0));
W.at<double>(0, 1) = -1;
W.at<double>(1, 0) = 1;
W.at<double>(2, 2) = 1;

cout << "computed rotation: " << endl;
cout << U * W.t() * V.t() << endl;
cout << "real rotation:" << endl;
Mat rot;
Rodrigues(images[1].rvec - images[0].rvec, rot); //Difference between known rotations
cout << rot << endl;

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

computed rotation:
[0.8543027125286542, -0.382437675069228, 0.352006107978011;
  0.3969758209413922, 0.9172325022900715, 0.03308676972148356;
  0.3355250705298953, -0.1114717965690797, -0.9354127247453767]

real rotation:
[0.9998572365450219, 0.01122579241510944, 0.01262886032882241;
  -0.0114034800333517, 0.9998357441946927, 0.01408706050863871;
  -0.01246864754818991, -0.01422906234781374, 0.9998210172891051]

Так ясно, что есть проблема, я просто не могу понять, что это может быть.

EDIT: Вот результаты, которые я получил с непереведенным vt (очевидно, из другой сцены):

computed rotation: 
[0.8720599858028177, -0.1867080200550876, 0.4523842353671251;
 0.141182538980452, 0.9810442195058469, 0.1327393312518831;
-0.4685924368239661, -0.05188790438313154, 0.8818893204535954]
real rotation
[0.8670861432556456, -0.427294988334106, 0.2560871201732064;
 0.4024551137989086, 0.9038194629873437, 0.1453969040329854;
-0.2935838918455123, -0.02300806966752995, 0.9556563855167906]

Вот моя вычислительная матрица камеры, ошибка была довольно низкой (около 0,17...).

[1699.001342509651, 0, 834.2587265398068;
  0, 1696.645251354618, 607.1292618175946;
  0, 0, 1]

Вот результаты, которые я получаю при попытке перепрограммировать куб... Камера 0, куб выровнен по оси, вращение и перевод (0, 0, 0). image http://imageshack.us/a/img802/5292/bildschirmfoto20130110u.png

а другой - с эпилинами точек первого изображения. изображение http://imageshack.us/a/img546/189/bildschirmfoto20130110uy.png

4b9b3361

Ответ 1

Пожалуйста, взгляните на эту ссылку:

http://isit.u-clermont1.fr/~ab/Classes/DIKU-3DCV2/Handouts/Lecture16.pdf.

См. стр. 2. Существует две возможности для R. Первый - это UWVT, а второй - UWTVT. Вы использовали второй. Попробуйте первый.

Ответ 2

8-точечный алгоритм - это самый простой способ вычисления фундаментальной матрицы, но если принять меры, вы можете выполнить его хорошо. Ключом для получения хороших результатов является правильная тщательная нормализация входных данных до построения решаемых уравнений. Многие алгоритмы могут это сделать. Координаты точек пикселей должны быть изменены на координаты камеры, вы делаете это в этой строке:

Mat E = A.t() * F * A;

Однако это предположение неверно. Если известна матрица калибровки камеры K, то вы можете применить инверсию к точке x для получения точки, выраженной в нормализованных координатах.

X_{norm}= K.inv()*X_{pix} где X_{pix}(2), z равно 1.

В случае 8PA простое преобразование точек улучшается и, следовательно, в стабильности результатов. Предложенная нормализация - это перевод и масштабирование каждого изображения, так что центроид опорных точек находится в начале координат, а среднеквадратичное расстояние точек от начала координат равно \sqrt{2}. Обратите внимание, что перед денормализацией рекомендуется выполнить условие сингулярности.

Ссылка: проверьте, если: вы по-прежнему заинтересованы