Spaces:
Running
on
L40S
Running
on
L40S
# -*- coding: utf-8 -*- | |
# 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. | |
# | |
# Copyright©2019 Max-Planck-Gesellschaft zur Förderung | |
# der Wissenschaften e.V. (MPG). acting on behalf of its Max Planck Institute | |
# for Intelligent Systems. All rights reserved. | |
# | |
# Contact: ps-license@tuebingen.mpg.de | |
from typing import NewType, Union, Optional | |
from dataclasses import dataclass, asdict, fields | |
import numpy as np | |
import torch | |
Tensor = NewType('Tensor', torch.Tensor) | |
Array = NewType('Array', np.ndarray) | |
class ModelOutput: | |
vertices: Optional[Tensor] = None | |
joints: Optional[Tensor] = None | |
full_pose: Optional[Tensor] = None | |
global_orient: Optional[Tensor] = None | |
transl: Optional[Tensor] = None | |
def __getitem__(self, key): | |
return getattr(self, key) | |
def get(self, key, default=None): | |
return getattr(self, key, default) | |
def __iter__(self): | |
return self.keys() | |
def keys(self): | |
keys = [t.name for t in fields(self)] | |
return iter(keys) | |
def values(self): | |
values = [getattr(self, t.name) for t in fields(self)] | |
return iter(values) | |
def items(self): | |
data = [(t.name, getattr(self, t.name)) for t in fields(self)] | |
return iter(data) | |
class SMPLOutput(ModelOutput): | |
betas: Optional[Tensor] = None | |
body_pose: Optional[Tensor] = None | |
class SMPLHOutput(SMPLOutput): | |
left_hand_pose: Optional[Tensor] = None | |
right_hand_pose: Optional[Tensor] = None | |
transl: Optional[Tensor] = None | |
class SMPLXOutput(SMPLHOutput): | |
expression: Optional[Tensor] = None | |
jaw_pose: Optional[Tensor] = None | |
joint_transformation: Optional[Tensor] = None | |
vertex_transformation: Optional[Tensor] = None | |
class MANOOutput(ModelOutput): | |
betas: Optional[Tensor] = None | |
hand_pose: Optional[Tensor] = None | |
class FLAMEOutput(ModelOutput): | |
betas: Optional[Tensor] = None | |
expression: Optional[Tensor] = None | |
jaw_pose: Optional[Tensor] = None | |
neck_pose: Optional[Tensor] = None | |
def find_joint_kin_chain(joint_id, kinematic_tree): | |
kin_chain = [] | |
curr_idx = joint_id | |
while curr_idx != -1: | |
kin_chain.append(curr_idx) | |
curr_idx = kinematic_tree[curr_idx] | |
return kin_chain | |
def to_tensor(array: Union[Array, Tensor], dtype=torch.float32) -> Tensor: | |
if torch.is_tensor(array): | |
return array | |
else: | |
return torch.tensor(array, dtype=dtype) | |
class Struct(object): | |
def __init__(self, **kwargs): | |
for key, val in kwargs.items(): | |
setattr(self, key, val) | |
def to_np(array, dtype=np.float32): | |
if 'scipy.sparse' in str(type(array)): | |
array = array.todense() | |
return np.array(array, dtype=dtype) | |
def rot_mat_to_euler(rot_mats): | |
# Calculates rotation matrix to euler angles | |
# Careful for extreme cases of eular angles like [0.0, pi, 0.0] | |
sy = torch.sqrt(rot_mats[:, 0, 0] * rot_mats[:, 0, 0] + | |
rot_mats[:, 1, 0] * rot_mats[:, 1, 0]) | |
return torch.atan2(-rot_mats[:, 2, 0], sy) | |