Поле зрения + соотношение сторон + матрица просмотра из матрицы проецирования (калибровка HMD OST)

В настоящее время я работаю над приложением дополненной реальности. Нацеленное устройство представляет собой шлем с оптическим зрением. Мне нужно откалибровать его дисплей, чтобы добиться правильной регистрации виртуальных объектов. Я использовал эту реализацию SPAAM для Android, чтобы сделать это, и результат достаточно точен для моей цели.

Моя проблема в том, что приложение калибровки выдает на выходе матрицу 4x4 проекции, которую я мог бы напрямую использовать, например, с OpenGL. Но структура дополненной реальности, которую я использую, принимает только параметры оптической калибровки в формате Поле обзора некоторый параметр + Соотношение сторон некоторый параметр + 4x4 Вид < / s> матрица.

Вот что у меня есть:

Правильный результат калибровки в неправильном формате:

 6.191399, 0.114267, -0.142429, -0.142144
-0.100027, 11.791289, 0.05604,   0.055928
 0.217304,-0.486923, -0.990243, -0.988265
 0.728104, 0.005347, -0.197072,  0.003122

Вы можете взглянуть на код, который генерирует этот результат здесь.

Я понимаю, что метод одноточечного активного выравнивания создает матрицу 3x4, а затем программа умножает эту матрицу на матрицу ортогональной проекции, чтобы получить результат выше. Вот параметры, используемые для создания ортогональной матрицы:

near : 0.1, far : 100.0, right : 960, left : 0, top :  540, bottom:  0

Плохой результат калибровки в правильном формате:

Param 1 : 12.465418
Param 2 : 1.535465

 0.995903,   -0.046072,   0.077501,  0.000000   
 0.050040,    0.994671,  -0.047959,  0.000000
-0.075318,    0.051640,   0.992901,  0.000000
 114.639359, -14.115030, -24.993097, 1.000000

У меня нет информации о том, как получаются эти результаты.

Я читаю эти параметры из двоичных файлов и не знаю, хранятся ли матрицы в виде строк или столбцов. Таким образом, возможно, придется переставить две матрицы.

Мой вопрос: Возможно ли, и если да, то как получить эти три параметра из первой имеющейся у меня матрицы projection?


person Raoul    schedule 12.09.2017    source источник
comment
матрица проекции и матрица представления - это разные вещи - см. Преобразование modelMatrix. Вероятно fov = 2.0*atan(1.0/prjM[1][1])*180.0/PI; aspect = prjM[1][1]/prj[0][0] - см. Как восстановить положение пространства обзора с учетом значения глубины пространства обзора и ndc xy   -  person Rabbid76    schedule 12.09.2017
comment
Эту информацию можно получить из матрицы проекции, но вам нужно знать, какие формулы использовались для ее построения.   -  person Mr. Reddy    schedule 13.09.2017
comment
Дерп, я не умею читать. Я не заметил, что матрица просмотра тоже была там. Максимум, что вы можете извлечь из матрицы проекции, - это угол обзора и соотношение сторон.   -  person Mr. Reddy    schedule 13.09.2017
comment
Откуда вы знаете, что результат калибровки правильный?   -  person Soccertrash    schedule 15.05.2018
comment
Поскольку после загрузки в соответствующую структуру первый результат дает хорошую регистрацию виртуальных объектов, тогда как второй дает плохую регистрацию.   -  person Raoul    schedule 22.05.2018


Ответы (1)


Возможно ли, и если да, то как получить эти три параметра из имеющейся у меня матрицы проекции?

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

Это означает, что невозможно получить матрицу вида из матрицы проекции. Но камера определяет матрицу обзора.


Если проекция является перспективной, то можно будет получить угол поля зрения и соотношение сторон из матрицы проекции.

введите описание изображения здесь

Матрица перспективной проекции выглядит так:

r = right, l = left, b = bottom, t = top, n = near, f = far

2*n/(r-l)      0              0               0
0              2*n/(t-b)      0               0
(r+l)/(r-l)    (t+b)/(t-b)    -(f+n)/(f-n)   -1    
0              0              -2*f*n/(f-n)    0

следует:

aspect = w / h
tanFov = tan( fov_y * 0.5 );

p[0][0] = 2*n/(r-l) = 1.0 / (tanFov * aspect)
p[1][1] = 2*n/(t-b) = 1.0 / tanFov

Угол поля зрения по оси Y в градусах:

fov = 2.0*atan( 1.0/prjMatrix[1][1] ) * 180.0 / PI;

Соотношение сторон:

aspect = prjMatrix[1][1] / prjMatrix[0][0];

См. далее ответы на следующий вопрос:
Как линейно визуализировать глубину в современном OpenGL с gl_FragCoord.z ​​во фрагментном шейдере?
Как восстановить положение в пространстве просмотра с учетом глубины пространства просмотра значение и ndc xy

person Rabbid76    schedule 13.09.2017