File size: 4,237 Bytes
373af33 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# -*- coding: utf-8 -*-
#
# Copyright (C) 2019 Max-Planck-Gesellschaft zur Förderung der Wissenschaften e.V. (MPG),
# acting on behalf of its Max Planck Institute for Intelligent Systems and the
# Max Planck Institute for Biological Cybernetics. All rights reserved.
#
# Max-Planck-Gesellschaft zur Förderung der Wissenschaften e.V. (MPG) is holder of all proprietary rights
# on this computer program. You can only use this computer program if you have closed a license agreement
# with MPG or you get the right to use the computer program from someone who is authorized to grant you that right.
# Any use of the computer program without a valid license is prohibited and liable to prosecution.
# Contact: [email protected]
#
#
# If you use this code in a research publication please consider citing the following:
#
# Expressive Body Capture: 3D Hands, Face, and Body from a Single Image <https://arxiv.org/abs/1904.05866>
#
#
# Code Developed by:
# Nima Ghorbani <https://nghorbani.github.io/>
#
# 2020.12.12
import numpy as np
from torch.nn import functional as F
from human_body_prior.tools import tgm_conversion as tgm
import torch
def local2global_pose(local_pose, kintree):
bs = local_pose.shape[0]
local_pose = local_pose.view(bs, -1, 3, 3)
global_pose = local_pose.clone()
for jId in range(len(kintree)):
parent_id = kintree[jId]
if parent_id >= 0:
global_pose[:, jId] = torch.matmul(global_pose[:, parent_id], global_pose[:, jId])
return global_pose
def em2euler(em):
'''
:param em: rotation in expo-map (3,)
:return: rotation in euler angles (3,)
'''
from transforms3d.euler import axangle2euler
theta = np.sqrt((em ** 2).sum())
axis = em / theta
return np.array(axangle2euler(axis, theta))
def euler2em(ea):
'''
:param ea: rotation in euler angles (3,)
:return: rotation in expo-map (3,)
'''
from transforms3d.euler import euler2axangle
axis, theta = euler2axangle(*ea)
return np.array(axis*theta)
def remove_zrot(pose):
noZ = em2euler(pose[:3].copy())
noZ[2] = 0
pose[:3] = euler2em(noZ).copy()
return pose
def matrot2aa(pose_matrot):
'''
:param pose_matrot: Nx3x3
:return: Nx3
'''
bs = pose_matrot.size(0)
homogen_matrot = F.pad(pose_matrot, [0,1])
pose = tgm.rotation_matrix_to_angle_axis(homogen_matrot)
return pose
def aa2matrot(pose):
'''
:param Nx3
:return: pose_matrot: Nx3x3
'''
bs = pose.size(0)
num_joints = pose.size(1)//3
pose_body_matrot = tgm.angle_axis_to_rotation_matrix(pose)[:, :3, :3].contiguous()#.view(bs, num_joints*9)
return pose_body_matrot
def noisy_zrot(rot_in):
'''
:param rot_in: np.array Nx3 rotations in axis-angle representation
:return:
will add a degree from a full circle to the zrotations
'''
is_batched = False
if rot_in.ndim == 2: is_batched = True
if not is_batched:
rot_in = rot_in[np.newaxis]
rnd_zrot = np.random.uniform(-np.pi, np.pi)
rot_out = []
for bId in range(len(rot_in)):
pose_cpu = rot_in[bId]
pose_euler = em2euler(pose_cpu)
pose_euler[2] += rnd_zrot
pose_aa = euler2em(pose_euler)
rot_out.append(pose_aa.copy())
return np.array(rot_out)
def rotate_points_xyz(mesh_v, Rxyz):
'''
:param mesh_v: Nxnum_vx3
:param Rxyz: Nx3
:return:
'''
mesh_v_rotated = []
for fId in range(mesh_v.shape[0]):
angle = np.radians(Rxyz[fId, 0])
rx = np.array([
[1., 0., 0. ],
[0., np.cos(angle), -np.sin(angle)],
[0., np.sin(angle), np.cos(angle) ]
])
angle = np.radians(Rxyz[fId, 1])
ry = np.array([
[np.cos(angle), 0., np.sin(angle)],
[0., 1., 0. ],
[-np.sin(angle), 0., np.cos(angle)]
])
angle = np.radians(Rxyz[fId, 2])
rz = np.array([
[np.cos(angle), -np.sin(angle), 0. ],
[np.sin(angle), np.cos(angle), 0. ],
[0., 0., 1. ]
])
mesh_v_rotated.append(rz.dot(ry.dot(rx.dot(mesh_v[fId].T))).T)
return np.array(mesh_v_rotated) |