Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
    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,
                )
Exemplo n.º 4
0
    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])
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
    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,
        )
Exemplo n.º 7
0
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)
Exemplo n.º 8
0
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)
Exemplo n.º 9
0
    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,
        )