geoug / data /depth_encoding /scale_shift_transform.py
multimodalart's picture
multimodalart HF Staff
Upload folder using huggingface_hub
5e5d775 verified
Raw History Blame Contribute Delete
2.07 kB
import random
from PIL import Image
import cv2
import numpy as np
import torch
from torchvision import transforms
from torchvision.transforms import functional as F
from torchvision.transforms import InterpolationMode
from loguru import logger
class ScaleShiftDepthNormalizer():
"""
Use near and far plane to linearly normalize depth,
i.e. d' = d * s + t,
where near plane is mapped to `norm_min`, and far plane is mapped to `norm_max`
Near and far planes are determined by taking quantile values.
"""
is_absolute = False
far_plane_at_max = True
def __init__(
self, norm_min=-1.0, norm_max=1.0, min_max_quantile=0.02, clip=True
) -> None:
self.norm_min = norm_min
self.norm_max = norm_max
self.norm_range = self.norm_max - self.norm_min
self.min_quantile = min_max_quantile
self.max_quantile = 1.0 - self.min_quantile
self.clip = clip
def __call__(self, depth_linear, valid_mask=None, clip=None):
clip = clip if clip is not None else self.clip
if valid_mask is None:
valid_mask = torch.ones_like(depth_linear).bool()
valid_mask = valid_mask & (depth_linear > 0)
# Take quantiles as min and max
_min, _max = torch.quantile(
depth_linear[valid_mask],
torch.tensor([self.min_quantile, self.max_quantile]),
)
# scale and shift
depth_norm_linear = (depth_linear - _min) / (
_max - _min
) * self.norm_range + self.norm_min
if clip:
depth_norm_linear = torch.clip(
depth_norm_linear, self.norm_min, self.norm_max
)
return depth_norm_linear
def scale_back(self, depth_norm):
# scale to [0, 1]
depth_linear = (depth_norm - self.norm_min) / self.norm_range
return depth_linear
def denormalize(self, depth_norm, **kwargs):
logger.warning(f"{self.__class__} is not revertible without GT")
return self.scale_back(depth_norm=depth_norm)