Spaces:
Running on Zero
Running on Zero
| """Image and prediction resizing shared by evaluation and inference. | |
| The functions parse user-facing sizes, derive patch-compatible equal-area | |
| shapes, resize RGB tensors for a model, and restore depth or mask maps to the | |
| source resolution. Their return values retain the original image dimensions so | |
| camera-normalized geometry remains consistent after restoration. | |
| """ | |
| from typing import Optional, Tuple | |
| import torch | |
| import torch.nn.functional as F | |
| def parse_size(value: Optional[str]) -> Optional[Tuple[int, int]]: | |
| """Parse a CLI image-size string in ``WIDTHxHEIGHT`` notation. | |
| Args: | |
| value: Size string, or ``None``/empty text when no target is requested. | |
| Returns: | |
| Positive integer tuple ``(width, height)``, or ``None``. | |
| """ | |
| if value is None or not str(value).strip(): | |
| return None | |
| parts = str(value).lower().replace(",", "x").split("x") | |
| if len(parts) != 2: | |
| raise ValueError("Image size must be WIDTHxHEIGHT, for example 1022x770.") | |
| width, height = map(int, parts) | |
| if width <= 0 or height <= 0: | |
| raise ValueError("Image width and height must be positive.") | |
| return width, height | |
| def area_size( | |
| height: int, | |
| width: int, | |
| target_width: int, | |
| target_height: int, | |
| patch_size: int, | |
| ) -> Tuple[int, int]: | |
| """Preserve aspect ratio while matching a reference width-height area. | |
| Args: | |
| height: Original image height ``H``. | |
| width: Original image width ``W``. | |
| target_width: Width defining the desired reference area. | |
| target_height: Height defining the desired reference area. | |
| patch_size: Required divisibility of both output dimensions. | |
| Returns: | |
| Integer ``(new_height, new_width)`` with approximately | |
| ``target_width*target_height`` pixels and the original aspect ratio. | |
| """ | |
| area = int(target_width) * int(target_height) | |
| return area_size_from_area(height, width, area, patch_size) | |
| def area_size_from_area( | |
| height: int, | |
| width: int, | |
| target_area: int, | |
| patch_size: int, | |
| ) -> Tuple[int, int]: | |
| """Preserve aspect ratio while matching an explicit target pixel area. | |
| Args: | |
| height: Original image height ``H``. | |
| width: Original image width ``W``. | |
| target_area: Desired number of input pixels before patch rounding. | |
| patch_size: Required divisibility of both output dimensions. | |
| Returns: | |
| Integer ``(new_height, new_width)`` rounded to patch multiples. | |
| """ | |
| area = int(target_area) | |
| if height <= 0 or width <= 0 or area <= 0: | |
| raise ValueError("Image dimensions and target area must be positive.") | |
| aspect = width / height | |
| new_width = int(round((area * aspect) ** 0.5)) | |
| new_height = int(round(new_width / aspect)) | |
| new_width = max(patch_size, int(round(new_width / patch_size)) * patch_size) | |
| new_height = max(patch_size, int(round(new_height / patch_size)) * patch_size) | |
| return new_height, new_width | |
| def patch_size(height: int, width: int, patch: int) -> Tuple[int, int]: | |
| """Round spatial dimensions down to valid patch multiples. | |
| Args: | |
| height: Original image height. | |
| width: Original image width. | |
| patch: Positive encoder patch side length. | |
| Returns: | |
| Integer ``(new_height, new_width)``. Already divisible dimensions are | |
| unchanged; smaller results are clamped to one patch. | |
| """ | |
| new_height = height if height % patch == 0 else max(patch, height // patch * patch) | |
| new_width = width if width % patch == 0 else max(patch, width // patch * patch) | |
| return new_height, new_width | |
| def resize_image( | |
| image: torch.Tensor, | |
| target: Optional[Tuple[int, int]], | |
| resize_by_area: bool, | |
| patch: int, | |
| ) -> Tuple[torch.Tensor, Tuple[int, int]]: | |
| """Resize a CHW/BCHW image to the model input resolution. | |
| Args: | |
| image: RGB tensor ``[3,H,W]`` or ``[B,3,H,W]``. | |
| target: Optional ``(width,height)`` reference size. | |
| resize_by_area: Preserve aspect ratio and use only ``target`` area when | |
| ``True``; otherwise force the exact target dimensions. | |
| patch: Required encoder patch divisibility. | |
| Returns: | |
| resized: Bilinearly resized tensor preserving the input batch layout. | |
| original_size: Original integer tuple ``(H,W)``. | |
| """ | |
| original = tuple(image.shape[-2:]) | |
| if target is None: | |
| height, width = patch_size(*original, patch) | |
| elif resize_by_area: | |
| height, width = area_size(*original, target[0], target[1], patch) | |
| else: | |
| width, height = target | |
| if height % patch or width % patch: | |
| raise ValueError(f"Fixed input size {width}x{height} must be divisible by patch size {patch}.") | |
| if (height, width) == original: | |
| return image, original | |
| batched = image.ndim == 4 | |
| source = image if batched else image.unsqueeze(0) | |
| resized = F.interpolate(source, (height, width), mode="bilinear", align_corners=False) | |
| return (resized if batched else resized[0]), original | |
| def resize_map(value: torch.Tensor, size: Tuple[int, int], is_mask: bool = False) -> torch.Tensor: | |
| """Nearest-resize a depth/probability map while preserving batch layout. | |
| Args: | |
| value: Map tensor ``[H,W]`` or batch ``[B,H,W]``. | |
| size: Target ``(height,width)``. | |
| is_mask: Threshold resized values at ``0.5`` and return boolean output. | |
| Returns: | |
| Tensor ``[H_t,W_t]`` or ``[B,H_t,W_t]``. Non-mask output is floating; | |
| mask output is boolean. | |
| """ | |
| if tuple(value.shape[-2:]) == tuple(size): | |
| return value | |
| batched = value.ndim == 3 | |
| source = value.float().unsqueeze(1) if batched else value.float()[None, None] | |
| output = F.interpolate(source, size=size, mode="nearest") | |
| output = output[:, 0] if batched else output[0, 0] | |
| return output > 0.5 if is_mask else output | |