Download dvsm/models/pose_preprocessor.py from nvidia/DVSM: direct link, hf CLI and curl.
- Browser
- Download file 2.07 kB
-
https://huggingface.co/spaces/nvidia/DVSM/resolve/main/dvsm/models/pose_preprocessor.py
- Command line
-
hf download hf://spaces/nvidia/DVSM/dvsm/models/pose_preprocessor.py
-
curl -L -o pose_preprocessor.py https://huggingface.co/spaces/nvidia/DVSM/resolve/main/dvsm/models/pose_preprocessor.py
2.07 kB
| import torch | |
| class PosePreprocessor: | |
| def __init__(self, c2w_r, c2w_t, subset_idx=None, scale_factor=0.75): | |
| """ | |
| Compute a series of [offset -> scale -> rotation] for normalizing poses. | |
| c2w_r: [b, v, 3, 3] | |
| c2w_t: [b, v, 3] | |
| subset_idx: [v] or None. Use a subset of view to compute normalization. | |
| scale_factor: Rescale factor for the normalized camera | |
| """ | |
| assert len(c2w_r.shape) == 4 and c2w_r.shape[-2:] == (3, 3) | |
| assert len(c2w_t.shape) == 3 and c2w_t.shape[2] == 3 | |
| assert c2w_r.shape[:2] == c2w_t.shape[:2] | |
| # Compute SE(3) normalizing factor | |
| if subset_idx is not None: | |
| assert len(subset_idx.shape) == 1 and len(subset_idx) == c2w_r.shape[1] | |
| avg_t = c2w_t[:, subset_idx].mean(1) | |
| avg_r = compute_avg_rotation(c2w_r[:, subset_idx]) | |
| else: | |
| avg_t = c2w_t.mean(1) | |
| avg_r = compute_avg_rotation(c2w_r) | |
| # Target transformation for normalization | |
| self.r = avg_r.moveaxis(2,1).contiguous() | |
| self.t = (-self.r @ avg_t.unsqueeze(-1)).squeeze(-1).unsqueeze(1).contiguous() | |
| # Target scene rescaling | |
| new_t = torch.einsum('bij, bvj -> bvi', self.r, c2w_t) + self.t | |
| post_scale = new_t.abs().amax((1,2), keepdim=True) | |
| self.s = scale_factor / post_scale | |
| def __call__(self, c2w_r, c2w_t): | |
| c2w_r = torch.einsum('bij, bvjk -> bvik', self.r, c2w_r) | |
| c2w_t = torch.einsum('bij, bvj -> bvi', self.r, c2w_t) + self.t | |
| c2w_t = c2w_t * self.s | |
| return c2w_r, c2w_t | |
| def compute_avg_rotation(c2w_r): | |
| # c2w_r: [b, v, 3, 3] | |
| avg_down = torch.nn.functional.normalize(c2w_r[..., 1].mean(1), dim=-1) | |
| avg_forward = c2w_r[..., 2].mean(1) | |
| avg_right = torch.nn.functional.normalize(torch.cross(avg_down, avg_forward, dim=-1), dim=-1) | |
| avg_forward = torch.nn.functional.normalize(torch.cross(avg_right, avg_down, dim=-1), dim=-1) | |
| avg_r = torch.stack([avg_right, avg_down, avg_forward], dim=-1) | |
| return avg_r | |