Esempio n. 1
0
    def test_domain_range_scale_XYZ_to_CAM16(self):
        """
        Tests :func:`colour.appearance.cam16.XYZ_to_CAM16` 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 = CAM16_VIEWING_CONDITIONS['Average']
        specification = XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b, surround)[:-1]

        d_r = (
            ('reference', 1, 1),
            (1, 0.01, np.array([1, 1, 1 / 360, 1, 1, 1, 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_CAM16(XYZ * factor_a, XYZ_w * factor_a, L_A, Y_b,
                                 surround)[:-1],
                    specification * factor_b,
                    decimal=7)
Esempio n. 2
0
    def test_domain_range_scale_XYZ_to_CAM16(self):
        """
        Test :func:`colour.appearance.cam16.XYZ_to_CAM16` 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_CAM16["Average"]
        specification = XYZ_to_CAM16(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_CAM16(XYZ * factor_a, XYZ_w * factor_a, L_A, Y_b,
                                 surround),
                    as_float_array(specification) * factor_b,
                    decimal=7,
                )
Esempio n. 3
0
    def test_nan_XYZ_to_CAM16(self):
        """
        Tests :func:`colour.appearance.cam16.XYZ_to_CAM16` 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 = CAM16_InductionFactors(case[0], case[0], case[0])
            XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b, surround)
Esempio n. 4
0
    def test_n_dimensional_XYZ_to_CAM16(self):
        """
        Test :func:`colour.appearance.cam16.XYZ_to_CAM16` 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_CAM16["Average"]
        specification = XYZ_to_CAM16(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_CAM16(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_CAM16(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_CAM16(XYZ, XYZ_w, L_A, Y_b, surround),
            specification,
            decimal=7,
        )
Esempio n. 5
0
    def output_specification_from_data(self, data):
        """
        Returns the *CAM16* colour appearance model output specification from
        given data.

        Parameters
        ----------
        data : list
            Fixture data.

        Returns
        -------
        CAM16_Specification
            *CAM16* colour appearance model specification.
        """

        XYZ = tstack([data['X'], data['Y'], data['Z']])
        XYZ_w = tstack([data['X_w'], data['Y_w'], data['Z_w']])

        specification = XYZ_to_CAM16(
            XYZ, XYZ_w, data['L_A'], data['Y_b'],
            CAM16_InductionFactors(data['F'], data['c'], data['N_c']))

        return specification
Esempio n. 6
0
def XYZ_to_UCS_Li2017(XYZ: ArrayLike, coefficients: ArrayLike,
                      **kwargs: Any) -> NDArray:
    """
    Convert from *CIE XYZ* tristimulus values to one of the *Li et al. (2017)*
    *CAM16-LCD*, *CAM16-SCD*, or *CAM16-UCS* colourspaces :math:`J'a'b'` array.

    Parameters
    ----------
    XYZ
        *CIE XYZ* tristimulus values.
    coefficients
        Coefficients of one of the *Li et al. (2017)* *CAM16-LCD*, *CAM16-SCD*,
        or *CAM16-UCS* colourspaces.

    Other Parameters
    ----------------
    kwargs
        {:func:`colour.XYZ_to_CAM16`},
        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`
        *Li et al. (2017)* *CAM16-LCD*, *CAM16-SCD*, or *CAM16-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
    --------
    >>> import numpy as np
    >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
    >>> XYZ_to_UCS_Li2017(XYZ, COEFFICIENTS_UCS_LUO2006['CAM02-LCD'])
    ... # doctest: +ELLIPSIS
    array([ 46.0658603...,  41.0758649...,  14.5102582...])

    >>> from colour.appearance import CAM_KWARGS_CIECAM02_sRGB
    >>> XYZ_w = CAM_KWARGS_CIECAM02_sRGB['XYZ_w']
    >>> XYZ_to_UCS_Li2017(
    ...     XYZ, COEFFICIENTS_UCS_LUO2006['CAM02-LCD'], XYZ_w=XYZ_w / 100)
    ... # doctest: +ELLIPSIS
    array([ 46.0658603...,  41.0758649...,  14.5102582...])
    """

    from colour.appearance import CAM_KWARGS_CIECAM02_sRGB, XYZ_to_CAM16

    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_CAM16(XYZ, **settings)
    JMh = tstack([specification.J, specification.M, specification.h])

    return JMh_CAM16_to_UCS_Li2017(JMh, coefficients)
Esempio n. 7
0
    def test_XYZ_to_CAM16(self):
        """Test :func:`colour.appearance.cam16.XYZ_to_CAM16` definition."""

        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_CAM16["Average"]
        np.testing.assert_almost_equal(
            XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b, surround),
            np.array([
                41.73120791,
                0.10335574,
                217.06795977,
                2.34501507,
                195.37170899,
                0.10743677,
                275.59498615,
                np.nan,
            ]),
            decimal=7,
        )

        XYZ = np.array([57.06, 43.06, 31.96])
        L_A = 31.83
        np.testing.assert_almost_equal(
            XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b, surround),
            np.array([
                65.42828069,
                49.67956420,
                17.48659243,
                52.94308868,
                152.06985268,
                42.62473321,
                398.03047943,
                np.nan,
            ]),
            decimal=7,
        )

        XYZ = np.array([3.53, 6.56, 2.14])
        XYZ_w = np.array([109.85, 100, 35.58])
        L_A = 318.31
        np.testing.assert_almost_equal(
            XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b, surround),
            np.array([
                21.36052893,
                50.99381895,
                178.86724266,
                61.57953092,
                139.78582768,
                53.00732582,
                223.01823806,
                np.nan,
            ]),
            decimal=7,
        )

        XYZ = np.array([19.01, 20.00, 21.78])
        L_A = 318.31
        np.testing.assert_almost_equal(
            XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b, surround),
            np.array([
                41.36326063,
                52.81154022,
                258.88676291,
                53.12406914,
                194.52011798,
                54.89682038,
                311.24768647,
                np.nan,
            ]),
            decimal=7,
        )

        XYZ = np.array([61.45276998, 7.00421901, 82.2406738])
        XYZ_w = np.array([95.05, 100.00, 108.88])
        L_A = 4.074366543152521
        np.testing.assert_almost_equal(
            XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b, surround),
            np.array([
                21.03801957,
                457.78881613,
                350.06445098,
                241.50642846,
                56.74143988,
                330.94646237,
                376.43915877,
                np.nan,
            ]),
            decimal=7,
        )