def RGB_to_coefficients(self, RGB: ArrayLike) -> NDArray: """ Look up a given *RGB* colourspace array and return corresponding coefficients. Interpolation is used for colours not on the table grid. Parameters ---------- RGB *RGB* colourspace array. Returns ------- :class:`numpy.ndarray` Corresponding coefficients that can be passed to :func:`colour.recovery.jakob2019.sd_Jakob2019` to obtain a spectral distribution. Raises ------ RuntimeError If the pre-computed lookup table has not been generated or read. Examples -------- >>> from colour import MSDS_CMFS, SDS_ILLUMINANTS >>> from colour.models import RGB_COLOURSPACE_sRGB >>> cmfs = ( ... MSDS_CMFS['CIE 1931 2 Degree Standard Observer']. ... copy().align(SpectralShape(360, 780, 10)) ... ) >>> illuminant = SDS_ILLUMINANTS['D65'].copy().align(cmfs.shape) >>> LUT = LUT3D_Jakob2019() >>> LUT.generate( ... RGB_COLOURSPACE_sRGB, cmfs, illuminant, 3, lambda x: x) >>> RGB = np.array([0.70573936, 0.19248266, 0.22354169]) >>> LUT.RGB_to_coefficients(RGB) # doctest: +ELLIPSIS array([ 1.5013448...e-04, -1.4679754...e-01, 3.4020219...e+01]) """ if self._interpolator is not None: RGB = as_float_array(RGB) value_max = np.max(RGB, axis=-1) chroma = RGB / (value_max[..., np.newaxis] + 1e-10) i_m = np.argmax(RGB, axis=-1) i_1 = index_along_last_axis(RGB, i_m) i_2 = index_along_last_axis(chroma, (i_m + 2) % 3) i_3 = index_along_last_axis(chroma, (i_m + 1) % 3) indexes = np.stack([i_m, i_1, i_2, i_3], axis=-1) return self._interpolator(indexes).squeeze() else: raise RuntimeError( "The pre-computed lookup table has not been read or generated!" )
def test_compare_with_argmin_argmax(self): """ Tests :func:`colour.utilities.array.index_along_last_axis` definition by comparison with :func:`argmin` and :func:`argmax`. """ a = np.random.random((2, 3, 4, 5, 6, 7)) np.testing.assert_equal( index_along_last_axis(a, np.argmin(a, axis=-1)), np.min(a, axis=-1)) np.testing.assert_equal( index_along_last_axis(a, np.argmax(a, axis=-1)), np.max(a, axis=-1))
def test_index_along_last_axis(self): """ Tests :func:`colour.utilities.array.index_along_last_axis` definition. """ a = np.array([[[[0.51090627, 0.86191718, 0.8687926], [0.82738158, 0.80587656, 0.28285687]], [[0.84085977, 0.03851814, 0.06057988], [0.94659267, 0.79308353, 0.30870888]]], [[[0.50758436, 0.24066455, 0.20199051], [0.4507304, 0.84189245, 0.81160878]], [[0.75421871, 0.88187494, 0.01612045], [0.38777511, 0.58905552, 0.32970469]]], [[[0.99285824, 0.738076, 0.0716432], [0.35847844, 0.0367514, 0.18586322]], [[0.72674561, 0.0822759, 0.9771182], [0.90644279, 0.09689787, 0.93483977]]]]) indexes = np.array([[[0, 1], [0, 1]], [[2, 1], [2, 1]], [[2, 1], [2, 0]]]) np.testing.assert_equal( index_along_last_axis(a, indexes), np.array([[[0.51090627, 0.80587656], [0.84085977, 0.79308353]], [[0.20199051, 0.84189245], [0.01612045, 0.58905552]], [[0.0716432, 0.0367514], [0.9771182, 0.90644279]]]))
def RGB_to_coefficients(self, RGB): """ Look up a given *RGB* colourspace array and return corresponding coefficients. Interpolation is used for colours not on the table grid. Parameters ---------- RGB : ndarray, (3,) *RGB* colourspace array. Returns ------- coefficients : ndarray, (3,) Corresponding coefficients that can be passed to :func:`colour.recovery.jakob2019.sd_Jakob2019` to obtain a spectral distribution. Examples -------- >>> from colour.models import RGB_COLOURSPACE_sRGB >>> cmfs = MSDS_CMFS_STANDARD_OBSERVER[ ... 'CIE 1931 2 Degree Standard Observer'].copy().align( ... SpectralShape(360, 780, 10)) >>> illuminant = SDS_ILLUMINANTS['D65'].copy().align(cmfs.shape) >>> LUT = LUT3D_Jakob2019() >>> LUT.generate( ... RGB_COLOURSPACE_sRGB, cmfs, illuminant, 3, lambda x: x) >>> RGB = np.array([0.70573936, 0.19248266, 0.22354169]) >>> LUT.RGB_to_coefficients(RGB) # doctest: +ELLIPSIS array([ 1.5012557...e-04, -1.4678661...e-01, 3.4017293...e+01]) """ RGB = as_float_array(RGB) value_max = np.max(RGB, axis=-1) chroma = RGB / (np.expand_dims(value_max, -1) + 1e-10) i_m = np.argmax(RGB, axis=-1) i_1 = index_along_last_axis(RGB, i_m) i_2 = index_along_last_axis(chroma, (i_m + 2) % 3) i_3 = index_along_last_axis(chroma, (i_m + 1) % 3) indexes = np.stack([i_m, i_1, i_2, i_3], axis=-1) return self._interpolator(indexes).squeeze()
def test_exceptions(self): """ Tests :func:`colour.utilities.array.index_along_last_axis` definition handling of invalid inputs. """ a = as_float_array([[11, 12], [21, 22]]) # Bad shape with self.assertRaises(ValueError): indexes = np.array([0]) index_along_last_axis(a, indexes) # Indexes out of range with self.assertRaises(IndexError): indexes = np.array([123, 456]) index_along_last_axis(a, indexes) # Non-integer indexes with self.assertRaises(IndexError): indexes = np.array([0., 0.]) index_along_last_axis(a, indexes)