|
import torch |
|
import numpy as np |
|
|
|
|
|
|
|
|
|
|
|
|
|
def normalize_vector(v): |
|
batch = v.shape[0] |
|
v_mag = torch.sqrt(v.pow(2).sum(1)) |
|
v_mag = torch.max(v_mag, torch.autograd.Variable(torch.FloatTensor([1e-8]).to(v.device))) |
|
v_mag = v_mag.view(batch, 1).expand(batch, v.shape[1]) |
|
v = v / v_mag |
|
return v |
|
|
|
|
|
|
|
def cross_product(u, v): |
|
batch = u.shape[0] |
|
|
|
|
|
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) |
|
|
|
return out |
|
|
|
|
|
def rotation_matrix_from_ortho6d(poses): |
|
""" |
|
Computes rotation matrix from 6D continuous space according to the parametrisation proposed in |
|
On the Continuity of Rotation Representations in Neural Networks |
|
https://arxiv.org/pdf/1812.07035.pdf |
|
:param poses: [B, 6] |
|
:return: R: [B, 3, 3] |
|
""" |
|
|
|
x_raw = poses[:, 0:3] |
|
y_raw = poses[:, 3:6] |
|
|
|
x = normalize_vector(x_raw) |
|
z = cross_product(x, y_raw) |
|
z = normalize_vector(z) |
|
y = cross_product(z, x) |
|
|
|
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) |
|
return matrix |
|
|
|
|
|
|
|
def rotation_matrix_from_quaternion(quaternion): |
|
batch=quaternion.shape[0] |
|
|
|
quat = normalize_vector(quaternion).contiguous() |
|
|
|
qw = quat[...,0].contiguous().view(batch, 1) |
|
qx = quat[...,1].contiguous().view(batch, 1) |
|
qy = quat[...,2].contiguous().view(batch, 1) |
|
qz = quat[...,3].contiguous().view(batch, 1) |
|
|
|
|
|
xx = qx*qx |
|
yy = qy*qy |
|
zz = qz*qz |
|
xy = qx*qy |
|
xz = qx*qz |
|
yz = qy*qz |
|
xw = qx*qw |
|
yw = qy*qw |
|
zw = qz*qw |
|
|
|
row0 = torch.cat((1-2*yy-2*zz, 2*xy - 2*zw, 2*xz + 2*yw), 1) |
|
row1 = torch.cat((2*xy+ 2*zw, 1-2*xx-2*zz, 2*yz-2*xw ), 1) |
|
row2 = torch.cat((2*xz-2*yw, 2*yz+2*xw, 1-2*xx-2*yy), 1) |
|
|
|
matrix = torch.cat((row0.view(batch, 1, 3), row1.view(batch,1,3), row2.view(batch,1,3)),1) |
|
|
|
return matrix |
|
|
|
|
|
def correct_intrinsic_scale(K, scale_x, scale_y): |
|
'''Given an intrinsic matrix (3x3) and two scale factors, returns the new intrinsic matrix corresponding to |
|
the new coordinates x' = scale_x * x; y' = scale_y * y |
|
Source: https://dsp.stackexchange.com/questions/6055/how-does-resizing-an-image-affect-the-intrinsic-camera-matrix |
|
''' |
|
|
|
transform = np.eye(3) |
|
transform[0, 0] = scale_x |
|
transform[0, 2] = scale_x / 2 - 0.5 |
|
transform[1, 1] = scale_y |
|
transform[1, 2] = scale_y / 2 - 0.5 |
|
Kprime = transform @ K |
|
|
|
return Kprime |
|
|