138 lines
5.3 KiB
Python
138 lines
5.3 KiB
Python
from typing import Any
|
||
import numpy as np
|
||
|
||
class SmoothAny:
|
||
def __init__(self, window_size) -> None:
|
||
self.w = window_size
|
||
|
||
def __call__(self, value, with_conf=True):
|
||
wsize = self.w
|
||
value = value.copy()
|
||
if with_conf:
|
||
pos_sum = np.zeros_like(value[:-wsize, ..., :-1])
|
||
conf_sum = np.zeros_like(value[:-wsize, ..., -1:])
|
||
else:
|
||
pos_sum = np.zeros_like(value[:-wsize])
|
||
for w in range(wsize):
|
||
if with_conf:
|
||
pos_sum += value[w:w-wsize, ..., :-1] * value[w:w-wsize, ..., -1:]
|
||
conf_sum += value[w:w-wsize, ..., -1:]
|
||
else:
|
||
pos_sum += value[w:w-wsize]
|
||
if with_conf:
|
||
pos_smooth = pos_sum / (1e-5 + conf_sum)
|
||
value[wsize//2:-wsize//2] = np.dstack([pos_smooth, conf_sum])
|
||
else:
|
||
pos_smooth = pos_sum / (wsize)
|
||
value[wsize//2:-wsize//2] = pos_smooth
|
||
return value
|
||
|
||
class Smooth(SmoothAny):
|
||
def __call__(self, keypoints3d):
|
||
return {'keypoints3d': super().__call__(keypoints3d, with_conf=True)}
|
||
|
||
class SmoothPoses:
|
||
def __init__(self, window_size) -> None:
|
||
self.W = window_size
|
||
|
||
def __call__(self, params):
|
||
# TODO: 这个是使用了padding的
|
||
poses = params['poses']
|
||
padding_before = poses[:1].copy().repeat(self.W, 0)
|
||
padding_after = poses[-1:].copy().repeat(self.W, 0)
|
||
mean = poses.copy()
|
||
nFrames = mean.shape[0]
|
||
poses_full = np.vstack([padding_before, poses, padding_after])
|
||
for w in range(1, self.W+1):
|
||
mean += poses_full[self.W-w:self.W-w+nFrames]
|
||
mean += poses_full[self.W+w:self.W+w+nFrames]
|
||
mean /= 2*self.W + 1
|
||
params['poses'] = mean
|
||
return {'params': params}
|
||
|
||
class SmoothRealtime:
|
||
def __init__(self, opt_name, win_sizes) -> None:
|
||
# import cv2
|
||
self.size = {}
|
||
self.opt_name = opt_name
|
||
self.smdata={}
|
||
for idx, name in enumerate(opt_name):
|
||
self.smdata[name] = []
|
||
self.size[name] = win_sizes[idx]
|
||
def cvt_Rh_Rot(self, Rh):
|
||
import cv2
|
||
RotList = []
|
||
Rh = Rh.reshape((-1,3))
|
||
for i in range(Rh.shape[0]):
|
||
RotList.append(cv2.Rodrigues(Rh[i])[0])
|
||
return np.stack(RotList)
|
||
|
||
def cvt_Rot_Rh(self, Rot):
|
||
import cv2
|
||
RhList = []
|
||
for i in range(Rot.shape[0]):
|
||
RhList.append(cv2.Rodrigues(Rot[i])[0].reshape(3))
|
||
return np.stack(RhList).reshape((1,-1))
|
||
|
||
def now_smplh(self):
|
||
data={}
|
||
for name in self.opt_name:
|
||
# if name == 'Rh':
|
||
if name in ['Rh','poses']:
|
||
out = (sum(self.smdata[name])/len(self.smdata[name]))
|
||
data[name] = self.cvt_Rot_Rh(out)
|
||
else:
|
||
data[name] = (sum(self.smdata[name])/len(self.smdata[name]))
|
||
return data
|
||
def __call__(self, data):
|
||
# breakpoint()
|
||
for name in self.opt_name:
|
||
if name in ['Rh','poses']:
|
||
self.smdata[name].append(self.cvt_Rh_Rot(data[name].copy()))
|
||
if len(self.smdata[name])>self.size[name]:
|
||
self.smdata[name].pop(0)
|
||
out = (sum(self.smdata[name])/len(self.smdata[name]))
|
||
data[name] = self.cvt_Rot_Rh(out) #.reshape(1,self.smdata[key][0].shape[-1])
|
||
else:
|
||
self.smdata[name].append(data[name].copy())
|
||
if len(self.smdata[name])>self.size[name]:
|
||
self.smdata[name].pop(0)
|
||
data[name] = (sum(self.smdata[name])/len(self.smdata[name])) #.reshape(1,self.smdata[key][0].shape[-1])
|
||
return data
|
||
class SmoothHandlr:
|
||
def __init__(self, opt_name, win_sizes):
|
||
self.smooth_handl = SmoothRealtime(opt_name, win_sizes)
|
||
self.smooth_handr = SmoothRealtime(opt_name, win_sizes)
|
||
def __call__(self, params_l, params_r) -> Any:
|
||
params_l = self.smooth_handl(params_l)
|
||
params_r = self.smooth_handr(params_r)
|
||
return {'params_l': params_l, 'params_r': params_r}
|
||
|
||
class SmoothSmplh(SmoothRealtime):
|
||
def __init__(self, opt_name, win_sizes):
|
||
self.opt_name = opt_name
|
||
self.win_sizes = win_sizes
|
||
self.smooth_lists=[]
|
||
# self.smooth_smplh = SmoothRealtime(opt_name, win_sizes)
|
||
def __call__(self, params_smplh):
|
||
#TODO 应该根据id, 放入到对应的smooth列表中, 长久不在的要删除或者清空,之后把id作为输入,然后smoothlists换成map
|
||
bz = params_smplh['Rh'].shape[0]
|
||
while (len(self.smooth_lists)<bz):
|
||
self.smooth_lists.append(SmoothRealtime(self.opt_name, self.win_sizes))
|
||
for i in range(bz):
|
||
param={}
|
||
for key in params_smplh.keys():
|
||
param[key] = params_smplh[key][i].reshape(1,-1)
|
||
out = self.smooth_lists[i](param)
|
||
for key in params_smplh.keys():
|
||
params_smplh[key][i] = out[key]
|
||
# params_smplh = self.smooth_smplh(params_smplh)
|
||
return {'params_smplh': params_smplh}
|
||
|
||
class Smoothkeypoints3d(SmoothRealtime):
|
||
def __init__(self, opt_name, win_sizes):
|
||
self.smooth_smplh = SmoothRealtime(opt_name, win_sizes)
|
||
def __call__(self, keypoints3d):
|
||
ret = self.smooth_smplh({'keypoints3d':keypoints3d})
|
||
return ret
|
||
|