extract near-surface patches of a 3D shape using torch.unfold Args: voxels (torch.Tensor): a 3D shape volume of size (H, W, D) patch_size (int): patch size stride (int, optional): stride for overlapping. Defaults to None. If None, set as half patch size. Returns:
(voxels: torch.Tensor, patch_size: int, stride=None)
| 44 | |
| 45 | |
| 46 | def extract_valid_patches_unfold(voxels: torch.Tensor, patch_size: int, stride=None): |
| 47 | """extract near-surface patches of a 3D shape using torch.unfold |
| 48 | |
| 49 | Args: |
| 50 | voxels (torch.Tensor): a 3D shape volume of size (H, W, D) |
| 51 | patch_size (int): patch size |
| 52 | stride (int, optional): stride for overlapping. Defaults to None. If None, set as half patch size. |
| 53 | |
| 54 | Returns: |
| 55 | patches: size (N, patch_size, patch_size, patch_size) |
| 56 | """ |
| 57 | overlap = patch_size // 2 if stride is None else stride |
| 58 | |
| 59 | p = patch_size // 2 |
| 60 | voxels = F.pad(voxels, [p, p, p, p, p, p]) |
| 61 | patches = voxels.unfold(0, patch_size, overlap).unfold(1, patch_size, overlap).unfold(2, patch_size, overlap) |
| 62 | patches = patches.contiguous().view(-1, patch_size, patch_size, patch_size) # (k, ps, ps, ps) |
| 63 | |
| 64 | # valid patch criterion |
| 65 | # center region (l^3) has at least one occupied and one unoccupied voxel |
| 66 | idx = patch_size // 2 - 1 |
| 67 | l = 2 if patch_size % 2 == 0 else 3 |
| 68 | centers = patches[:, idx:idx+l, idx:idx+l, idx:idx+l] # (k, l, l, l) |
| 69 | mask_occ = torch.sum(centers.int(), dim=(1, 2, 3)) > 0 # (k,) |
| 70 | mask_unocc = torch.sum(centers.int(), dim=(1, 2, 3)) < l * l * l # (k,) |
| 71 | mask = torch.logical_and(mask_occ, mask_unocc) |
| 72 | |
| 73 | patches = patches[mask] |
| 74 | return patches |
| 75 | |
| 76 | |
| 77 | def eval_LP_IoU(gen_patches: torch.Tensor, ref_patches: torch.Tensor, threshold=0.95): |
no outgoing calls
no test coverage detected