| | 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: |
| | |
| | |
| | |
| | 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"] |
| | 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") |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| |
|
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| | |
| |
|