如何反转相机矩阵中一个轴的旋转(例如 OSG CameraViewMatrix)
How to invert the Rotation of one Axis in a Camera Matrix (e.g. OSG CameraViewMatrix)
对于增强现实应用程序,我正在使用一些 slam 算法来预测我手机的当前方向 phone。
算法(LSD-Slam) supplies the current pose in form of a SE3 lie group (using Sophus::Sim3f)。
如果我做对了,这个类型包含一个矩阵,可以解释为相机的 Viewmatrix。初始化后,例如矩阵如下所示:
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
为了可视化 3D 内容,我使用了 OpenSceneGraph。幸运的是,在 OSG 中,您可以直接使用视图矩阵设置相机位置:
camera->setViewMatrix(matrix);
现在,当我 运行 绕 Y(滚动)或 Z(偏航)旋转时,代码似乎工作正常。但是当我围绕 X(俯仰)旋转时,我在 OSG 中的数码相机似乎与它应该做的完全相反。
例如:想象一个 3D 模型正对着相机。如果我然后慢慢向上倾斜相机(大约 X),3D 模型也会向上移动,而它实际上应该在底部离开屏幕。我试图用下图来说明这种行为:
可能有一个非常简单的解决方案,但即使经过数小时的尝试我也无法修复。如果我理解正确,第一列代表围绕某个轴的旋转,所以我尝试反转单个向量,例如这样做了:
u u u 0 -u u u 0 -u -u -u 0
v v v 0 => -v v v 0 ... v v v 0
n n n 0 -n n n 0 n n n 0
0 0 0 1 0 0 0 1 0 0 0 1
虽然有些尝试确实解决了 Pitch-Issue,但他们随后弄乱了另一个轴。至少似乎总是有一个轴是错误的。 有人知道我该如何解决这个问题吗?我非常感谢关于这个问题的任何提示。
如果你从库中得到的姿势对应于 OpenGL 视图矩阵,你应该能够像你提到的那样将它直接传递给 osg 相机。
但是,请记住 OSG 采用 row-major 矩阵约定(参见示例 this post)因此您可能需要切换 row/columns 在你的矩阵中。
如果这不起作用,我建议您确定 Sophus 使用的姿势约定(哪个旋转相对于世界坐标中的哪个静止位置)并重新创建同样的转换是osg从零开始。
再次检查Sophus后,我发现我可以分别得到旋转矩阵和平移向量。使用 this post 我将旋转矩阵转换为欧拉角。使用欧拉角,我可以分别设置每个轴的旋转:
rotationMatrix.makeRotate(
osg::DegreesToRadians(-angleZ), osg::Vec3(0,1,0), // roll
osg::DegreesToRadians(angleX), osg::Vec3(1,0,0) , // pitch
osg::DegreesToRadians(angleY), osg::Vec3(0,0,1) ); // heading
倒转终于成功了...
对于增强现实应用程序,我正在使用一些 slam 算法来预测我手机的当前方向 phone。
算法(LSD-Slam) supplies the current pose in form of a SE3 lie group (using Sophus::Sim3f)。 如果我做对了,这个类型包含一个矩阵,可以解释为相机的 Viewmatrix。初始化后,例如矩阵如下所示:
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
为了可视化 3D 内容,我使用了 OpenSceneGraph。幸运的是,在 OSG 中,您可以直接使用视图矩阵设置相机位置:
camera->setViewMatrix(matrix);
现在,当我 运行 绕 Y(滚动)或 Z(偏航)旋转时,代码似乎工作正常。但是当我围绕 X(俯仰)旋转时,我在 OSG 中的数码相机似乎与它应该做的完全相反。
例如:想象一个 3D 模型正对着相机。如果我然后慢慢向上倾斜相机(大约 X),3D 模型也会向上移动,而它实际上应该在底部离开屏幕。我试图用下图来说明这种行为:
可能有一个非常简单的解决方案,但即使经过数小时的尝试我也无法修复。如果我理解正确,第一列代表围绕某个轴的旋转,所以我尝试反转单个向量,例如这样做了:
u u u 0 -u u u 0 -u -u -u 0
v v v 0 => -v v v 0 ... v v v 0
n n n 0 -n n n 0 n n n 0
0 0 0 1 0 0 0 1 0 0 0 1
虽然有些尝试确实解决了 Pitch-Issue,但他们随后弄乱了另一个轴。至少似乎总是有一个轴是错误的。 有人知道我该如何解决这个问题吗?我非常感谢关于这个问题的任何提示。
如果你从库中得到的姿势对应于 OpenGL 视图矩阵,你应该能够像你提到的那样将它直接传递给 osg 相机。
但是,请记住 OSG 采用 row-major 矩阵约定(参见示例 this post)因此您可能需要切换 row/columns 在你的矩阵中。
如果这不起作用,我建议您确定 Sophus 使用的姿势约定(哪个旋转相对于世界坐标中的哪个静止位置)并重新创建同样的转换是osg从零开始。
再次检查Sophus后,我发现我可以分别得到旋转矩阵和平移向量。使用 this post 我将旋转矩阵转换为欧拉角。使用欧拉角,我可以分别设置每个轴的旋转:
rotationMatrix.makeRotate(
osg::DegreesToRadians(-angleZ), osg::Vec3(0,1,0), // roll
osg::DegreesToRadians(angleX), osg::Vec3(1,0,0) , // pitch
osg::DegreesToRadians(angleY), osg::Vec3(0,0,1) ); // heading
倒转终于成功了...