ttxskk
update
d7e58f0
raw
history blame
4.19 kB
import numpy as np
from detrsmpl.utils.transforms import aa_to_rotmat, rotmat_to_aa
def transform_to_camera_frame(global_orient, transl, pelvis, extrinsic):
"""Transform body model parameters to camera frame.
Args:
global_orient (numpy.ndarray): shape (3, ). Only global_orient and
transl needs to be updated in the rigid transformation
transl (numpy.ndarray): shape (3, ).
pelvis (numpy.ndarray): shape (3, ). 3D joint location of pelvis
This is necessary to eliminate the offset from SMPL
canonical space origin to pelvis, because the global orient
is conducted around the pelvis, not the canonical space origin
extrinsic (numpy.ndarray): shape (4, 4). Transformation matrix
from world frame to camera frame
Returns:
(new_gloabl_orient, new_transl)
new_gloabl_orient: transformed global orient
new_transl: transformed transl
"""
# take out the small offset from smpl origin to pelvis
transl_offset = pelvis - transl
T_p2w = np.eye(4)
T_p2w[:3, 3] = transl_offset
# camera extrinsic: transformation from world frame to camera frame
T_w2c = extrinsic
# smpl transformation: from vertex frame to world frame
T_v2p = np.eye(4)
global_orient_mat = aa_to_rotmat(global_orient)
T_v2p[:3, :3] = global_orient_mat
T_v2p[:3, 3] = transl
# compute combined transformation from vertex to world
T_v2w = T_p2w @ T_v2p
# compute transformation from vertex to camera
T_v2c = T_w2c @ T_v2w
# decompose vertex to camera transformation
# np: new pelvis frame
# T_v2c = T_np2c x T_v2np
T_np2c = T_p2w
T_v2np = np.linalg.inv(T_np2c) @ T_v2c
# decompose into new global orient and new transl
new_global_orient_mat = T_v2np[:3, :3]
new_global_orient = rotmat_to_aa(new_global_orient_mat)
new_transl = T_v2np[:3, 3]
return new_global_orient, new_transl
def batch_transform_to_camera_frame(global_orient, transl, pelvis, extrinsic):
"""Transform body model parameters to camera frame by batch.
Args:
global_orient (np.ndarray): shape (N, 3). Only global_orient and
transl needs to be updated in the rigid transformation
transl (np.ndarray): shape (N, 3).
pelvis (np.ndarray): shape (N, 3). 3D joint location of pelvis
This is necessary to eliminate the offset from SMPL
canonical space origin to pelvis, because the global orient
is conducted around the pelvis, not the canonical space origin
extrinsic (np.ndarray): shape (4, 4). Transformation matrix
from world frame to camera frame
Returns:
(new_gloabl_orient, new_transl)
new_gloabl_orient: transformed global orient
new_transl: transformed transl
"""
N = len(global_orient)
assert global_orient.shape == (N, 3)
assert transl.shape == (N, 3)
assert pelvis.shape == (N, 3)
# take out the small offset from smpl origin to pelvis
transl_offset = pelvis - transl
T_p2w = np.eye(4).reshape(1, 4, 4).repeat(N, axis=0)
T_p2w[:, :3, 3] = transl_offset
# camera extrinsic: transformation from world frame to camera frame
T_w2c = extrinsic
# smpl transformation: from vertex frame to world frame
T_v2p = np.eye(4).reshape(1, 4, 4).repeat(N, axis=0)
global_orient_mat = aa_to_rotmat(global_orient)
T_v2p[:, :3, :3] = global_orient_mat
T_v2p[:, :3, 3] = transl
# compute combined transformation from vertex to world
T_v2w = T_p2w @ T_v2p
# compute transformation from vertex to camera
T_v2c = T_w2c @ T_v2w
# decompose vertex to camera transformation
# np: new pelvis frame
# T_v2c = T_np2c x T_v2np
T_np2c = T_p2w
T_v2np = np.linalg.inv(T_np2c) @ T_v2c
# decompose into new global orient and new transl
new_global_orient_mat = T_v2np[:, :3, :3]
new_global_orient = rotmat_to_aa(new_global_orient_mat)
new_transl = T_v2np[:, :3, 3]
assert new_global_orient.shape == (N, 3)
assert new_transl.shape == (N, 3)
return new_global_orient, new_transl