How to convert these Euler angles to a 3×3 rotation matrix

rotations

I'm working with a set of stereo cameras and having trouble with the math for the rotation calibration in openCV. Each set of cameras comes with a set of calibration data that includes three Euler angles to describe rotation between the left camera to the right camera. (It also includes translation data and distortion parameters). The angles are described as using passive rotation where you rotate about the first axis, then from the new position you rotate around the next axis if I understand that correctly. Finally the coordinate system's axis are defined like this: If you stood in a t-pose and could shoot lasers out of your eyes they would go in the positive z direction, your legs would be the positive y direction, and right arm the positive x direction.

edit: I forgot to add that I know the order of rotations is x, y, z.

I tried the following approach.
I define the R_x, R_y, and R_z matrix like this:

R_x << 1, 0, 0,
       0, cos(E_x[0]), -sin(E_x[0]),
       0, sin(E_x[0]), cos(E_x[0]);

R_y << cos(E_y[0]), 0, sin(E_y[0]),
       0, 1, 0
       -sin(E_y[0]), 0, cos(E_y[0]);

R_z << cos(E_z[0]), -sin(E_z[0]), 0,
       sin(E_z[0]), cos(E_z[0]), 0,
       0, 0, 1;

Then I multiply them like this:

R = R_x * R_y * R_z;

And I also tried every possible ordering of that multiplication. Still my results are either a blurred mess or rotated 90 degrees. So I'm missing something about how to do this.

Best Answer

Given what you've said about matrix-vector multiply, the order you need for your rotations is certainly $$ R_z \cdot R_y \cdot R_x $$ because when applied to a vector $v$, this will result in $$ v \mapsto R_z (R_y (R_x \cdot v))) $$ so that rotation about $x$ is applied first, then rotation about $y$, etc.

What's not clear is your sentence "The angles are described as using passive rotation where you rotate about the first axis, then from the new position you rotate around the next axis if I understand that correctly." The question that remains is whether the axes themselves are rotated as well. I'm going to assume not, but ... who knows?

As for the end results being rotated 90 degrees, you might try out your experiment using 0-degree rotation angles for all three angles; the resulting matrix should be the identity matrix, and your images should not move at all. If they do, then maybe there's a row-column swap somewhere.

It's also possible that your $R_y$ matrix should be

R_y << cos(E_y[0]), 0, -sin(E_y[0]),
       0, 1, 0
       sin(E_y[0]), 0, cos(E_y[0]);

Both conventions are used by various software. The one you wrote is better (in my mind, at least), but beauty is in the eye of the beholder, and all that. Even so, unless your y-rotation amount is approximately 45 degrees, this change would not create an off-by-90-degrees error, so I doubt it's the source of the problems.