Spaces:
Sleeping
Sleeping
File size: 1,898 Bytes
e7b9fb6 |
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 |
# Modified from https://github.com/zhan-xu/RigNet
import numpy as np
##### for quantitative calculation
def chamfer_dist(pt1, pt2):
pt1 = pt1[np.newaxis, :, :]
pt2 = pt2[:, np.newaxis, :]
dist = np.sqrt(np.sum((pt1 - pt2) ** 2, axis=2))
min_left = np.mean(np.min(dist, axis=0))
min_right = np.mean(np.min(dist, axis=1))
return (min_left + min_right) / 2
def oneway_chamfer(pt_src, pt_dst):
pt1 = pt_src[np.newaxis, :, :]
pt2 = pt_dst[:, np.newaxis, :]
dist = np.sqrt(np.sum((pt1 - pt2) ** 2, axis=2))
avg_dist = np.mean(np.min(dist, axis=0))
return avg_dist
def joint2bone_chamfer_dist(joints1, bones1, joints2, bones2):
bone_sample_1 = sample_skel(joints1, bones1)
bone_sample_2 = sample_skel(joints2, bones2)
dist1 = oneway_chamfer(joints1, bone_sample_2)
dist2 = oneway_chamfer(joints2, bone_sample_1)
return (dist1 + dist2) / 2
def bone2bone_chamfer_dist(joints1, bones1, joints2, bones2):
bone_sample_1 = sample_skel(joints1, bones1)
bone_sample_2 = sample_skel(joints2, bones2)
return chamfer_dist(bone_sample_1, bone_sample_2)
def sample_bone(p_pos, ch_pos):
ray = ch_pos - p_pos
bone_length = np.linalg.norm(p_pos - ch_pos)
num_step = np.round(bone_length / 0.005).astype(int)
i_step = np.arange(0, num_step + 1)
unit_step = ray / (num_step + 1e-30)
unit_step = np.repeat(unit_step[np.newaxis, :], num_step + 1, axis=0)
res = p_pos + unit_step * i_step[:, np.newaxis]
return res
def sample_skel(joints, bones):
bone_sample = []
for parent_idx, child_idx in bones:
p_pos = joints[parent_idx]
ch_pos = joints[child_idx]
res = sample_bone(p_pos, ch_pos)
bone_sample.append(res)
if bone_sample:
bone_sample = np.concatenate(bone_sample, axis=0)
else:
bone_sample = np.empty((0, 3))
return bone_sample |