Корреляция между матрицей калибровки камеры OpenCV и матрицей проекции OpenGL

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

Сначала я калибрую камеру с помощью OpenGL, как в руководстве. , когда фокус оптимален для реального объекта. После получения значений cx, cy, fx и fy я создаю матрицу перспективы с этими значениями и использую функцию glMultMatrixd. Наконец, я изменяю размер фотографии, чтобы она соответствовала моему окну OpenGL, и сравниваю фотографию с отрендеренной моделью.

Но у меня есть некоторые проблемы с результатом:

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

Моя матрица отношений ниже:

GLdouble perspMatrix[16] = { fx / cx,     0   ,   0    ,    0,
    0,   fy / cy ,   0    ,    0,
    0,     0   ,  -(znear + zfar) / (znear - zfar), 2 * zfar*znear / (zfar - znear),
    0,     0   ,  -1    ,   0 };

person Bruno Medeiros    schedule 09.05.2018    source источник


Ответы (1)


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

Вы также строите симметричную усеченную пирамиду обзора (правая == левая == cx и верхняя == нижняя == cy), которая предполагает, что оптическая ось (cx, cy) находится в центре формирователя изображения камеры. Настоящие камеры никогда не бывают такими совершенными, поэтому нам приходится их калибровать. Вам нужен асимметричный усеченный конус, используя left==cx, right==(width-cx) и т. д.; это руководство должно помочь.

Обратите внимание, что в OpenGL +Y находится вверху, а +Z — за камерой (в OpenCV +Y — внизу, +Z — перед камерой), поэтому проверьте знаки на своей матрице.

person Chungzuwalla    schedule 25.05.2018