Оценка позы: solvePnP и эпиполярная геометрия не согласуются

У меня есть проблема с оценкой относительной позы камеры, когда я смотрю на сцену с разноориентированными камерами, расположенными на определенном расстоянии друг от друга. Сначала я вычисляю основную матрицу, используя 5-точечный алгоритм, и разлагаю ее, чтобы получить R и t для камеры 2 по сравнению с камерой 1.

Я подумал, что было бы неплохо сделать проверку, триангулировав два набора точек изображения в 3D, а затем запустив solvePnP на 3D-2D соответствиях, но результат, который я получаю от solvePnP, далек. Я пытаюсь сделать это, чтобы "уточнить" свою позу, поскольку масштаб может меняться от одного кадра к другому. Во всяком случае, в одном случае у меня был поворот на 45 градусов между камерой 1 и камерой 2 вдоль оси Z, и часть эпиполярной геометрии дала мне такой ответ:

Relative camera rotation is [1.46774, 4.28483, 40.4676]
Translation vector is [-0.778165583410928;  -0.6242059242696293;  -0.06946429947410336]

solvePnP, с другой стороны..

Camera1: rvecs [0.3830144497209735;   -0.5153903947692436;  -0.001401186630803216]
         tvecs [-1777.451836911453;  -1097.111339375749;  3807.545406775675]
Euler1 [24.0615, -28.7139, -6.32776]

Camera2: rvecs [1407374883553280; 1337006420426752; 774194163884064.1] (!!)
         tvecs[1.249151852575814;  -4.060149502748567;  -0.06899980661249146]
Euler2 [-122.805, -69.3934, 45.7056]

Что-то тревожно отключено с помощью rvecs camera2 и tvec camera 1. Мой код, включающий триангуляцию точек и solvePnP, выглядит следующим образом:

points1.convertTo(points1, CV_32F);
points2.convertTo(points2, CV_32F);

 // Homogenize image points

points1.col(0) = (points1.col(0) - pp.x) / focal;
points2.col(0) = (points2.col(0) - pp.x) / focal;
points1.col(1) = (points1.col(1) - pp.y) / focal;
points2.col(1) = (points2.col(1) - pp.y) / focal;

points1 = points1.t();      points2 = points2.t();

cv::triangulatePoints(P1, P2, points1, points2, points3DH);

cv::Mat points3D;
convertPointsFromHomogeneous(Mat(points3DH.t()).reshape(4, 1), points3D);

cv::solvePnP(points3D, points1.t(), K, noArray(), rvec1, tvec1, 1, CV_ITERATIVE );
cv::solvePnP(points3D, points2.t(), K, noArray(), rvec2, tvec2, 1, CV_ITERATIVE );

И затем я конвертирую rvecs через Rodrigues, чтобы получить углы Эйлера: но так как сами rvecs и tvecs кажутся неправильными, я чувствую, что что-то не так с моим процессом. Любые указатели будут полезны. Спасибо!

0 ответов

Другие вопросы по тегам