EasyMocap/myeasymocap/operations/merge.py
2023-06-19 16:39:27 +08:00

193 lines
7.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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}