-
Notifications
You must be signed in to change notification settings - Fork 147
/
pose_utils.py
149 lines (127 loc) · 4.41 KB
/
pose_utils.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
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
import torch
import numpy as np
from config import cfg
import copy
def cam2pixel(cam_coord, f, c):
x = cam_coord[:, 0] / (cam_coord[:, 2] + 1e-8) * f[0] + c[0]
y = cam_coord[:, 1] / (cam_coord[:, 2] + 1e-8) * f[1] + c[1]
z = cam_coord[:, 2]
img_coord = np.concatenate((x[:,None], y[:,None], z[:,None]),1)
return img_coord
def pixel2cam(pixel_coord, f, c):
x = (pixel_coord[:, 0] - c[0]) / f[0] * pixel_coord[:, 2]
y = (pixel_coord[:, 1] - c[1]) / f[1] * pixel_coord[:, 2]
z = pixel_coord[:, 2]
cam_coord = np.concatenate((x[:,None], y[:,None], z[:,None]),1)
return cam_coord
def world2cam(world_coord, R, t):
cam_coord = np.dot(R, world_coord.transpose(1,0)).transpose(1,0) + t.reshape(1,3)
return cam_coord
def rigid_transform_3D(A, B):
centroid_A = np.mean(A, axis = 0)
centroid_B = np.mean(B, axis = 0)
H = np.dot(np.transpose(A - centroid_A), B - centroid_B)
U, s, V = np.linalg.svd(H)
R = np.dot(np.transpose(V), np.transpose(U))
if np.linalg.det(R) < 0:
V[2] = -V[2]
R = np.dot(np.transpose(V), np.transpose(U))
t = -np.dot(R, np.transpose(centroid_A)) + np.transpose(centroid_B)
return R, t
def rigid_align(A, B):
R, t = rigid_transform_3D(A, B)
A2 = np.transpose(np.dot(R, np.transpose(A))) + t
return A2
def get_bbox(joint_img):
# bbox extract from keypoint coordinates
bbox = np.zeros((4))
xmin = np.min(joint_img[:,0])
ymin = np.min(joint_img[:,1])
xmax = np.max(joint_img[:,0])
ymax = np.max(joint_img[:,1])
width = xmax - xmin - 1
height = ymax - ymin - 1
bbox[0] = (xmin + xmax)/2. - width/2*1.2
bbox[1] = (ymin + ymax)/2. - height/2*1.2
bbox[2] = width*1.2
bbox[3] = height*1.2
return bbox
def process_bbox(bbox, width, height):
# sanitize bboxes
x, y, w, h = bbox
x1 = np.max((0, x))
y1 = np.max((0, y))
x2 = np.min((width - 1, x1 + np.max((0, w - 1))))
y2 = np.min((height - 1, y1 + np.max((0, h - 1))))
if w*h > 0 and x2 >= x1 and y2 >= y1:
bbox = np.array([x1, y1, x2-x1, y2-y1])
else:
return None
# aspect ratio preserving bbox
w = bbox[2]
h = bbox[3]
c_x = bbox[0] + w/2.
c_y = bbox[1] + h/2.
aspect_ratio = cfg.input_shape[1]/cfg.input_shape[0]
if w > aspect_ratio * h:
h = w / aspect_ratio
elif w < aspect_ratio * h:
w = h * aspect_ratio
bbox[2] = w*1.25
bbox[3] = h*1.25
bbox[0] = c_x - bbox[2]/2.
bbox[1] = c_y - bbox[3]/2.
return bbox
def transform_joint_to_other_db(src_joint, src_name, dst_name):
src_joint_num = len(src_name)
dst_joint_num = len(dst_name)
new_joint = np.zeros(((dst_joint_num,) + src_joint.shape[1:]))
for src_idx in range(len(src_name)):
name = src_name[src_idx]
if name in dst_name:
dst_idx = dst_name.index(name)
new_joint[dst_idx] = src_joint[src_idx]
return new_joint
def fliplr_joints(_joints, width, matched_parts):
"""
flip coords
joints: numpy array, nJoints * dim, dim == 2 [x, y] or dim == 3 [x, y, z]
width: image width
matched_parts: list of pairs
"""
joints = _joints.copy()
# Flip horizontal
joints[:, 0] = width - joints[:, 0] - 1
# Change left-right parts
for pair in matched_parts:
joints[pair[0], :], joints[pair[1], :] = joints[pair[1], :], joints[pair[0], :].copy()
return joints
def multi_meshgrid(*args):
"""
Creates a meshgrid from possibly many
elements (instead of only 2).
Returns a nd tensor with as many dimensions
as there are arguments
"""
args = list(args)
template = [1 for _ in args]
for i in range(len(args)):
n = args[i].shape[0]
template_copy = template.copy()
template_copy[i] = n
args[i] = args[i].view(*template_copy)
# there will be some broadcast magic going on
return tuple(args)
def flip(tensor, dims):
if not isinstance(dims, (tuple, list)):
dims = [dims]
indices = [torch.arange(tensor.shape[dim] - 1, -1, -1,
dtype=torch.int64) for dim in dims]
multi_indices = multi_meshgrid(*indices)
final_indices = [slice(i) for i in tensor.shape]
for i, dim in enumerate(dims):
final_indices[dim] = multi_indices[i]
flipped = tensor[final_indices]
assert flipped.device == tensor.device
assert flipped.requires_grad == tensor.requires_grad
return flipped