forked from CalciferZh/minimal-hand
-
Notifications
You must be signed in to change notification settings - Fork 11
/
hand_mesh.py
83 lines (71 loc) · 2.31 KB
/
hand_mesh.py
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
import numpy as np
from transforms3d.quaternions import quat2mat
from config import *
from kinematics import *
from utils import *
class HandMesh():
"""
Wrapper for the MANO hand model.
"""
def __init__(self, model_path):
"""
Init.
Parameters
----------
model_path : str
Path to the MANO model file. This model is converted by `prepare_mano.py`
from official release.
"""
params = load_pkl(model_path)
self.verts = params['verts']
self.faces = params['faces']
self.weights = params['weights']
self.joints = params['joints']
self.n_verts = self.verts.shape[0]
self.n_faces = self.faces.shape[0]
self.ref_pose = []
self.ref_T = []
for j in range(MANOHandJoints.n_joints):
parent = MANOHandJoints.parents[j]
if parent is None:
self.ref_T.append(self.verts)
self.ref_pose.append(self.joints[j])
else:
self.ref_T.append(self.verts - self.joints[parent])
self.ref_pose.append(self.joints[j] - self.joints[parent])
self.ref_pose = np.expand_dims(np.stack(self.ref_pose, 0), -1)
self.ref_T = np.expand_dims(np.stack(self.ref_T, 1), -1)
def set_abs_quat(self, quat):
"""
Set absolute (global) rotation for the hand.
Parameters
----------
quat : np.ndarray, shape [J, 4]
Absolute rotations for each joint in quaternion.
Returns
-------
np.ndarray, shape [V, 3]
Mesh vertices after posing.
"""
mats = []
for j in range(MANOHandJoints.n_joints):
mats.append(quat2mat(quat[j]))
mats = np.stack(mats, 0)
pose = np.matmul(mats, self.ref_pose)
joint_xyz = [None] * MANOHandJoints.n_joints
for j in range(MANOHandJoints.n_joints):
joint_xyz[j] = pose[j]
parent = MANOHandJoints.parents[j]
if parent is not None:
joint_xyz[j] += joint_xyz[parent]
joint_xyz = np.stack(joint_xyz, 0)[..., 0]
T = np.matmul(np.expand_dims(mats, 0), self.ref_T)[..., 0]
self.verts = [None] * MANOHandJoints.n_joints
for j in range(MANOHandJoints.n_joints):
self.verts[j] = T[:, j]
parent = MANOHandJoints.parents[j]
if parent is not None:
self.verts[j] += joint_xyz[parent]
self.verts = np.stack(self.verts, 1)
self.verts = np.sum(self.verts * self.weights, 1)
return self.verts.copy()