def hsv_to_rgb(image: torch.Tensor) -> torch.Tensor: r"""Convert an HSV image to RGB The image data is assumed to be in the range of (0, 1). Args: input (torch.Tensor): HSV Image to be converted to RGB. Returns: torch.Tensor: RGB version of the image. """ if not torch.is_tensor(image): raise TypeError("Input type is not a torch.Tensor. Got {}".format( type(image))) if len(image.shape) < 3 or image.shape[-3] != 3: raise ValueError( "Input size must have a shape of (*, 3, H, W). Got {}".format( image.shape)) h: torch.Tensor = image[..., 0, :, :] / (2 * pi.to(image.device)) s: torch.Tensor = image[..., 1, :, :] v: torch.Tensor = image[..., 2, :, :] hi: torch.Tensor = torch.floor(h * 6) % 6 f: torch.Tensor = ((h * 6) % 6) - hi one: torch.Tensor = torch.tensor(1.).to(image.device) p: torch.Tensor = v * (one - s) q: torch.Tensor = v * (one - f * s) t: torch.Tensor = v * (one - (one - f) * s) hi = hi.long() indices: torch.Tensor = torch.stack([hi, hi + 6, hi + 12], dim=-3) out = torch.stack(( v, q, p, p, t, v, t, v, v, q, p, p, p, p, t, v, v, q, ), dim=-3) out = torch.gather(out, -3, indices) return out
def rgb_to_hsv(image: torch.Tensor) -> torch.Tensor: r"""Convert an RGB image to HSV. Args: input (torch.Tensor): RGB Image to be converted to HSV. Returns: torch.Tensor: HSV version of the image. """ if not torch.is_tensor(image): raise TypeError("Input type is not a torch.Tensor. Got {}".format( type(image))) if len(image.shape) < 3 or image.shape[-3] != 3: raise ValueError( "Input size must have a shape of (*, 3, H, W). Got {}".format( image.shape)) r: torch.Tensor = image[..., 0, :, :] g: torch.Tensor = image[..., 1, :, :] b: torch.Tensor = image[..., 2, :, :] maxc: torch.Tensor = image.max(-3)[0] minc: torch.Tensor = image.min(-3)[0] v: torch.Tensor = maxc # brightness deltac: torch.Tensor = maxc - minc s: torch.Tensor = deltac / v s[torch.isnan(s)] = 0. # avoid division by zero deltac = torch.where(deltac == 0, torch.ones_like(deltac), deltac) rc: torch.Tensor = (maxc - r) / deltac gc: torch.Tensor = (maxc - g) / deltac bc: torch.Tensor = (maxc - b) / deltac maxg: torch.Tensor = g == maxc maxr: torch.Tensor = r == maxc h: torch.Tensor = 4.0 + gc - rc h[maxg] = 2.0 + rc[maxg] - bc[maxg] h[maxr] = bc[maxr] - gc[maxr] h[minc == maxc] = 0.0 h = (h / 6.0) % 1.0 h = 2 * pi.to(image.device) * h return torch.stack([h, s, v], dim=-3)
def rgb_to_hls(image: torch.Tensor) -> torch.Tensor: r"""Convert an RGB image to HLS The image data is assumed to be in the range of (0, 1). Args: input (torch.Tensor): RGB Image to be converted to HLS. Returns: torch.Tensor: HLS version of the image. """ if not torch.is_tensor(image): raise TypeError("Input type is not a torch.Tensor. Got {}".format( type(image))) if len(image.shape) < 3 or image.shape[-3] != 3: raise ValueError( "Input size must have a shape of (*, 3, H, W). Got {}".format( image.shape)) r: torch.Tensor = image[..., 0, :, :] g: torch.Tensor = image[..., 1, :, :] b: torch.Tensor = image[..., 2, :, :] maxc: torch.Tensor = image.max(-3)[0] minc: torch.Tensor = image.min(-3)[0] imax: torch.Tensor = image.max(-3)[1] l: torch.Tensor = (maxc + minc) / 2 # luminance deltac: torch.Tensor = maxc - minc s: torch.Tensor = torch.where(l < 0.5, deltac / (maxc + minc), deltac / (torch.tensor(2.) - (maxc + minc))) # saturation hi: torch.Tensor = torch.zeros_like(deltac) hi[imax == 0] = (((g - b) / deltac) % 6)[imax == 0] hi[imax == 1] = (((b - r) / deltac) + 2)[imax == 1] hi[imax == 2] = (((r - g) / deltac) + 4)[imax == 2] h: torch.Tensor = 2. * pi.to( image.device) * (60. * hi) / 360. # hue [0, 2*pi] image_hls: torch.Tensor = torch.stack([h, l, s], dim=-3) image_hls[torch.isnan(image_hls)] = 0. return image_hls
def rgb_to_hsv(image: torch.Tensor) -> torch.Tensor: r"""Convert an RGB image to HSV. Args: input (torch.Tensor): RGB Image to be converted to HSV. Returns: torch.Tensor: HSV version of the image. """ if not torch.is_tensor(image): raise TypeError("Input type is not a torch.Tensor. Got {}".format( type(image))) if len(image.shape) < 3 or image.shape[-3] != 3: raise ValueError( "Input size must have a shape of (*, 3, H, W). Got {}".format( image.shape)) maxc, max_indices = image.max(-3) minc: torch.Tensor = image.min(-3)[0] v: torch.Tensor = maxc # brightness deltac: torch.Tensor = maxc - minc s: torch.Tensor = deltac / (v + 1e-31) # avoid division by zero deltac = torch.where(deltac == 0, torch.ones_like(deltac), deltac) rc, gc, bc = torch.unbind(maxc.unsqueeze(-3) - image, dim=-3) h = torch.stack([ bc - gc, 2.0 * deltac + rc - bc, 4.0 * deltac + gc - rc, ], dim=-3) h = torch.gather(h, dim=-3, index=max_indices[..., None, :, :]) h = h.squeeze(-3) h = h / deltac h = (h / 6.0) % 1.0 h = 2 * pi.to(image.device) * h return torch.stack([h, s, v], dim=-3)
def rad2deg(tensor: torch.Tensor) -> torch.Tensor: r"""Function that converts angles from radians to degrees. Args: tensor (torch.Tensor): Tensor of arbitrary shape. Returns: torch.Tensor: Tensor with same shape as input. Example: >>> input = torch.tensor(3.1415926535) * torch.rand(1, 3, 3) >>> output = rad2deg(input) """ if not isinstance(tensor, torch.Tensor): raise TypeError("Input type is not a torch.Tensor. Got {}".format(type(tensor))) return 180.0 * tensor / pi.to(tensor.device).type(tensor.dtype)
def hls_to_rgb(image: torch.Tensor) -> torch.Tensor: r"""Convert an HLS image to RGB The image data is assumed to be in the range of (0, 1). Args: input (torch.Tensor): HLS Image to be converted to RGB. Returns: torch.Tensor: RGB version of the image. """ if not torch.is_tensor(image): raise TypeError("Input type is not a torch.Tensor. Got {}".format( type(image))) if len(image.shape) < 3 or image.shape[-3] != 3: raise ValueError( "Input size must have a shape of (*, 3, H, W). Got {}".format( image.shape)) h: torch.Tensor = image[..., 0, :, :] * 360 / (2 * pi.to(image.device)) l: torch.Tensor = image[..., 1, :, :] s: torch.Tensor = image[..., 2, :, :] kr = (0 + h / 30) % 12 kg = (8 + h / 30) % 12 kb = (4 + h / 30) % 12 a = s * torch.min(l, torch.tensor(1.) - l) ones_k = torch.ones_like(kr) fr: torch.Tensor = l - a * torch.max( torch.min(torch.min(kr - torch.tensor(3.), torch.tensor(9.) - kr), ones_k), -1 * ones_k) fg: torch.Tensor = l - a * torch.max( torch.min(torch.min(kg - torch.tensor(3.), torch.tensor(9.) - kg), ones_k), -1 * ones_k) fb: torch.Tensor = l - a * torch.max( torch.min(torch.min(kb - torch.tensor(3.), torch.tensor(9.) - kb), ones_k), -1 * ones_k) out: torch.Tensor = torch.stack([fr, fg, fb], dim=-3) return out
def deg2rad(tensor: torch.Tensor) -> torch.Tensor: r"""Function that converts angles from degrees to radians. Args: tensor: Tensor of arbitrary shape. Returns: tensor with same shape as input. Examples: >>> input = 360. * torch.rand(1, 3, 3) >>> output = deg2rad(input) """ if not isinstance(tensor, torch.Tensor): raise TypeError("Input type is not a torch.Tensor. Got {}".format( type(tensor))) return tensor * pi.to(tensor.device).type(tensor.dtype) / 180.0
def deg2rad(tensor: torch.Tensor) -> torch.Tensor: r"""Function that converts angles from degrees to radians. Args: tensor: Tensor of arbitrary shape. Returns: tensor with same shape as input. Examples: >>> input = torch.tensor(180.) >>> deg2rad(input) tensor(3.1416) """ if not isinstance(tensor, torch.Tensor): raise TypeError(f"Input type is not a torch.Tensor. Got {type(tensor)}") return tensor * pi.to(tensor.device).type(tensor.dtype) / 180.0
def hsv_to_rgb(image: torch.Tensor) -> torch.Tensor: r"""Convert an HSV image to RGB The image data is assumed to be in the range of (0, 1). Args: input (torch.Tensor): HSV Image to be converted to RGB. Returns: torch.Tensor: RGB version of the image. """ if not torch.is_tensor(image): raise TypeError("Input type is not a torch.Tensor. Got {}".format( type(image))) if len(image.shape) < 3 or image.shape[-3] != 3: raise ValueError( "Input size must have a shape of (*, 3, H, W). Got {}".format( image.shape)) h: torch.Tensor = image[..., 0, :, :] / (2 * pi.to(image.device)) s: torch.Tensor = image[..., 1, :, :] v: torch.Tensor = image[..., 2, :, :] hi: torch.Tensor = torch.floor(h * 6) % 6 f: torch.Tensor = ((h * 6) % 6) - hi one: torch.Tensor = torch.tensor(1.).to(image.device) p: torch.Tensor = v * (one - s) q: torch.Tensor = v * (one - f * s) t: torch.Tensor = v * (one - (one - f) * s) out: torch.Tensor = torch.stack([hi, hi, hi], dim=-3) out[out == 0] = torch.stack((v, t, p), dim=-3)[out == 0] out[out == 1] = torch.stack((q, v, p), dim=-3)[out == 1] out[out == 2] = torch.stack((p, v, t), dim=-3)[out == 2] out[out == 3] = torch.stack((p, q, v), dim=-3)[out == 3] out[out == 4] = torch.stack((t, p, v), dim=-3)[out == 4] out[out == 5] = torch.stack((v, p, q), dim=-3)[out == 5] return out