kbrodt commited on
Commit
78d75d4
·
1 Parent(s): 89e7133

Upload hist_cub.py

Browse files
Files changed (1) hide show
  1. src/hist_cub.py +231 -0
src/hist_cub.py ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import itertools
2
+ import functools
3
+ import math
4
+ import multiprocessing
5
+ from pathlib import Path
6
+
7
+ import matplotlib
8
+ matplotlib.rcParams.update({'font.size': 24})
9
+ matplotlib.rcParams.update({
10
+ "text.usetex": True,
11
+ "text.latex.preamble": r"\usepackage{biolinum} \usepackage{libertineRoman} \usepackage{libertineMono} \usepackage{biolinum} \usepackage[libertine]{newtxmath}",
12
+ 'ps.usedistiller': "xpdf",
13
+ })
14
+
15
+ import matplotlib.pyplot as plt
16
+ import matplotlib.gridspec as gridspec
17
+ import numpy as np
18
+ import tqdm
19
+ from scipy.stats import wasserstein_distance
20
+
21
+ import pose_estimation
22
+
23
+
24
+ def cub(x, a, b, c):
25
+ x2 = x * x
26
+ x3 = x2 * x
27
+
28
+ y = a * x3 + b * x2 + c * x
29
+
30
+ return y
31
+
32
+
33
+ def subsample(a, p=0.0005, seed=0):
34
+ np.random.seed(seed)
35
+ N = len(a)
36
+ inds = np.random.choice(range(N), size=int(p * N))
37
+ a = a[inds].copy()
38
+
39
+ return a
40
+
41
+
42
+ def read_cos_opt(path, fname="cos_hist.npy"):
43
+ cos_opt = []
44
+ for p in Path(path).rglob(fname):
45
+ d = np.load(p)
46
+ cos_opt.append(d)
47
+
48
+ cos_opt = np.array(cos_opt)
49
+
50
+ return cos_opt
51
+
52
+
53
+ def plot_hist(cos_opt_dir, hist_smpl_fpath, params, out_dir, bins=10, xy=None):
54
+ cos_opt = read_cos_opt(cos_opt_dir)
55
+ angle_opt = np.arccos(cos_opt)
56
+ angle_opt2 = cub(angle_opt, *params)
57
+
58
+ cos_opt2 = np.cos(angle_opt2)
59
+ cos_smpl = np.load(hist_smpl_fpath)
60
+ # cos_smpl = subsample(cos_smpl)
61
+ print(cos_smpl.shape)
62
+
63
+ cos_smpl = np.clip(cos_smpl, -1, 1)
64
+
65
+ cos_opt = angle_opt
66
+ cos_opt2 = angle_opt2
67
+ cos_smpl = np.arccos(cos_smpl)
68
+
69
+ cos_opt = 180 / math.pi * cos_opt
70
+ cos_opt2 = 180 / math.pi * cos_opt2
71
+ cos_smpl = 180 / math.pi * cos_smpl
72
+ max_range = 90 # math.pi / 2
73
+
74
+ xticks = [0, 15, 30, 45, 60, 75, 90]
75
+ for idx, bone in enumerate(pose_estimation.SKELETON):
76
+ i, j = bone
77
+ i_name = pose_estimation.KPS[i]
78
+ j_name = pose_estimation.KPS[j]
79
+ if i_name != "Left Upper Leg":
80
+ continue
81
+
82
+ name = f"{i_name}_{j_name}"
83
+
84
+ gs = gridspec.GridSpec(2, 4)
85
+ fig = plt.figure(tight_layout=True, figsize=(16, 8), dpi=300)
86
+
87
+ ax0 = fig.add_subplot(gs[0, 0])
88
+ ax0.hist(cos_smpl[:, idx], bins=bins, range=(0, max_range), density=True)
89
+ ax0.set_xticks(xticks)
90
+ ax0.tick_params(labelbottom=False, labelleft=True)
91
+
92
+ ax1 = fig.add_subplot(gs[1, 0], sharex=ax0)
93
+ ax1.hist(cos_opt[:, idx], bins=bins, range=(0, max_range), density=True)
94
+ ax1.set_xticks(xticks)
95
+
96
+ if xy is not None:
97
+ ax2 = fig.add_subplot(gs[:, 1:3])
98
+ ax2.plot(xy[0], xy[1], linewidth=8)
99
+ ax2.plot(xy[0], xy[0], linewidth=4, linestyle="dashed")
100
+ ax2.set_xticks(xticks)
101
+ ax2.set_yticks(xticks)
102
+
103
+ ax3 = fig.add_subplot(gs[0, 3], sharey=ax0)
104
+ ax3.hist(cos_opt2[:, idx], bins=bins, range=(0, max_range), density=True)
105
+ ax3.set_xticks(xticks)
106
+ ax3.tick_params(labelbottom=False, labelleft=False)
107
+
108
+ ax4 = fig.add_subplot(gs[1, 3], sharex=ax3, sharey=ax1)
109
+ alpha = 0.5
110
+ ax4.hist(cos_opt[:, idx], bins=bins, range=(0, max_range), density=True, label=r"$\mathcal{B}_i$", alpha=alpha)
111
+ ax4.hist(cos_opt2[:, idx], bins=bins, range=(0, max_range), density=True, label=r"$f(\mathcal{B}_i)$", alpha=alpha)
112
+ ax4.hist(cos_smpl[:, idx], bins=bins, range=(0, max_range), density=True, label=r"$\mathcal{A}_i$", alpha=alpha)
113
+ ax4.set_xticks(xticks)
114
+ ax4.tick_params(labelbottom=True, labelleft=False)
115
+ ax4.legend()
116
+
117
+ fig.savefig(out_dir / f"hist_{name}.png")
118
+ plt.close()
119
+
120
+
121
+ def kldiv(p_hist, q_hist):
122
+ wd = wasserstein_distance(p_hist, q_hist)
123
+
124
+ return wd
125
+
126
+
127
+ def calc_histogram(x, bins=10, range=(0, 1)):
128
+ h, _ = np.histogram(x, bins=bins, range=range, density=True)
129
+
130
+ return h
131
+
132
+ def step(params, angles_opt, p_hist, bone_idx=None):
133
+ if sum(params) > 1:
134
+ return math.inf, params
135
+
136
+ kl = 0
137
+ for i, _ in enumerate(pose_estimation.SKELETON):
138
+ if bone_idx is not None and i != bone_idx:
139
+ continue
140
+
141
+ angles_opt2 = cub(angles_opt[:, i], *params)
142
+ if angles_opt2.max() > 1 or angles_opt2.min() < 0:
143
+ kl = math.inf
144
+
145
+ break
146
+
147
+ q_hist = calc_histogram(angles_opt2)
148
+
149
+ kl += kldiv(p_hist[i], q_hist)
150
+
151
+ return kl, params
152
+
153
+
154
+ def optimize(cos_opt_dir, hist_smpl_fpath, bone_idx=None):
155
+ cos_opt = read_cos_opt(cos_opt_dir)
156
+ angles_opt = np.arccos(cos_opt) / (math.pi / 2)
157
+ cos_smpl = np.load(hist_smpl_fpath)
158
+ # cos_smpl = subsample(cos_smpl)
159
+ print(cos_smpl.shape)
160
+ cos_smpl = np.clip(cos_smpl, -1, 1)
161
+ mask = cos_smpl <= 1
162
+ assert np.all(mask), (~mask).mean()
163
+ mask = cos_smpl >= 0
164
+ assert np.all(mask), (~mask).mean()
165
+ angles_smpl = np.arccos(cos_smpl) / (math.pi / 2)
166
+ p_hist = [
167
+ calc_histogram(angles_smpl[:, i])
168
+ for i, _ in enumerate(pose_estimation.SKELETON)
169
+ ]
170
+
171
+ with multiprocessing.Pool(8) as p:
172
+ results = list(
173
+ tqdm.tqdm(
174
+ p.imap_unordered(
175
+ functools.partial(step, angles_opt=angles_opt, p_hist=p_hist, bone_idx=bone_idx),
176
+ itertools.product(
177
+ np.linspace(0, 20, 100),
178
+ np.linspace(-20, 20, 200),
179
+ np.linspace(-20, 1, 100),
180
+ ),
181
+ ),
182
+ total=(100 * 200 * 100),
183
+ )
184
+ )
185
+
186
+ kls, params = zip(*results)
187
+ ind = np.argmin(kls)
188
+ best_params = params[ind]
189
+
190
+ print(kls[ind], best_params)
191
+
192
+ inds = np.argsort(kls)
193
+ for i in inds[:10]:
194
+ print(kls[i])
195
+ print(params[i])
196
+ print()
197
+
198
+ return best_params
199
+
200
+
201
+ def main():
202
+ cos_opt_dir = "paper_single2_150mse"
203
+ hist_smpl_fpath = "./data/hist_smpl.npy"
204
+ # hist_smpl_fpath = "./testtest.npy"
205
+ params = optimize(cos_opt_dir, hist_smpl_fpath)
206
+ # params = (1.2121212121212122, -1.105527638190953, 0.787878787878789)
207
+ # params = (0.20202020202020202, 0.30150753768844396, 0.3636363636363633)
208
+ print(params)
209
+
210
+ x = np.linspace(0, math.pi / 2, 100)
211
+ y = cub(x / (math.pi / 2), *params) * (math.pi / 2)
212
+ x = x * 180 / math.pi
213
+ y = y * 180 / math.pi
214
+
215
+ out_dir = Path("hists")
216
+ out_dir.mkdir(parents=True, exist_ok=True)
217
+ plot_hist(cos_opt_dir, hist_smpl_fpath, params, out_dir, xy=(x, y))
218
+
219
+ plt.figure(figsize=(4, 4), dpi=300)
220
+ plt.plot(x, y, linewidth=6)
221
+ plt.plot(x, x, linewidth=2, linestyle="dashed")
222
+ xticks = [0, 15, 30, 45, 60, 75, 90]
223
+ plt.xticks(xticks)
224
+ plt.yticks(xticks)
225
+ plt.axis("equal")
226
+ plt.tight_layout()
227
+ plt.savefig(out_dir / "new_out.png")
228
+
229
+
230
+ if __name__ == "__main__":
231
+ main()