import time import torch import torch.nn.functional as F import numpy as np def get_gaussian_kernel_1d(kernel_size, sigma, device): x = torch.arange(kernel_size).float() - (kernel_size // 2) g = torch.exp(-((x ** 2) / (2 * sigma ** 2))) g /= g.sum() kernel_weight = g.view(1, 1, -1).to(device) return kernel_weight def gaussian_filter_1d(data, kernel_size=3, sigma=1.0, weight=None): kernel_weight = get_gaussian_kernel_1d(kernel_size, sigma, data.device) if weight is None else weight data = F.pad(data, (kernel_size // 2, kernel_size // 2), mode='replicate') return F.conv1d(data, kernel_weight) def exponential_smoothing(x, d_x, alpha=0.5): return d_x + alpha * (x - d_x) class OneEuroFilter: # param setting: # realtime v2m: min_cutoff=1.0, beta=1.5 # motionshop 2d keypoint: min_cutoff=1.7, beta=0.3 def __init__(self, min_cutoff=1.0, beta=0.0, sampling_rate=30, d_cutoff=1.0, device='cuda'): self.min_cutoff = min_cutoff self.beta = beta self.sampling_rate = sampling_rate self.x_prev = None self.dx_prev = None self.d_cutoff = d_cutoff self.pi = torch.tensor(torch.pi, device=device) def smoothing_factor(self, cutoff): r = 2 * self.pi * cutoff / self.sampling_rate return r/ (1 + r) def filter(self, x): if self.x_prev is None: self.x_prev = x self.dx_prev = torch.zeros_like(x) return x a_d = self.smoothing_factor(self.d_cutoff) # 计算当前的速度 dx = (x - self.x_prev) * self.sampling_rate dx_hat = exponential_smoothing(dx, self.dx_prev, a_d) cutoff = self.min_cutoff + self.beta * torch.abs(dx_hat) a = self.smoothing_factor(cutoff) x_hat = exponential_smoothing(x, self.x_prev, a) self.x_prev = x_hat self.dx_prev = dx_hat return x_hat class Filter(): filter_factory = { 'gaussian': get_gaussian_kernel_1d, } def __init__(self, target_data, filter_type, filter_args): self.target_data = target_data self.filter = self.filter_factory[filter_type] self.filter_args = filter_args def process(self, network_outputs): filter_data = [] for human in network_outputs: filter_data.append(human[self.target_data]) filter_data = torch.stack(filter_data, dim=0) filter_data = self.filter(filter_data, **self.filter_args) for i, human in enumerate(network_outputs): human[self.target_data] = filter_data[i] if __name__ == '__main__': import argparse import matplotlib.pyplot as plt import numpy as np from rot6d import rotation_6d_to_axis_angle, axis_angle_to_rotation_6d from humans import get_smplx_joint_names parser = argparse.ArgumentParser() parser.add_argument('--data_path', type=str) parser.add_argument('--save_path', type=str) parser.add_argument('--name', type=str) args = parser.parse_args() fig, axs = plt.subplots(nrows=2, ncols=2, figsize=(10, 8)) data_types = ['rotvec']#, 'j3d'] observe_keypoints = ['pelvis', 'head', 'left_wrist', 'left_knee'] joint_names = get_smplx_joint_names() data = np.load(f'{args.data_path}/shape_{args.name}.npy') fig, axs = plt.subplots(nrows=2, ncols=2, figsize=(10, 8)) for i in range(2): for j in range(2): x = data[:, i*4 + j*2] print(x.shape) axs[i, j].plot(x) axs[i, j].set_title(f'{4 * i + 2 * j}') axs[i, j].plot(np.load(f'{args.data_path}/dist_{args.name}.npy')) plt.tight_layout() plt.savefig(f'{args.save_path}/shape_{args.name}.jpg') # for data_type in data_types: # data = np.load(f'{args.data_path}/{data_type}_{args.name}.npy') # fig, axs = plt.subplots(nrows=2, ncols=2, figsize=(10, 8)) # for i in range(2): # for j in range(2): # # todo: something wrong here # filter = OneEuroFilter(min_cutoff=1, beta=0.01, sampling_rate=30, device='cuda:0') # x = data[:, joint_names.index(observe_keypoints[i*2+j])] #(F, 3) # print(x.shape) # x = axis_angle_to_rotation_6d(torch.tensor(x, device='cuda:0')) # x_filtered = x.clone() # start = time.time() # for k in range(x.shape[0]): # x_filtered[k] = filter.filter(x[k]) # print(x_filtered.shape[0]/(time.time()-start)) # # x_filtered = x.clone() # # a = 0.5 # # for k in range(1, x.shape[0]): # # x_filtered[k] = (1 - a) * x_filtered[k-1] + a * x[k] # #theta = np.linalg.norm(x, axis=-1) # #x = x / theta[..., None] # # f, n = x.shape # # x_filtered = gaussian_filter_1d(x.permute(1, 0).view(n, 1, -1), 11, 11) # # x_filtered = x_filtered.view(n, -1).permute(1, 0) # x = rotation_6d_to_axis_angle(x).cpu().numpy() # x_filtered = rotation_6d_to_axis_angle(x_filtered).cpu().numpy() # axs[i, j].plot(x[..., 0]) # axs[i, j].plot(x[..., 1]) # axs[i, j].plot(x[..., 2]) # axs[i, j].plot(x_filtered[..., 0]) # axs[i, j].plot(x_filtered[..., 1]) # axs[i, j].plot(x_filtered[..., 2]) # #axs[i, j].plot(theta) # axs[i, j].set_title(f'{observe_keypoints[i*2 + j]}') # plt.tight_layout() # plt.savefig(f'{args.save_path}/{data_type}_{args.name}.jpg')