User-friendly inference function ### Parameters - `image`: input image tensor of shape (B, 3, H, W) or (3, H, W) - `num_tokens`: the number of base ViT tokens to use for inference, `'least'` or `'most'` or an integer. Suggested range: 1200 ~ 2500. More
(
self,
image: torch.Tensor,
num_tokens: int = None,
resolution_level: int = 9,
force_projection: bool = True,
apply_mask: Literal[False, True, 'blend'] = True,
fov_x: Optional[Union[Number, torch.Tensor]] = None,
use_fp16: bool = True,
)
| 180 | |
| 181 | @torch.inference_mode() |
| 182 | def infer( |
| 183 | self, |
| 184 | image: torch.Tensor, |
| 185 | num_tokens: int = None, |
| 186 | resolution_level: int = 9, |
| 187 | force_projection: bool = True, |
| 188 | apply_mask: Literal[False, True, 'blend'] = True, |
| 189 | fov_x: Optional[Union[Number, torch.Tensor]] = None, |
| 190 | use_fp16: bool = True, |
| 191 | ) -> Dict[str, torch.Tensor]: |
| 192 | """ |
| 193 | User-friendly inference function |
| 194 | |
| 195 | ### Parameters |
| 196 | - `image`: input image tensor of shape (B, 3, H, W) or (3, H, W) |
| 197 | - `num_tokens`: the number of base ViT tokens to use for inference, `'least'` or `'most'` or an integer. Suggested range: 1200 ~ 2500. |
| 198 | More tokens will result in significantly higher accuracy and finer details, but slower inference time. Default: `'most'`. |
| 199 | - `force_projection`: if True, the output point map will be computed using the actual depth map. Default: True |
| 200 | - `apply_mask`: if True, the output point map will be masked using the predicted mask. Default: True |
| 201 | - `fov_x`: the horizontal camera FoV in degrees. If None, it will be inferred from the predicted point map. Default: None |
| 202 | - `use_fp16`: if True, use mixed precision to speed up inference. Default: True |
| 203 | |
| 204 | ### Returns |
| 205 | |
| 206 | A dictionary containing the following keys: |
| 207 | - `points`: output tensor of shape (B, H, W, 3) or (H, W, 3). |
| 208 | - `depth`: tensor of shape (B, H, W) or (H, W) containing the depth map. |
| 209 | - `intrinsics`: tensor of shape (B, 3, 3) or (3, 3) containing the camera intrinsics. |
| 210 | """ |
| 211 | if image.dim() == 3: |
| 212 | omit_batch_dim = True |
| 213 | image = image.unsqueeze(0) |
| 214 | else: |
| 215 | omit_batch_dim = False |
| 216 | image = image.to(dtype=self.dtype, device=self.device) |
| 217 | |
| 218 | original_height, original_width = image.shape[-2:] |
| 219 | area = original_height * original_width |
| 220 | aspect_ratio = original_width / original_height |
| 221 | |
| 222 | # Determine the number of base tokens to use |
| 223 | if num_tokens is None: |
| 224 | min_tokens, max_tokens = self.num_tokens_range |
| 225 | num_tokens = int(min_tokens + (resolution_level / 9) * (max_tokens - min_tokens)) |
| 226 | |
| 227 | # Forward pass |
| 228 | with torch.autocast(device_type=self.device.type, dtype=torch.float16, enabled=use_fp16 and self.dtype != torch.float16): |
| 229 | output = self.forward(image, num_tokens=num_tokens) |
| 230 | points, normal, mask, metric_scale = (output.get(k, None) for k in ['points', 'normal', 'mask', 'metric_scale']) |
| 231 | |
| 232 | # Always process the output in fp32 precision |
| 233 | points, normal, mask, metric_scale, fov_x = map(lambda x: x.float() if isinstance(x, torch.Tensor) else x, [points, normal, mask, metric_scale, fov_x]) |
| 234 | with torch.autocast(device_type=self.device.type, dtype=torch.float32): |
| 235 | if mask is not None: |
| 236 | mask_binary = mask > 0.5 |
| 237 | else: |
| 238 | mask_binary = None |
| 239 |
no test coverage detected