Source code for torchjpeg.dct._color

import torch
from torch import Tensor


[docs]def to_ycbcr(x: Tensor, data_range: float = 255) -> Tensor: r""" Converts a Tensor from RGB color space to YCbCr color space Parameters ---------- x : Tensor The input Tensor holding an RGB image in :math:`(\ldots, C, H ,W)` format (where :math:`\ldots` indicates an arbitrary number of dimensions). data_range : float The range of the input/output data. i.e., 255 indicates pixels in [0, 255], 1.0 indicates pixels in [0, 1]. Only 1.0 and 255 are supported. Returns ------- Tensor The YCbCr result of the same shape as the input and with the same data range. Note ----- This function implements the "full range" conversion used by JPEG, e.g. it does **not** implement the ITU-R BT.601 standard which many libraries (excluding PIL) use as the default definition of YCbCr. This conversion (for [0, 255]) is given by: .. math:: \begin{aligned} Y&=&0&+(0.299&\cdot R)&+(0.587&\cdot G)&+(0.114&\cdot B) \\ C_{B}&=&128&-(0.168736&\cdot R)&-(0.331264&\cdot G)&+(0.5&\cdot B) \\ C_{R}&=&128&+(0.5&\cdot R)&-(0.418688&\cdot G)&-(0.081312&\cdot B) \end{aligned} """ assert data_range in [1.0, 255] # fmt: off ycbcr_from_rgb = torch.tensor([ 0.29900, 0.58700, 0.11400, -0.168735892, -0.331264108, 0.50000, 0.50000, -0.418687589, -0.081312411 ], device=x.device).view(3, 3).transpose(0, 1) # fmt: on if data_range == 255: b = torch.tensor([0, 128, 128], device=x.device).view(3, 1, 1) else: b = torch.tensor([0, 0.5, 0.5], device=x.device).view(3, 1, 1) x = torch.einsum("cv,...cxy->...vxy", [ycbcr_from_rgb, x]) x += b return x.contiguous()
[docs]def to_rgb(x: Tensor, data_range: float = 255) -> Tensor: r""" Converts a Tensor from YCbCr color space to RGB color space Parameters ---------- x : Tensor The input Tensor holding a YCbCr image in :math:`(\ldots, C, H ,W)` format (where :math:`\ldots` indicates an arbitrary number of dimensions). data_range : float The range of the input/output data. i.e., 255 indicates pixels in [0, 255], 1.0 indicates pixels in [0, 1]. Only 1.0 and 255 are supported. Returns ------- Tensor The RGB result of the same shape as the input and with the same data range. Note ----- This function expects the input to be "full range" conversion used by JPEG, e.g. it does **not** implement the ITU-R BT.601 standard which many libraries (excluding PIL) use as the default definition of YCbCr. If the input came from this library or from PIL it should be fine. The conversion (for [0, 255]) is given by: .. math:: \begin{aligned} R&=&Y&&&+1.402&\cdot (C_{R}-128) \\ G&=&Y&-0.344136&\cdot (C_{B}-128)&-0.714136&\cdot (C_{R}-128 ) \\ B&=&Y&+1.772&\cdot (C_{B}-128)& \end{aligned} """ assert data_range in [1.0, 255] # fmt: off rgb_from_ycbcr = torch.tensor([ 1, 0, 1.40200, 1, -0.344136286, -0.714136286, 1, 1.77200, 0 ], device=x.device).view(3, 3).transpose(0, 1) # fmt: on if data_range == 255: b = torch.tensor([-179.456, 135.458816, -226.816], device=x.device).view(3, 1, 1) else: b = torch.tensor([-0.70374902, 0.531211043, -0.88947451], device=x.device).view(3, 1, 1) x = torch.einsum("cv,...cxy->...vxy", [rgb_from_ycbcr, x]) x += b return x.contiguous()