예제 #1
0
def rgb2lrgb(rgb: np.ndarray, *, rgbs: RgbSpecification = None) -> np.ndarray:
    """
    Convert companded RGB to linear RGB
    
    :param rgb: 
    :param rgbs: 
    :return: 
    """
    if rgbs is None:
        rgbs = get_default_rgb_specification()
    return rgbs.inverse_compand(rgb)
예제 #2
0
 def __init__(
         self,
         data: ArrayLike,
         *,
         axis: int = None,
         illuminant: Illuminant = get_default_illuminant(),
         observer: Observer = get_default_observer(),
         rgbs: RgbSpecification = get_default_rgb_specification(),
         caa:
     ChromaticAdaptationAlgorithm = get_default_chromatic_adaptation_algorithm(
     ),
         is_scaled: bool = False):
     """
     
     :param data: the color space data to contain
     :param axis: the axis along which the color data lies. If `axis` is not
        specified, then it will be determined automatically by finding the 
        last dimension with the required size.
     :param illuminant: the illuminant
     :param observer: the observer
     :param rgbs: the rgb specification
     :param caa: the chromatic adaptation algorithm
     :param is_scaled: Whether or not the data is scaled
     """
     if is_scaled:
         self._data = np.array(data, copy=True) / self.scale_factor
     else:
         self._data = np.array(data, copy=True)
     self._data.flags.writeable = False
     self._axis = (axis if axis is not None else get_matching_axis(
         self._data.shape, 3))
     self._illuminant = (illuminant if illuminant is not None else
                         get_default_illuminant())
     self._observer = (observer
                       if observer is not None else get_default_observer())
     self._rgbs = (rgbs
                   if rgbs is not None else get_default_rgb_specification())
     self._caa = (caa if caa is not None else
                  get_default_chromatic_adaptation_algorithm())
     self._is_scaled = is_scaled
예제 #3
0
def xyz2lrgb(xyz: np.ndarray,
             *,
             axis: int = None,
             illuminant: Illuminant = None,
             observer: Observer = None,
             rgbs: RgbSpecification = None,
             caa: ChromaticAdaptationAlgorithm = None) -> np.ndarray:
    """
    Convert XYZ to linear RGB
    
    :param xyz: 
    :param axis: 
    :param illuminant: 
    :param observer: 
    :param rgbs: 
    :param caa: 
    :return: 
    """
    if axis is None:
        axis = get_matching_axis(xyz.shape, 3)
    if illuminant is None:
        illuminant = get_default_illuminant()
    if observer is None:
        observer = get_default_observer()
    if rgbs is None:
        rgbs = get_default_rgb_specification()
    if caa is None:
        caa = get_default_chromatic_adaptation_algorithm()

    # If the white points are not equal, we will need to convert to the
    # RGB white point
    source_white_point = illuminant.get_white_point(observer)
    destination_white_point = rgbs.white_point
    if not np.allclose(
            source_white_point, destination_white_point, rtol=1e-5,
            atol=1e-14):
        xyz = xyz2xyz(xyz, source_white_point, destination_white_point, axis,
                      caa)

    # Get the XYZ values into the correct shape for matrix multiplication
    n_dims = xyz.ndim
    new_dims = list(range(n_dims))
    if axis != n_dims - 1:
        new_dims[-1] = axis
        new_dims[axis] = n_dims - 1
    xyz = xyz.transpose(new_dims)

    input_shape = xyz.shape
    xyz_is_not_matrix = xyz.ndim != 2
    if xyz_is_not_matrix:
        xyz = xyz.reshape((-1, 3))

    # Convert to linear RGB
    m = rgbs.linear_transformation
    lrgb = np.linalg.solve(m.T, xyz.T).T

    # Transform the destination data back to the original shape
    if xyz_is_not_matrix:
        lrgb = lrgb.reshape(input_shape)

    return lrgb.transpose(new_dims)
예제 #4
0
def lrgb2xyz(lrgb: np.ndarray,
             *,
             axis: int = None,
             illuminant: Illuminant = None,
             observer: Observer = None,
             rgbs: RgbSpecification = None,
             caa: ChromaticAdaptationAlgorithm = None) -> np.ndarray:
    """
    Convert from linear RGB to XYZ
    
    :param lrgb: 
    :param axis: 
    :param illuminant: 
    :param observer: 
    :param rgbs: 
    :param caa: 
    :return: 
    """
    if axis is None:
        axis = get_matching_axis(lrgb.shape, 3)
    if illuminant is None:
        illuminant = get_default_illuminant()
    if observer is None:
        observer = get_default_observer()
    if rgbs is None:
        rgbs = get_default_rgb_specification()
    if caa is None:
        caa = get_default_chromatic_adaptation_algorithm()

    # Get the XYZ values into the correct shape for matrix multiplication
    n_dims = lrgb.ndim
    new_dims = list(range(n_dims))
    if axis != n_dims - 1:
        new_dims[-1] = axis
        new_dims[axis] = n_dims - 1
    lrgb = lrgb.transpose(new_dims)

    input_shape = lrgb.shape
    lrgb_is_not_matrix = n_dims != 2
    if lrgb_is_not_matrix:
        lrgb = lrgb.reshape((-1, 3))

    # Do the transformation
    m = rgbs.linear_transformation
    xyz = lrgb.dot(m)

    # Transform back to the original shape
    if lrgb_is_not_matrix:
        xyz = xyz.reshape(input_shape)

    if axis != n_dims - 1:
        xyz = xyz.transpose(new_dims)

    source_white_point = rgbs.white_point
    destination_white_point = illuminant.get_white_point(observer)
    if not np.allclose(
            source_white_point, destination_white_point, rtol=1e-5,
            atol=1e-14):
        return xyz2xyz(xyz, source_white_point, destination_white_point, axis,
                       caa)
    else:
        return xyz