MCPcopy Create free account
hub / github.com/NVlabs/InstantSplat / ManyAR_PatchEmbed

Class ManyAR_PatchEmbed

dust3r/patch_embed.py:32–70  ·  view source on GitHub ↗

Handle images with non-square aspect ratio. All images in the same batch have the same aspect ratio. true_shape = [(height, width) ...] indicates the actual shape of each image.

Source from the content-addressed store, hash-verified

30
31
32class ManyAR_PatchEmbed (PatchEmbed):
33 """ Handle images with non-square aspect ratio.
34 All images in the same batch have the same aspect ratio.
35 true_shape = [(height, width) ...] indicates the actual shape of each image.
36 """
37
38 def __init__(self, img_size=224, patch_size=16, in_chans=3, embed_dim=768, norm_layer=None, flatten=True):
39 self.embed_dim = embed_dim
40 super().__init__(img_size, patch_size, in_chans, embed_dim, norm_layer, flatten)
41
42 def forward(self, img, true_shape):
43 B, C, H, W = img.shape
44 assert W >= H, f'img should be in landscape mode, but got {W=} {H=}'
45 assert H % self.patch_size[0] == 0, f"Input image height ({H}) is not a multiple of patch size ({self.patch_size[0]})."
46 assert W % self.patch_size[1] == 0, f"Input image width ({W}) is not a multiple of patch size ({self.patch_size[1]})."
47 assert true_shape.shape == (B, 2), f"true_shape has the wrong shape={true_shape.shape}"
48
49 # size expressed in tokens
50 W //= self.patch_size[0]
51 H //= self.patch_size[1]
52 n_tokens = H * W
53
54 height, width = true_shape.T
55 is_landscape = (width >= height)
56 is_portrait = ~is_landscape
57
58 # allocate result
59 x = img.new_zeros((B, n_tokens, self.embed_dim))
60 pos = img.new_zeros((B, n_tokens, 2), dtype=torch.int64)
61
62 # linear projection, transposed if necessary
63 x[is_landscape] = self.proj(img[is_landscape]).permute(0, 2, 3, 1).flatten(1, 2).float()
64 x[is_portrait] = self.proj(img[is_portrait].swapaxes(-1, -2)).permute(0, 2, 3, 1).flatten(1, 2).float()
65
66 pos[is_landscape] = self.position_getter(1, H, W, pos.device)
67 pos[is_portrait] = self.position_getter(1, W, H, pos.device)
68
69 x = self.norm(x)
70 return x, pos

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected