Convert rotation vector to eularian rotation

Hello,

I am trying to create virtual cameras in a 3D software (blender) corresponding to 360 street views in mapillary.

If I successfully positioned the camera, I cannot say the same for the 3-axis rotation. I tried different conversion techniques from mapillary’s rotation vector extracted from the “computed_rotation” field to eularian but it never was aligned.

Here is my current script that places and rotate on Z the virtual camera from mapillary data. I introduced the - sign when I saw that it wasn’t aligned otherwise.

def place_camera(
    xyz: tuple[float, float, float],
    computed_compass_angle: float,
    offset_altitude: float = 0.3
):
    """
    Parameters
    ----------
    xyz : tuple[float, float, float]
        in meters
    computed_compass_angle : float
        in degree
    offset_altitude : float
        move the z point up or down to account for streets not being at 0
    """
    camera = bpy.context.scene.camera

    x, y, z = xyz
    camera.location = (x, y, z + offset_altitude)
    camera.rotation_euler = mapillary_to_euler(computed_compass_angle)


def mapillary_to_euler(compass_orientation: float) -> tuple[float, float, float]:
    euler_rotation = [90, 0, -compass_orientation]

    return deg2rad(euler_rotation)

and here is my two tries for 3D rotation, with the second one being as close as possible as my understanding of https://opensfm.org/docs/cam_coord_system.html:

def mapillary_to_euler(mapillary_rotation: tuple[float, float, float]) -> tuple[float, float, float]:
    roll, pitch, yaw = mapillary_rotation
    euler_rotation = mathutils.Euler((pitch, yaw, roll), 'XYZ')

    return euler_rotation


def mapillary_to_euler(mapillary_rotation: tuple[float, float, float]) -> tuple[float, float, float]:
    length = np.linalg.norm(mapillary_rotation)
    euler_rotation = mathutils.Matrix.Rotation(length, 3, mapillary_rotation).to_euler("XYZ")

    return euler_rotation

Thank you for your help

1 Like

Hello,

So after more and more research, I stumbled upon this doc mentioning the angle axis rotation vector.

From that, I was able to code this function that effectively convert mapillary rotation vector to blender eulerarian rotation vector:

def mapillary_to_euler(angle_axis_rot: tuple[float, float, float]) -> tuple[float, float, float]:
    """
    convert the mapillary rotation vector to a blender rotation vector

    Parameters
    ----------
    angle_axis_rot : tuple[float, float, float]
        angle axis rotation vector from mapillary

    Returns
    -------
    tuple[float, float, float]
        eularian rotation vector for blender
    """
    e = angle_axis_rot / np.linalg.norm(angle_axis_rot)
    teta = np.linalg.norm(angle_axis_rot)

    axis_angle_rot = mathutils.Matrix.Rotation(-teta, 3, e)

    # this is to correctly align axis in blender according to https://opensfm.org/docs/cam_coord_system.html
    camera_rotation = mathutils.Euler([0, pi, pi])

    camera_rotation.rotate(axis_angle_rot)

    return camera_rotation
1 Like