| 40 | |
| 41 | |
| 42 | class BackboneMidas(Backbone[BackboneMidasCfg]): |
| 43 | def __init__( |
| 44 | self, |
| 45 | cfg: BackboneMidasCfg, |
| 46 | num_frames: int | None, |
| 47 | image_shape: tuple[int, int] | None, |
| 48 | ) -> None: |
| 49 | super().__init__(cfg, num_frames=num_frames, image_shape=image_shape) |
| 50 | self.midas = torch.hub.load( |
| 51 | "intel-isl/MiDaS", |
| 52 | cfg.model, |
| 53 | pretrained=cfg.pretrained, |
| 54 | ) |
| 55 | self.midas_out = self.midas.scratch.output_conv |
| 56 | self.midas.scratch.output_conv = nn.Identity() |
| 57 | |
| 58 | # If a weight sensitivity is specified, don't learn weights. |
| 59 | if cfg.weight_sensitivity is None: |
| 60 | weight_channels = { |
| 61 | "DPT_Large": 256, |
| 62 | "MiDaS_small": 64, |
| 63 | }[cfg.model] |
| 64 | self.corr_weighter_perpoint = make_net([weight_channels * 2, 128, 64, 1]) |
| 65 | else: |
| 66 | weights = torch.full((num_frames - 1, *image_shape), 0, dtype=torch.float32) |
| 67 | self.weights = nn.Parameter(weights) |
| 68 | |
| 69 | if cfg.mapping == "exp": |
| 70 | self.midas_out = nn.Sequential(*self.midas_out[:-2]) |
| 71 | |
| 72 | def forward(self, batch: Batch, flows: Flows) -> BackboneOutput: |
| 73 | device = batch.videos.device |
| 74 | b, f, _, h, w = batch.videos.shape |
| 75 | |
| 76 | videos = rearrange(batch.videos, "b f c h w -> (b f) c h w") |
| 77 | features = self.midas(videos) |
| 78 | |
| 79 | # This matches Cameron's original implementation. |
| 80 | match self.cfg.mapping: |
| 81 | case "original": |
| 82 | depths = 1e3 / (self.midas_out(features) + 0.1) |
| 83 | case "exp": |
| 84 | depths = (self.midas_out(features) / 1000).exp() + 0.01 |
| 85 | |
| 86 | features = F.interpolate(features, (h, w), mode="bilinear") / 20 |
| 87 | |
| 88 | depths = rearrange(depths, "(b f) () h w -> b f h w", b=b, f=f) |
| 89 | features = rearrange(features, "(b f) c h w -> b f c h w", b=b, f=f) |
| 90 | |
| 91 | # Compute correspondence weights. |
| 92 | if self.cfg.weight_sensitivity is None: |
| 93 | xy, _ = sample_image_grid((h, w), device) |
| 94 | backward_weights = self.compute_correspondence_weights( |
| 95 | self.grid_sample_features(earlier(features), xy + flows.backward), |
| 96 | later(features), |
| 97 | ) |
| 98 | else: |
| 99 | backward_weights = (self.cfg.weight_sensitivity * self.weights).sigmoid() |
nothing calls this directly
no outgoing calls
no test coverage detected