kairunwen's picture
add code
35e2073
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import numpy as np
import utils.utils_poses.ATE.transformations as tfs
import utils.utils_poses.ATE.align_trajectory as align
def _getIndices(n_aligned, total_n):
if n_aligned == -1:
idxs = np.arange(0, total_n)
else:
assert n_aligned <= total_n and n_aligned >= 1
idxs = np.arange(0, n_aligned)
return idxs
def alignPositionYawSingle(p_es, p_gt, q_es, q_gt):
'''
calcualte the 4DOF transformation: yaw R and translation t so that:
gt = R * est + t
'''
p_es_0, q_es_0 = p_es[0, :], q_es[0, :]
p_gt_0, q_gt_0 = p_gt[0, :], q_gt[0, :]
g_rot = tfs.quaternion_matrix(q_gt_0)
g_rot = g_rot[0:3, 0:3]
est_rot = tfs.quaternion_matrix(q_es_0)
est_rot = est_rot[0:3, 0:3]
C_R = np.dot(est_rot, g_rot.transpose())
theta = align.get_best_yaw(C_R)
R = align.rot_z(theta)
t = p_gt_0 - np.dot(R, p_es_0)
return R, t
def alignPositionYaw(p_es, p_gt, q_es, q_gt, n_aligned=1):
if n_aligned == 1:
R, t = alignPositionYawSingle(p_es, p_gt, q_es, q_gt)
return R, t
else:
idxs = _getIndices(n_aligned, p_es.shape[0])
est_pos = p_es[idxs, 0:3]
gt_pos = p_gt[idxs, 0:3]
_, R, t = align.align_umeyama(gt_pos, est_pos, known_scale=True,
yaw_only=True) # note the order
t = np.array(t)
t = t.reshape((3, ))
R = np.array(R)
return R, t
# align by a SE3 transformation
def alignSE3Single(p_es, p_gt, q_es, q_gt):
'''
Calculate SE3 transformation R and t so that:
gt = R * est + t
Using only the first poses of est and gt
'''
p_es_0, q_es_0 = p_es[0, :], q_es[0, :]
p_gt_0, q_gt_0 = p_gt[0, :], q_gt[0, :]
g_rot = tfs.quaternion_matrix(q_gt_0)
g_rot = g_rot[0:3, 0:3]
est_rot = tfs.quaternion_matrix(q_es_0)
est_rot = est_rot[0:3, 0:3]
R = np.dot(g_rot, np.transpose(est_rot))
t = p_gt_0 - np.dot(R, p_es_0)
return R, t
def alignSE3(p_es, p_gt, q_es, q_gt, n_aligned=-1):
'''
Calculate SE3 transformation R and t so that:
gt = R * est + t
'''
if n_aligned == 1:
R, t = alignSE3Single(p_es, p_gt, q_es, q_gt)
return R, t
else:
idxs = _getIndices(n_aligned, p_es.shape[0])
est_pos = p_es[idxs, 0:3]
gt_pos = p_gt[idxs, 0:3]
s, R, t = align.align_umeyama(gt_pos, est_pos,
known_scale=True) # note the order
t = np.array(t)
t = t.reshape((3, ))
R = np.array(R)
return R, t
# align by similarity transformation
def alignSIM3(p_es, p_gt, q_es, q_gt, n_aligned=-1):
'''
calculate s, R, t so that:
gt = R * s * est + t
'''
idxs = _getIndices(n_aligned, p_es.shape[0])
est_pos = p_es[idxs, 0:3]
gt_pos = p_gt[idxs, 0:3]
s, R, t = align.align_umeyama(gt_pos, est_pos) # note the order
return s, R, t
# a general interface
def alignTrajectory(p_es, p_gt, q_es, q_gt, method, n_aligned=-1):
'''
calculate s, R, t so that:
gt = R * s * est + t
method can be: sim3, se3, posyaw, none;
n_aligned: -1 means using all the frames
'''
assert p_es.shape[1] == 3
assert p_gt.shape[1] == 3
assert q_es.shape[1] == 4
assert q_gt.shape[1] == 4
s = 1
R = None
t = None
if method == 'sim3':
assert n_aligned >= 2 or n_aligned == -1, "sim3 uses at least 2 frames"
s, R, t = alignSIM3(p_es, p_gt, q_es, q_gt, n_aligned)
elif method == 'se3':
R, t = alignSE3(p_es, p_gt, q_es, q_gt, n_aligned)
elif method == 'posyaw':
R, t = alignPositionYaw(p_es, p_gt, q_es, q_gt, n_aligned)
elif method == 'none':
R = np.identity(3)
t = np.zeros((3, ))
else:
assert False, 'unknown alignment method'
return s, R, t
if __name__ == '__main__':
pass