Apply a mild corruption procedure that mimics the noise patterns observed in vision-based motion capture (small jitter, occasional temporal flicker). Args: ref_motion (Tensor): [B, T, C] reference motion (local joints + optional global orient). ref_motion_mask (Tensor):
(ref_motion,
ref_motion_mask,
corrupt_rate=0.1,
noise_scale=0.02,
replace_noise_rate=0.05,
dropout_rate=0.0,
temporal_dropout_rate=0.02,
is_test=False,
jitter_strength=0.3)
| 60 | |
| 61 | |
| 62 | def create_ref_motion(ref_motion, |
| 63 | ref_motion_mask, |
| 64 | corrupt_rate=0.1, |
| 65 | noise_scale=0.02, |
| 66 | replace_noise_rate=0.05, |
| 67 | dropout_rate=0.0, |
| 68 | temporal_dropout_rate=0.02, |
| 69 | is_test=False, |
| 70 | jitter_strength=0.3): |
| 71 | """ |
| 72 | Apply a mild corruption procedure that mimics the noise patterns observed in |
| 73 | vision-based motion capture (small jitter, occasional temporal flicker). |
| 74 | |
| 75 | Args: |
| 76 | ref_motion (Tensor): [B, T, C] reference motion (local joints + optional global orient). |
| 77 | ref_motion_mask (Tensor): [B, T] validity mask. |
| 78 | corrupt_rate (float): probability of applying Gaussian noise to a frame. |
| 79 | noise_scale (float): standard deviation of the Gaussian noise. |
| 80 | replace_noise_rate (float): probability of replacing a frame with a blend |
| 81 | of neighbouring frames (simulates short-term jitter). |
| 82 | dropout_rate (float): probability of dropping the entire reference for a sample. |
| 83 | Kept for API compatibility; defaults to 0. |
| 84 | temporal_dropout_rate (float): probability of masking small temporal spans. |
| 85 | is_test (bool): bypass corruption if True. |
| 86 | jitter_strength (float): controls the interpolation weight range when blending neighbours. |
| 87 | """ |
| 88 | if is_test: |
| 89 | return ref_motion, ref_motion_mask |
| 90 | |
| 91 | device = ref_motion.device |
| 92 | corrupt_rate = sample_from_range(corrupt_rate, device=device) |
| 93 | noise_scale = sample_from_range(noise_scale, device=device) |
| 94 | replace_noise_rate = sample_from_range(replace_noise_rate, device=device) |
| 95 | |
| 96 | B, T, C = ref_motion.shape |
| 97 | ref_motion_aug = ref_motion.clone() |
| 98 | mask = ref_motion_mask.clone() |
| 99 | valid_mask = mask.bool() |
| 100 | |
| 101 | if dropout_rate > 0: |
| 102 | drop_flags = torch.rand(B, device=device) < dropout_rate |
| 103 | if drop_flags.any(): |
| 104 | ref_motion_aug[drop_flags] = 0 |
| 105 | mask[drop_flags] = 0 |
| 106 | valid_mask = mask.bool() |
| 107 | |
| 108 | if noise_scale > 0 and corrupt_rate > 0: |
| 109 | frame_noise = torch.randn_like(ref_motion_aug) * noise_scale |
| 110 | apply_noise = (torch.rand(B, T, device=device) < corrupt_rate) & valid_mask |
| 111 | ref_motion_aug = ref_motion_aug + frame_noise * apply_noise.unsqueeze(-1) |
| 112 | |
| 113 | if replace_noise_rate > 0: |
| 114 | jitter_flags = (torch.rand(B, T, device=device) < replace_noise_rate) & valid_mask |
| 115 | if jitter_flags.any(): |
| 116 | base = ref_motion.clone() |
| 117 | prev = torch.roll(base, shifts=1, dims=1) |
| 118 | next = torch.roll(base, shifts=-1, dims=1) |
| 119 | prev_valid = torch.roll(valid_mask, shifts=1, dims=1) |
no test coverage detected