Рассчитать внешность камеры от положения и поворота - PullRequest
0 голосов
/ 16 апреля 2020

Цель

В настоящее время я работаю над программным обеспечением, которое использует распознавание объектов для обнаружения объектов, проходящих мимо камеры. Обнаружение объекта обеспечивает ограничивающую рамку вокруг обнаруженного объекта в координатах изображения (x, y), но мне нужно преобразовать их в трехмерные координаты на плоскости xy (z = 0).

Подход

Глядя на другие вопросы о переполнении стека и других форумах, я смог получить общее представление о том, как это должно быть реализовано. Поэтому я сначала посмотрел, применив калибровку камеры OpenCV , чтобы получить матрицу камеры intrinsi c вместе с коэффициентами искажения.

Затем я нашел две разные реализации для получения трехмерных координат, учитывая, что я знать матрицу extrinsi c камер ( метод 1 / метод 2 ). Я предпочитаю первый вариант, используя обратную матрицу гомографии, поскольку процесс намного понятнее:

projection_matrix[3,4] = camera_matrix[3,3] * extrinsic_matrix[3,4];

Матрица гомогерапии создается путем удаления третьего столбца в матрице проекции. Из того, что я понимаю, это потому, что Z всегда равен 0, и поэтому столбец для расчета позиции z не нужен. Хотя не стесняйтесь меня поправить, поскольку я не уверен на 100%, что было причиной.

homography_matrix[3,3] = projection_matrix[c1, c2, c4];

Затем создайте матрицу обратной гомографии для сопоставления пространства камеры с физическим пространством.

inv_homography_matrix = homography_matrix.inv();

Затем мы можем преобразовать координаты изображения в физические, используя следующий код]

point2D = {x, y , 1};
point3Dw = inv_homography_matrix * point2D;
cv::divide(point3Dw[2][0], point3Dw, point3D); //normalize

Задача

Другие примеры ( 1 , 2 , 3 ), который я рассмотрел, использует SolvePnP для вычисления матрицы extrinsi c.

cv::solvePnP(world_points, image_points, camera_matrix, dist_coeffs, rotation_vector, translation_vector);
cv::Rodrigues(rotation_vector, rotation_matrix);
cv::hconcat(rotation_matrix, translation_vector, extrinsic_matrix);

Теперь моя реализация не может использовать SolvePnP для вычисления extrinsi c матрица, так как положение и поворот камеры могут быть изменены и установлены пользователем. Поэтому мне не хватает точек мира для отображения точек изображения, требуемых SolvePnP. Таким образом, чтобы вычислить матрицу extrinsi c, мне нужно было найти альтернативу.

Альтернатива

Учитывая, что я знаю положение и вращение камер, я обнаружил блог , который объяснил как построить матрицу extrinsi c из позы камеры. Суть в том, что обратная матрица позы камеры дает матрицу extrinsi c.

[r,r,r,tx]
[r,r,r,ty]
[r,r,r,tz]
[0,0,0,1]

Затем я удаляю нижний ряд, чтобы матрица могла быть умножена на матрицу камеры.

Проблемы

При тестировании кода с определенными параметрами я получаю не те результаты, которые ожидаю. Пример результатов, которые я получаю, выглядит следующим образом:

(10, 10)   = {1.47186, 5.77999}
(990, 10) = {0.0111787, 5.77999}
(640, 360) = {0.730328, 243.779}
(10, 490) = {84.5887, 332.179}
(990, 490) = {0.642446, 332.179}

Основываясь на моих измерениях, с изображениями и линейкой, я ожидаю, что значения x будут примерно между -1,1 до 1,1 и y должен составлять от -0,45 до 0,45. Это, конечно, с камерой, помещенной на 0,77 м (z) над началом координат и повернутой на -90 градусов вокруг оси x, чтобы повернуть ее вниз.

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

Дополнительные детали

Я использую следующую матрицу позы камеры:

[1, 0, 0, 0   ]
[0, 0, 1, 0   ]
[0,-1, 0, 0.77]
[0, 0, 0, 1   ]

Матрица камеры:

[1.9098593171027440 0. 2.5  ]
[0. 1.9098593171027440 1.5  ]
[0. 0. 1]

Рассматриваемая камера - See3CAM_CU55 с объективом fi sh.

...