MCPcopy Create free account
hub / github.com/MotrixLab/AiOS / quaternion_to_angle_axis

Function quaternion_to_angle_axis

detrsmpl/utils/geometry.py:119–163  ·  view source on GitHub ↗

This function is borrowed from https://github.com/kornia/kornia Convert quaternion vector to angle axis of rotation. Adapted from ceres C++ library: ceres-solver/include/ceres/rotation.h Args: quaternion (torch.Tensor): tensor with quaternions. Return: torch.Tens

(quaternion: torch.Tensor)

Source from the content-addressed store, hash-verified

117
118
119def quaternion_to_angle_axis(quaternion: torch.Tensor) -> torch.Tensor:
120 """
121 This function is borrowed from https://github.com/kornia/kornia
122 Convert quaternion vector to angle axis of rotation.
123 Adapted from ceres C++ library: ceres-solver/include/ceres/rotation.h
124 Args:
125 quaternion (torch.Tensor): tensor with quaternions.
126 Return:
127 torch.Tensor: tensor with angle axis of rotation.
128 Shape:
129 - Input: :math:`(*, 4)` where `*` means, any number of dimensions
130 - Output: :math:`(*, 3)`
131 Example:
132 >>> quaternion = torch.rand(2, 4) # Nx4
133 >>> angle_axis = tgm.quaternion_to_angle_axis(quaternion) # Nx3
134 """
135 if not torch.is_tensor(quaternion):
136 raise TypeError('Input type is not a torch.Tensor. Got {}'.format(
137 type(quaternion)))
138
139 if not quaternion.shape[-1] == 4:
140 raise ValueError(
141 'Input must be a tensor of shape Nx4 or 4. Got {}'.format(
142 quaternion.shape))
143 # unpack input and compute conversion
144 q1: torch.Tensor = quaternion[..., 1]
145 q2: torch.Tensor = quaternion[..., 2]
146 q3: torch.Tensor = quaternion[..., 3]
147 sin_squared_theta: torch.Tensor = q1 * q1 + q2 * q2 + q3 * q3
148
149 sin_theta: torch.Tensor = torch.sqrt(sin_squared_theta)
150 cos_theta: torch.Tensor = quaternion[..., 0]
151 two_theta: torch.Tensor = 2.0 * torch.where(
152 cos_theta < 0.0, torch.atan2(-sin_theta, -cos_theta),
153 torch.atan2(sin_theta, cos_theta))
154
155 k_pos: torch.Tensor = two_theta / sin_theta
156 k_neg: torch.Tensor = 2.0 * torch.ones_like(sin_theta)
157 k: torch.Tensor = torch.where(sin_squared_theta > 0.0, k_pos, k_neg)
158
159 angle_axis: torch.Tensor = torch.zeros_like(quaternion)[..., :3]
160 angle_axis[..., 0] += q1 * k
161 angle_axis[..., 1] += q2 * k
162 angle_axis[..., 2] += q3 * k
163 return angle_axis
164
165
166def rotation_matrix_to_quaternion(rotation_matrix, eps=1e-6):

Callers 1

Calls

no outgoing calls

Tested by

no test coverage detected