193 lines
7.5 KiB
Python
193 lines
7.5 KiB
Python
|
import numpy as np
|
|||
|
import cv2
|
|||
|
import scipy
|
|||
|
import torch
|
|||
|
|
|||
|
class MultilView_Merge:
|
|||
|
def __init__(self) -> None:
|
|||
|
pass
|
|||
|
def forward(self, data,ax=0):
|
|||
|
'''
|
|||
|
data - dict
|
|||
|
data[key] (nv,...)
|
|||
|
'''
|
|||
|
results={}
|
|||
|
for key in data.keys():
|
|||
|
results[key] = data[key].mean(axis=ax)
|
|||
|
return results
|
|||
|
|
|||
|
|
|||
|
class Merge_hand(MultilView_Merge):
|
|||
|
def __init__(self, camtoworld) -> None:
|
|||
|
self.camtoworld = camtoworld
|
|||
|
# pass
|
|||
|
def __call__(self, posel , cameras, match3d_l):
|
|||
|
# ret = []
|
|||
|
# for nf in range(len(posel)):
|
|||
|
# breakpoint()
|
|||
|
hand_list=[]
|
|||
|
for pid in range(len(match3d_l)):
|
|||
|
dt = match3d_l[pid]
|
|||
|
if(isinstance(dt,int)):
|
|||
|
# TODO:处理-1的情况,也就是没有找到合适的匹配到的手
|
|||
|
hand_list.append(np.zeros((1,48)))
|
|||
|
break
|
|||
|
Merge_list=[]
|
|||
|
for cid in range(len(dt['views'])):
|
|||
|
nv = dt['views'][cid]
|
|||
|
poseid = dt['indices'][cid]
|
|||
|
pose = posel[nv][poseid].copy()
|
|||
|
|
|||
|
if self.camtoworld:
|
|||
|
Rh = pose[:,:3].copy()
|
|||
|
invR = np.linalg.inv(cameras['R'][nv])
|
|||
|
Rh_m_old = np.matrix(cv2.Rodrigues(Rh)[0])
|
|||
|
Rh_m_new = invR @ Rh_m_old
|
|||
|
Rh = cv2.Rodrigues(Rh_m_new)[0]
|
|||
|
Merge_list.append(np.hstack((Rh.reshape(3),pose[:,3:].reshape(-1))))
|
|||
|
else:
|
|||
|
Merge_list.append(pose)
|
|||
|
out = self.forward({'pose':np.stack(Merge_list)},0)
|
|||
|
|
|||
|
hand_list.append(out['pose'])
|
|||
|
pose_ = np.stack(hand_list)
|
|||
|
Rh = pose_[:,:3].copy()
|
|||
|
pose_[:,:3] = 0
|
|||
|
params={
|
|||
|
'Rh':Rh,
|
|||
|
'Th':np.zeros_like(Rh),
|
|||
|
'poses':pose_,
|
|||
|
'shapes':np.zeros((Rh.shape[0],10)),
|
|||
|
}
|
|||
|
# ret.append(params)
|
|||
|
return {'params': params}
|
|||
|
|
|||
|
class Merge_handlr(Merge_hand):
|
|||
|
def __call__(self, posel, poser, cameras, match3d_l, match3d_r):
|
|||
|
params_l = super().__call__(posel, cameras, match3d_l)
|
|||
|
params_r = super().__call__(poser, cameras, match3d_r)
|
|||
|
# breakpoint()
|
|||
|
return {'params_l':params_l['params'], 'params_r':params_r['params']}
|
|||
|
# return {'params_l':params_l['params'], 'params_r':params_r['params'], 'params':params_l['params']}
|
|||
|
|
|||
|
class Merge_bodyandhand:
|
|||
|
def __init__(self, tmp) -> None:
|
|||
|
pass
|
|||
|
def get_R(self, poses, cfg, st):
|
|||
|
res = st.copy()
|
|||
|
for i in cfg:
|
|||
|
res = res @ cv2.Rodrigues(poses[i,:])[0]
|
|||
|
return res
|
|||
|
def process_poses_mano(self, poses, hand_Rh, flag):
|
|||
|
if sum(flag) == 0:
|
|||
|
return poses
|
|||
|
|
|||
|
poses = poses.reshape((-1,3))
|
|||
|
cfg={'rt': [0,3,6,9],
|
|||
|
'r': [14,17,19],
|
|||
|
'l': [13,16,18]
|
|||
|
}
|
|||
|
RA = self.get_R(poses, cfg['rt'],np.eye(3))
|
|||
|
|
|||
|
if flag[0] :
|
|||
|
RL = self.get_R(poses, cfg['l'],RA)
|
|||
|
tmppose = np.matrix(RL).I @ cv2.Rodrigues(np.array(hand_Rh[0]))[0]
|
|||
|
tmppose = cv2.Rodrigues(tmppose)[0]
|
|||
|
poses[20,:] = tmppose.reshape(3)
|
|||
|
|
|||
|
e20 = scipy.spatial.transform.Rotation.from_rotvec(torch.from_numpy(poses[20,:]).reshape(-1,3))
|
|||
|
e20 = e20.as_euler('ZYX', degrees=True)
|
|||
|
|
|||
|
|
|||
|
dt = scipy.spatial.transform.Rotation.from_euler('ZYX', np.array([0,0,e20[0,2]/2]), degrees=True)
|
|||
|
rot_dt = dt.as_matrix()
|
|||
|
rot18 = cv2.Rodrigues(poses[18,:])[0]
|
|||
|
rot18 = rot18@rot_dt
|
|||
|
vec18 = cv2.Rodrigues(rot18)[0].reshape((1,3))
|
|||
|
rot20 = cv2.Rodrigues(poses[20,:])[0]
|
|||
|
rot20 = np.linalg.inv(rot_dt) @ rot20
|
|||
|
vec20 = cv2.Rodrigues(rot20)[0].reshape((1,3))
|
|||
|
poses[20,:] = vec20
|
|||
|
poses[18,:] = vec18
|
|||
|
|
|||
|
# e18 = scipy.spatial.transform.Rotation.from_rotvec(torch.from_numpy(poses[18,:]).reshape(-1,3))
|
|||
|
# e18 = e18.as_euler('ZYX', degrees=True)
|
|||
|
# e20[0,2] = e20[0,2]/2
|
|||
|
# e18[0,2] += e20[0,2]
|
|||
|
# e20 = scipy.spatial.transform.Rotation.from_euler('ZYX', e20, degrees=True)
|
|||
|
# e20 = e20.as_rotvec()
|
|||
|
# e18 = scipy.spatial.transform.Rotation.from_euler('ZYX', e18, degrees=True)
|
|||
|
# e18 = e18.as_rotvec()
|
|||
|
# poses[20,:] = e20
|
|||
|
# poses[18,:] = e18
|
|||
|
if flag[1] : #and sum(np.array(hand_Rh[1])!=0)>0:
|
|||
|
RR = self.get_R(poses, cfg['r'],RA)
|
|||
|
tmppose = np.matrix(RR).I @ cv2.Rodrigues(np.array(hand_Rh[1]))[0]
|
|||
|
tmppose = cv2.Rodrigues(tmppose)[0]
|
|||
|
poses[21,:] = tmppose.reshape(3)
|
|||
|
|
|||
|
e21 = scipy.spatial.transform.Rotation.from_rotvec(torch.from_numpy(poses[21,:]).reshape(-1,3))
|
|||
|
e21 = e21.as_euler('ZYX', degrees=True)
|
|||
|
|
|||
|
dt = scipy.spatial.transform.Rotation.from_euler('ZYX', np.array([0,0,e21[0,2]/2]), degrees=True)
|
|||
|
rot_dt = dt.as_matrix()
|
|||
|
rot19 = cv2.Rodrigues(poses[19,:])[0]
|
|||
|
rot19 = rot19@rot_dt
|
|||
|
vec19 = cv2.Rodrigues(rot19)[0].reshape((1,3))
|
|||
|
rot21 = cv2.Rodrigues(poses[21,:])[0]
|
|||
|
rot21 = np.linalg.inv(rot_dt) @ rot21
|
|||
|
vec21 = cv2.Rodrigues(rot21)[0].reshape((1,3))
|
|||
|
poses[21,:] = vec21
|
|||
|
poses[19,:] = vec19
|
|||
|
|
|||
|
# e19 = scipy.spatial.transform.Rotation.from_rotvec(torch.from_numpy(poses[19,:]).reshape(-1,3))
|
|||
|
# e19 = e19.as_euler('ZYX', degrees=True)
|
|||
|
# e21[0,2] = e21[0,2]/2
|
|||
|
# e19[0,2] += e21[0,2]
|
|||
|
# e21 = scipy.spatial.transform.Rotation.from_euler('ZYX', e21, degrees=True)
|
|||
|
# e21 = e21.as_rotvec()
|
|||
|
# e19 = scipy.spatial.transform.Rotation.from_euler('ZYX', e19, degrees=True)
|
|||
|
# e19 = e19.as_rotvec()
|
|||
|
# poses[21,:] = e21
|
|||
|
# poses[19,:] = e19
|
|||
|
|
|||
|
return poses.reshape((1,-1))
|
|||
|
|
|||
|
def merge_pose(self, bodypose,handlpose,handrpose):
|
|||
|
flag=[True,True]
|
|||
|
if abs(handlpose).sum()==0:
|
|||
|
flag[0]=False
|
|||
|
if abs(handrpose).sum()==0:
|
|||
|
flag[1]=False
|
|||
|
|
|||
|
out_L = []
|
|||
|
pose = np.hstack((bodypose,handlpose[:,3:],handrpose[:,3:])) # (1,156)
|
|||
|
out_pose = self.process_poses_mano(pose, [handlpose[0,:3],handrpose[0,:3]], flag) # 如果没找到手,那么应该设置为全0 这里设置为false
|
|||
|
out_L.append(out_pose)
|
|||
|
return out_pose
|
|||
|
def __call__(self, params_l, params_r, params):
|
|||
|
# breakpoint()
|
|||
|
bz = params['Rh'].shape[0]
|
|||
|
ret = {
|
|||
|
'Rh': np.zeros((bz,3),dtype=np.float32),
|
|||
|
'Th': params['Th'],
|
|||
|
'poses': np.zeros((bz,156),dtype=np.float32),
|
|||
|
'shapes':np.zeros((bz,16),dtype=np.float32)
|
|||
|
}
|
|||
|
ret['shapes'][:,:10] = params['shapes']
|
|||
|
# breakpoint()
|
|||
|
#TODO for nframe nperson
|
|||
|
for i in range(bz):
|
|||
|
inpose = np.zeros((1,66))
|
|||
|
inpose[:,3:] = params['poses'][i][:63].copy()
|
|||
|
inpose[:,:3] = params['Rh'][i].copy() # pose0:3有值 Rh 可能要合并
|
|||
|
|
|||
|
handlpose = params_l['poses'][i].reshape((1,-1)).copy()
|
|||
|
handrpose = params_r['poses'][i].reshape((1,-1)).copy()
|
|||
|
handlpose[:,:3] = params_l['Rh'][i]
|
|||
|
handrpose[:,:3] = params_r['Rh'][i]
|
|||
|
|
|||
|
out = self.merge_pose(inpose.reshape((1,-1)), handlpose, handrpose)
|
|||
|
ret['Rh'][i] = out[:,:3]
|
|||
|
ret['poses'][i,3:] = out[:,3:]
|
|||
|
return {'params_smplh': ret}
|