Sukanyaaa's picture
Upload 36 files
b38c7b5 verified
import torch
# batch*n
def normalize_vector(v):
batch = v.shape[0]
v_mag = torch.sqrt(v.pow(2).sum(1)) # batch
eps = torch.tensor(1e-8, device=v.device)
v_mag = torch.max(v_mag, eps)
v_mag = v_mag.view(batch, 1).expand(batch, v.shape[1])
v = v / v_mag
return v
# u, v batch*n
def cross_product(u, v):
batch = u.shape[0]
# print (u.shape)
# print (v.shape)
i = u[:, 1] * v[:, 2] - u[:, 2] * v[:, 1]
j = u[:, 2] * v[:, 0] - u[:, 0] * v[:, 2]
k = u[:, 0] * v[:, 1] - u[:, 1] * v[:, 0]
out = torch.cat((i.view(batch, 1), j.view(batch, 1), k.view(batch, 1)), 1) # batch*3
return out
# poses batch*6
# poses
def compute_rotation_matrix_from_ortho6d(poses):
x_raw = poses[:, 0:3] # batch*3
y_raw = poses[:, 3:6] # batch*3
x = normalize_vector(x_raw) # batch*3
z = cross_product(x, y_raw) # batch*3
z = normalize_vector(z) # batch*3
y = cross_product(z, x) # batch*3
x = x.view(-1, 3, 1)
y = y.view(-1, 3, 1)
z = z.view(-1, 3, 1)
matrix = torch.cat((x, y, z), 2) # batch*3*3
return matrix
# input batch*4*4 or batch*3*3
# output torch batch*3 x, y, z in radiant
# the rotation is in the sequence of x,y,z
def compute_euler_angles_from_rotation_matrices(rotation_matrices):
batch = rotation_matrices.shape[0]
R = rotation_matrices
sy = torch.sqrt(R[:, 0, 0] * R[:, 0, 0] + R[:, 1, 0] * R[:, 1, 0])
singular = sy < 1e-6
singular = singular.float()
x = torch.atan2(R[:, 2, 1], R[:, 2, 2])
y = torch.atan2(-R[:, 2, 0], sy)
z = torch.atan2(R[:, 1, 0], R[:, 0, 0])
xs = torch.atan2(-R[:, 1, 2], R[:, 1, 1])
ys = torch.atan2(-R[:, 2, 0], sy)
zs = R[:, 1, 0] * 0
out_euler = torch.zeros(batch, 3, device=rotation_matrices.device)
out_euler[:, 0] = x * (1 - singular) + xs * singular
out_euler[:, 1] = y * (1 - singular) + ys * singular
out_euler[:, 2] = z * (1 - singular) + zs * singular
return out_euler
def get_R(x, y, z):
"""Get rotation matrix from three rotation angles (radians). right-handed.
Args:
x: rotation angle around x-axis
y: rotation angle around y-axis
z: rotation angle around z-axis
Returns:
R: [3, 3]. rotation matrix.
"""
# x
Rx = torch.tensor(
[[1, 0, 0], [0, torch.cos(x), -torch.sin(x)], [0, torch.sin(x), torch.cos(x)]],
device=x.device,
)
# y
Ry = torch.tensor(
[[torch.cos(y), 0, torch.sin(y)], [0, 1, 0], [-torch.sin(y), 0, torch.cos(y)]],
device=y.device,
)
# z
Rz = torch.tensor(
[[torch.cos(z), -torch.sin(z), 0], [torch.sin(z), torch.cos(z), 0], [0, 0, 1]],
device=z.device,
)
R = torch.mm(Rz, torch.mm(Ry, Rx))
return R