How to invert the Rotation of one Axis in a Camera Matrix (e.g. OSG CameraViewMatrix)

1.8k views Asked by At

For an augmented reality application I am using some slam algorithm to predict the current orientation of my mobile phone.

The algorithm (LSD-Slam) supplies the current pose in form of a SE3 lie group (using Sophus::Sim3f). If I got this right, this type contains a matrix which can be interpreted as the Viewmatrix of a Camera. After initialisation, e.g. the matrix looks like this:

1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1

To visualize 3D Content, I use OpenSceneGraph. Fortunatley, in OSG you can set the camera position directly using a view-matrix:

camera->setViewMatrix(matrix);

Now, when I run the code things seem to work fine if I rotate around Y (roll) or Z (yaw). But when I rotate around X (pitch), my digital Camera in OSG seems to do the exact opposite of what it's supposed to to.

For example: Imagine a 3D-Model directly in front of the Camera. If I then slowly tilt the camera upwards (around X), the 3D-Model also moves upwards, while it actually should be leaving the screen at the bottom end. I tried to illustrate this behaviour with the following graphic:axis behaviour

Propably there is a really easy solution for this, but I just couldn't fix even after hours of trying. If I understood right, the first Columns represent the rotation around a certain Axis, so I tried inverting the single vectors, e.g. did this:

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

While some tries really solved the Pitch-Issue, they then messed up another axis.. There always seems to be one axis wrong at least. Does anybody have a clue how i could solve this? I'd really appreciate any hints on this issue.

2

There are 2 answers

1
rickyviking On BEST ANSWER

If the pose you get from the library corresponds to the OpenGL view matrix, you should be able to pass it directly to the osg Camera as you mention.

However, keep in mind that OSG adopts a row-major matrix convention (see for example this post) hence you might need to switch row/columns in your matrix.

If that doesn't work, I suggest you to make sure about the pose conventions used by Sophus (which rotations with respect to which rest position in world coords) and recreate the same transformation is osg from scratch.

0
Christoph Göttert On

After checking Sophus again I found I could get a rotation matrix as well as tranlsation vector seperatly. Using this post I converted the rotationmatrix to euler angles. With the euler angles, I was able to set the rotation of each axis seperatly:

  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

Inverting roll did the trick finally...