def test_domain_range_scale_XYZ_to_CIECAM02(self): """ Tests :func:`colour.appearance.cam16.XYZ_to_CIECAM02` definition domain and range scale support. """ XYZ = np.array([19.01, 20.00, 21.78]) XYZ_w = np.array([95.05, 100.00, 108.88]) L_A = 318.31 Y_b = 20.0 surround = VIEWING_CONDITIONS_CIECAM02['Average'] specification = XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b, surround)[:-1] d_r = ( ('reference', 1, 1), (1, 0.01, np.array([ 1 / 100, 1 / 100, 1 / 360, 1 / 100, 1 / 100, 1 / 100, 1 / 360 ])), (100, 1, np.array([1, 1, 100 / 360, 1, 1, 1, 100 / 360])), ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): np.testing.assert_almost_equal(XYZ_to_CIECAM02( XYZ * factor_a, XYZ_w * factor_a, L_A, Y_b, surround)[:-1], specification * factor_b, decimal=7)
def output_specification_from_data(self, data): """ Returns the *CIECAM02* colour appearance model output specification from given data. Parameters ---------- data : list Fixture data. Returns ------- CIECAM02_Specification *CIECAM02* colour appearance model specification. """ XYZ = np.array([data['X'], data['Y'], data['Z']]) XYZ_w = np.array([data['X_w'], data['Y_w'], data['Z_w']]) specification = XYZ_to_CIECAM02(XYZ, XYZ_w, data['L_A'], data['Y_b'], CIECAM02_InductionFactors(data['F'], data['c'], data['N_c'])) return specification
def test_domain_range_scale_XYZ_to_CIECAM02(self): """ Test :func:`colour.appearance.ciecam02.XYZ_to_CIECAM02` definition domain and range scale support. """ XYZ = np.array([19.01, 20.00, 21.78]) XYZ_w = np.array([95.05, 100.00, 108.88]) L_A = 318.31 Y_b = 20 surround = VIEWING_CONDITIONS_CIECAM02["Average"] specification = XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b, surround) d_r = ( ("reference", 1, 1), ( "1", 0.01, np.array([ 1 / 100, 1 / 100, 1 / 360, 1 / 100, 1 / 100, 1 / 100, 1 / 400, np.nan, ]), ), ( "100", 1, np.array([1, 1, 100 / 360, 1, 1, 1, 100 / 400, np.nan]), ), ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): np.testing.assert_almost_equal( XYZ_to_CIECAM02(XYZ * factor_a, XYZ_w * factor_a, L_A, Y_b, surround), as_float_array(specification) * factor_b, decimal=7, )
def setUp(self): """Initialise the common tests attributes.""" XYZ = np.array([19.01, 20.00, 21.78]) XYZ_w = np.array([95.05, 100.00, 108.88]) L_A = 318.31 Y_b = 20.0 surround = VIEWING_CONDITIONS_CIECAM02["Average"] specification = XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b, surround) self._JMh = np.array( [specification.J, specification.M, specification.h])
def test_nan_XYZ_to_CIECAM02(self): """ Tests :func:`colour.appearance.ciecam02.XYZ_to_CIECAM02` definition nan support. """ cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan] cases = set(permutations(cases * 3, r=3)) for case in cases: XYZ = np.array(case) XYZ_w = np.array(case) L_A = case[0] Y_b = case[0] surround = InductionFactors_CIECAM02(case[0], case[0], case[0]) XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b, surround)
def test_n_dimensional_XYZ_to_CIECAM02(self): """ Test :func:`colour.appearance.ciecam02.XYZ_to_CIECAM02` definition n-dimensional support. """ XYZ = np.array([19.01, 20.00, 21.78]) XYZ_w = np.array([95.05, 100.00, 108.88]) L_A = 318.31 Y_b = 20 surround = VIEWING_CONDITIONS_CIECAM02["Average"] specification = XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b, surround) XYZ = np.tile(XYZ, (6, 1)) specification = np.tile(specification, (6, 1)) np.testing.assert_almost_equal( XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b, surround), specification, decimal=7, ) XYZ_w = np.tile(XYZ_w, (6, 1)) np.testing.assert_almost_equal( XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b, surround), specification, decimal=7, ) XYZ = np.reshape(XYZ, (2, 3, 3)) XYZ_w = np.reshape(XYZ_w, (2, 3, 3)) specification = np.reshape(specification, (2, 3, 8)) np.testing.assert_almost_equal( XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b, surround), specification, decimal=7, )
def tcs_colorimetry_data( sd_irradiance: SpectralDistribution, sds_tcs: MultiSpectralDistributions, cmfs: MultiSpectralDistributions, ) -> Tuple[TCS_ColorimetryData_CIE2017, ...]: """ Return the *test colour samples* colorimetry data under given test light source or reference illuminant spectral distribution for the *CIE 2017 Colour Fidelity Index* (CFI) computations. Parameters ---------- sd_irradiance Test light source or reference illuminant spectral distribution, i.e. the irradiance emitter. sds_tcs *Test colour samples* spectral distributions. cmfs Standard observer colour matching functions. Returns ------- :class:`tuple` *Test colour samples* colorimetry data under the given test light source or reference illuminant spectral distribution. Examples -------- >>> delta_E_to_R_f(4.4410383190) # doctest: +ELLIPSIS 70.1208254... """ XYZ_w = sd_to_XYZ(sd_ones(), cmfs, sd_irradiance) Y_b = 20 L_A = 100 surround = VIEWING_CONDITIONS_CIECAM02["Average"] tcs_data = [] for sd_tcs in sds_tcs.to_sds(): XYZ = sd_to_XYZ(sd_tcs, cmfs, sd_irradiance) CAM = XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b, surround, True) JMh = tstack([CAM.J, CAM.M, CAM.h]) Jpapbp = JMh_CIECAM02_to_CAM02UCS(JMh) tcs_data.append( TCS_ColorimetryData_CIE2017(sd_tcs.name, XYZ, CAM, JMh, Jpapbp)) return tuple(tcs_data)
def XYZ_to_UCS_Luo2006(XYZ: ArrayLike, coefficients: ArrayLike, **kwargs: Any) -> NDArray: """ Convert from *CIE XYZ* tristimulus values to one of the *Luo et al. (2006)* *CAM02-LCD*, *CAM02-SCD*, or *CAM02-UCS* colourspaces :math:`J'a'b'` array. Parameters ---------- XYZ *CIE XYZ* tristimulus values. coefficients Coefficients of one of the *Luo et al. (2006)* *CAM02-LCD*, *CAM02-SCD*, or *CAM02-UCS* colourspaces. Other Parameters ---------------- kwargs {:func:`colour.XYZ_to_CIECAM02`}, See the documentation of the previously listed definition. The default viewing conditions are that of *IEC 61966-2-1:1999*, i.e. *sRGB* 64 Lux ambient illumination, 80 :math:`cd/m^2`, adapting field luminance about 20% of a white object in the scene. Returns ------- :class:`numpy.ndarray` *Luo et al. (2006)* *CAM02-LCD*, *CAM02-SCD*, or *CAM02-UCS* colourspaces :math:`J'a'b'` array. Warnings -------- The ``XYZ_w`` parameter for :func:`colour.XYZ_to_CAM16` definition must be given in the same domain-range scale than the ``XYZ`` parameter. Notes ----- +------------+------------------------+------------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+========================+==================+ | ``XYZ`` | [0, 1] | [0, 1] | +------------+------------------------+------------------+ +------------+------------------------+------------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+========================+==================+ | ``Jpapbp`` | ``Jp`` : [0, 100] | ``Jp`` : [0, 1] | | | | | | | ``ap`` : [-100, 100] | ``ap`` : [-1, 1] | | | | | | | ``bp`` : [-100, 100] | ``bp`` : [-1, 1] | +------------+------------------------+------------------+ Examples -------- >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952]) >>> XYZ_to_UCS_Luo2006(XYZ, COEFFICIENTS_UCS_LUO2006['CAM02-LCD']) ... # doctest: +ELLIPSIS array([ 46.6138615..., 39.3576023..., 15.9673043...]) """ from colour.appearance import CAM_KWARGS_CIECAM02_sRGB, XYZ_to_CIECAM02 domain_range_reference = get_domain_range_scale() == "reference" settings = CAM_KWARGS_CIECAM02_sRGB.copy() settings.update(**kwargs) XYZ_w = kwargs.get("XYZ_w") if XYZ_w is not None and domain_range_reference: settings["XYZ_w"] = XYZ_w * 100 if domain_range_reference: XYZ = as_float_array(XYZ) * 100 specification = XYZ_to_CIECAM02(XYZ, **settings) JMh = tstack([specification.J, specification.M, specification.h]) return JMh_CIECAM02_to_UCS_Luo2006(JMh, coefficients)
def test_XYZ_to_CIECAM02(self): """ Test :func:`colour.appearance.ciecam02.XYZ_to_CIECAM02` definition. Notes ----- - The test values have been generated from data of the following file by *Fairchild (2013)*: http://rit-mcsl.org/fairchild//files/AppModEx.xls """ XYZ = np.array([19.01, 20.00, 21.78]) XYZ_w = np.array([95.05, 100.00, 108.88]) L_A = 318.31 Y_b = 20 surround = InductionFactors_CIECAM02(1, 0.69, 1) np.testing.assert_allclose( XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b, surround), np.array([41.73, 0.1, 219, 2.36, 195.37, 0.11, 278.1, np.nan]), rtol=0.01, atol=0.01, ) XYZ = np.array([57.06, 43.06, 31.96]) L_A = 31.83 np.testing.assert_allclose( XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b, surround), np.array([65.96, 48.57, 19.6, 52.25, 152.67, 41.67, 399.6, np.nan]), rtol=0.01, atol=0.01, ) XYZ = np.array([3.53, 6.56, 2.14]) XYZ_w = np.array([109.85, 100.00, 35.58]) L_A = 318.31 np.testing.assert_allclose( XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b, surround), np.array([21.79, 46.94, 177.1, 58.79, 141.17, 48.8, 220.4, np.nan]), rtol=0.01, atol=0.01, ) XYZ = np.array([19.01, 20.00, 21.78]) L_A = 31.83 np.testing.assert_allclose( XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b, surround), np.array( [42.53, 51.92, 248.9, 60.22, 122.83, 44.54, 305.8, np.nan]), rtol=0.01, atol=0.01, ) XYZ = np.array([61.45276998, 7.00421901, 82.24067384]) XYZ_w = np.array([95.05, 100, 108.88]) L_A = 4.074366543152521 np.testing.assert_allclose( XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b, surround), np.array([ 21.72630603341673, 411.5190338631848, 349.12875710099053, 227.15081998415593, 57.657243286322725, 297.49693233026602, 375.5788601911363, np.nan, ]), rtol=0.01, atol=0.01, )