Как создать матрицу перспективной проекции, заданные координационные центры и главный центр камеры

Мне удалось получить встроенные и внешние параметры камеры с помощью OpenCV, поэтому у меня есть fx, fy, cx и cy. И у меня также есть ширина и высота экрана/изображения.

Но как мне создать проекционную матрицу OpenGL из этих параметров?

glFrustrum показывает, как создать матрицу проекции, заданную Z рядом, Z далеко и ширину и высоту изображения. Но как включить в эту матрицу координационные центры и камеры?

enter image description here

Ответы

Ответ 2

Вот код для получения матрицы проекций OpenGL, эквивалентной компьютерной видоискателе с матрицей камеры K=[fx, s, cx; 0, fy, cy; 0, 0, 1] и размером изображения [W, H]:

glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity();            // Reset The Projection Matrix
GLdouble perspMatrix[16]={2*fx/W,0,0,0,2*s/W,2*fy/H,0,0,2*(cx/W)-1,2*(cy/H)-1,(zmax+zmin)/(zmax-zmin),1,0,0,2*zmax*zmin/(zmin-zmax),0};
glMultMatrixd(perspMatrix);

NB: zmin и zmax представляют плоскость отсечения ближнего и дальнего Z. Эта формулировка предполагает, что глобальный координатный кадр OpenGL выбирается следующим образом:

enter image description here

Предполагается, что камера OpenGL расположена в начале координат, обращаясь к положительной оси Z, а нижний вектор коллинеарный и к положительной оси Y.

Ответ 3

В отношении ответа AldurDisciple это формулировка, которую вы должны использовать, если кадр мировой координации выбран с инвертированным z ax

inverted z axe

glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity();            // Reset The Projection Matrix
GLdouble perspMatrix[16]={2*fx/w,0,0,0,0,2*fy/h,0,0,2*(cx/w)-1,2*(cy/h)-1,-(far+near)/(far-near),-1,0,0,-2*far*near/(far-near),0};
glMultMatrixd(perspMatrix);

Ответ 4

Open GL работает с усечкой, которая связана с перспективной проекцией с некоторыми ограничениями по глубине, называемыми близкими и дальними значениями. Представьте себе пирамиду, лежащую на ее стороне - это усечка. Другой аналогией является луч проектора, который простирается по своей ширине и высоте с расстоянием - это тоже усечение. Таким образом, правые, левые, нижние и верхние - ваши координаты изображения, а ближние и дальние - ваши границы глубины с ближайшим фоном фокальной плоскостью. OpenGL поместит Cx и Cy в центр плоскости изображения, чтобы вы могли пропустить их. Альтернативный и более естественный способ определения усеченного конуса основан на углу обзора или поле зрения (типично 50-60 градусов); функция, которую вы вызываете, glPerspective(), где у вас все еще есть рядом и далеко, но вместо размеров укажите угол и соотношение сторон. Удачи.