Esempio n. 1
0
    def test_filter_kwargs(self):
        """
        Tests :func:`colour.utilities.common.filter_kwargs` definition.
        """

        def fn_a(a):
            """
            :func:`filter_kwargs` unit tests :func:`fn_a` definition.
            """
            return a

        def fn_b(a, b=0):
            """
            :func:`filter_kwargs` unit tests :func:`fn_b` definition.
            """

            return a, b

        def fn_c(a, b=0, c=0):
            """
            :func:`filter_kwargs` unit tests :func:`fn_c` definition.
            """

            return a, b, c

        self.assertEqual(1, fn_a(1, **filter_kwargs(fn_a, b=2, c=3)))

        self.assertTupleEqual((1, 2), fn_b(1, **filter_kwargs(fn_b, b=2, c=3)))

        self.assertTupleEqual((1, 2, 3),
                              fn_c(1, **filter_kwargs(fn_c, b=2, c=3)))
Esempio n. 2
0
    def test_filter_kwargs(self):
        """
        Tests :func:`colour.utilities.common.filter_kwargs` definition.
        """
        def fn_a(a):
            """
            :func:`filter_kwargs` unit tests :func:`fn_a`.
            """
            return a

        def fn_b(a, b=0):
            """
            :func:`filter_kwargs` unit tests :func:`fn_b`.
            """

            return a, b

        def fn_c(a, b=0, c=0):
            """
            :func:`filter_kwargs` unit tests :func:`fn_c`.
            """

            return a, b, c

        self.assertEqual(1, fn_a(1, **filter_kwargs(fn_a, b=2, c=3)))

        self.assertTupleEqual((1, 2), fn_b(1, **filter_kwargs(fn_b, b=2, c=3)))

        self.assertTupleEqual((1, 2, 3),
                              fn_c(1, **filter_kwargs(fn_c, b=2, c=3)))
Esempio n. 3
0
def eotf(value, function='sRGB', **kwargs):
    """
    Decodes :math:`R'G'B'` video component signal value to tristimulus values
    at the display using given electro-optical transfer function (EOTF / EOCF).

    Parameters
    ----------
    value : numeric or array_like
        Value.
    function : unicode, optional
        **{'sRGB', 'BT.1886', 'BT.2020', 'BT.709', 'DCI-P3', 'ROMM RGB',
        'ProPhoto RGB', 'RIMM RGB', 'ST 2084'}**,
        Computation function.

    Other Parameters
    ----------------
    L_B : numeric, optional
        {:func:`eotf_BT1886`},
        Screen luminance for black.
    L_W : numeric, optional
        {:func:`eotf_BT1886`},
        Screen luminance for white.
    is_12_bits_system : bool
        {:func:`eotf_BT2020`},
        *BT.709* *alpha* and *beta* constants are used if system is not 12-bit.
    I_max : numeric, optional
        {:func:`eotf_ROMMRGB`, :func:`eotf_RIMMRGB`},
        Maximum code value: 255, 4095 and 650535 for respectively 8-bit,
        12-bit and 16-bit per channel.
    E_clip : numeric, optional
        {:func:`eotf_RIMMRGB`},
        Maximum exposure level.
    L_p : numeric, optional
        {:func:`eotf_ST2084`},
        Display peak luminance :math:`cd/m^2`.

    Returns
    -------
    numeric or ndarray
        Tristimulus values at the display.

    Examples
    --------
    >>> eotf(0.461356129500442)  # doctest: +ELLIPSIS
    0.1...
    >>> eotf(0.409007728864150,
    ...     function='BT.2020')  # doctest: +ELLIPSIS
    0.1...
    >>> eotf(  # doctest: +ELLIPSIS
    ...     0.182011532850008, function='ST 2084', L_p=1000)
    0.1...
    """

    function = EOTFS[function]

    filter_kwargs(function, **kwargs)

    return function(value, **kwargs)
Esempio n. 4
0
def luminance(LV, method='CIE 1976', **kwargs):
    """
    Returns the *luminance* :math:`Y` of given *Lightness* :math:`L^*` or given
    *Munsell* value :math:`V`.

    Parameters
    ----------
    LV : numeric or array_like
        *Lightness* :math:`L^*` or *Munsell* value :math:`V`.
    method : unicode, optional
        **{'CIE 1976', 'Newhall 1943', 'ASTM D1535-08', 'Fairchild 2010'}**,
        Computation method.

    Other Parameters
    ----------------
    Y_n : numeric or array_like, optional
        {:func:`luminance_CIE1976`},
        White reference *luminance* :math:`Y_n`.
    epsilon : numeric or array_like, optional
        {:func:`lightness_Fairchild2010`},
        :math:`\epsilon` exponent.

    Returns
    -------
    numeric or array_like
        *luminance* :math:`Y`.

    Notes
    -----
    -   Input *LV* is in domain [0, 100], [0, 10] or [0, 1] and optional
        *luminance* :math:`Y_n` is in domain [0, 100].
    -   Output *luminance* :math:`Y` is in range [0, 100] or
        [0, math:`\infty`].

    Examples
    --------
    >>> luminance(37.98562910)  # doctest: +ELLIPSIS
    array(10.0800000...)
    >>> luminance(37.98562910, Y_n=100)  # doctest: +ELLIPSIS
    array(10.0800000...)
    >>> luminance(37.98562910, Y_n=95)  # doctest: +ELLIPSIS
    array(9.5760000...)
    >>> luminance(3.74629715, method='Newhall 1943')  # doctest: +ELLIPSIS
    10.4089874...
    >>> luminance(3.74629715, method='ASTM D1535-08')  # doctest: +ELLIPSIS
    10.1488096...
    >>> luminance(
    ...     24.902290269546651,
    ...     epsilon=1.836,
    ...     method='Fairchild 2010')  # doctest: +ELLIPSIS
    0.1007999...
    """

    function = LUMINANCE_METHODS[method]

    filter_kwargs(function, **kwargs)

    return function(LV, **kwargs)
Esempio n. 5
0
def delta_E(Lab_1, Lab_2, method='CMC', **kwargs):
    """
    Returns the difference :math:`\Delta E_{ab}` between two given *CIE Lab*
    colourspace arrays using given method.

    Parameters
    ----------
    Lab_1 : array_like
        *CIE Lab* colourspace array 1.
    Lab_2 : array_like
        *CIE Lab* colourspace array 2.
    method : unicode, optional
        **{'CMC', 'CIE 1976', 'CIE 1994', 'CIE 2000'}**,
        Computation method.

    Other Parameters
    ----------------
    textiles : bool, optional
        {:func:`delta_E_CIE1994`, :func:`delta_E_CIE2000`},
        Textiles application specific parametric factors
        :math:`k_L=2,\ k_C=k_H=1,\ k_1=0.048,\ k_2=0.014` weights are used
        instead of :math:`k_L=k_C=k_H=1,\ k_1=0.045,\ k_2=0.015`.
    l : numeric, optional
        {:func:`delta_E_CIE2000`},
        Lightness weighting factor.
    c : numeric, optional
        {:func:`delta_E_CIE2000`},
        Chroma weighting factor.

    Returns
    -------
    numeric or ndarray
        Colour difference :math:`\Delta E_{ab}`.

    Examples
    --------
    >>> Lab_1 = np.array([100.00000000, 21.57210357, 272.22819350])
    >>> Lab_2 = np.array([100.00000000, 426.67945353, 72.39590835])
    >>> delta_E(Lab_1, Lab_2)  # doctest: +ELLIPSIS
    172.7047712...
    >>> delta_E(Lab_1, Lab_2, method='CIE 1976')  # doctest: +ELLIPSIS
    451.7133019...
    >>> delta_E(Lab_1, Lab_2, method='CIE 1994')  # doctest: +ELLIPSIS
    83.7792255...
    >>> delta_E(  # doctest: +ELLIPSIS
    ...     Lab_1, Lab_2, method='CIE 1994', textiles=False)
    83.7792255...
    >>> delta_E(Lab_1, Lab_2, method='CIE 2000')  # doctest: +ELLIPSIS
    94.0356490...
    """

    function = DELTA_E_METHODS[method]

    filter_kwargs(function, **kwargs)

    return function(Lab_1, Lab_2, **kwargs)
Esempio n. 6
0
def lightness(Y, method='CIE 1976', **kwargs):
    """
    Returns the *Lightness* :math:`L` using given method.

    Parameters
    ----------
    Y : numeric or array_like
        *luminance* :math:`Y`.
    method : unicode, optional
        **{'CIE 1976', 'Glasser 1958', 'Wyszecki 1963', 'Fairchild 2010'}**,
        Computation method.

    Other Parameters
    ----------------
    Y_n : numeric or array_like, optional
        {:func:`lightness_CIE1976`},
        White reference *luminance* :math:`Y_n`.
    epsilon : numeric or array_like, optional
        {:func:`lightness_Fairchild2010`},
        :math:`\epsilon` exponent.

    Returns
    -------
    numeric or array_like
        *Lightness* :math:`L`.

    Notes
    -----
    -   Input *luminance* :math:`Y` and optional :math:`Y_n` are in domain
        [0, 100] or [0, :math:`\infty`].
    -   Output *Lightness* :math:`L` is in range [0, 100].

    Examples
    --------
    >>> lightness(10.08)  # doctest: +ELLIPSIS
    array(37.9856290...)
    >>> lightness(10.08, Y_n=100)  # doctest: +ELLIPSIS
    array(37.9856290...)
    >>> lightness(10.08, Y_n=95)  # doctest: +ELLIPSIS
    array(38.9165987...)
    >>> lightness(10.08, method='Glasser 1958')  # doctest: +ELLIPSIS
    36.2505626...
    >>> lightness(10.08, method='Wyszecki 1963')  # doctest: +ELLIPSIS
    37.0041149...
    >>> lightness(
    ...     10.08 / 100,
    ...     epsilon=1.836,
    ...     method='Fairchild 2010')  # doctest: +ELLIPSIS
    24.9022902...
    """

    function = LIGHTNESS_METHODS[method]

    filter_kwargs(function, **kwargs)

    return function(Y, **kwargs)
Esempio n. 7
0
def corresponding_chromaticities_prediction(experiment=1,
                                            model='Von Kries',
                                            **kwargs):
    """
    Returns the corresponding chromaticities prediction for given chromatic
    adaptation model.

    Parameters
    ----------
    experiment : integer, optional
        {1, 2, 3, 4, 6, 8, 9, 11, 12}
        *Breneman (1987)* experiment number.
    model : unicode, optional
        **{'Von Kries', 'CIE 1994', 'CMCCAT2000', 'Fairchild 1990'}**,
        Chromatic adaptation model.

    Other Parameters
    ----------------
    transform : unicode, optional
        {:func:`corresponding_chromaticities_prediction_VonKries`},
        **{'CAT02', 'XYZ Scaling', 'Von Kries', 'Bradford', 'Sharp',
        'Fairchild', 'CMCCAT97', 'CMCCAT2000', 'CAT02_BRILL_CAT', 'Bianco',
        'Bianco PC'}**,
        Chromatic adaptation transform.

    Returns
    -------
    tuple
        Corresponding chromaticities prediction.

    Examples
    --------
    >>> from pprint import pprint
    >>> pr = corresponding_chromaticities_prediction(2, 'CMCCAT2000')
    >>> pr = [(p.uvp_m, p.uvp_p) for p in pr]
    >>> pprint(pr)  # doctest: +SKIP
    [((0.207, 0.486), (0.2083210..., 0.4727168...)),
     ((0.449, 0.511), (0.4459270..., 0.5077735...)),
     ((0.263, 0.505), (0.2640262..., 0.4955361...)),
     ((0.322, 0.545), (0.3316884..., 0.5431580...)),
     ((0.316, 0.537), (0.3222624..., 0.5357624...)),
     ((0.265, 0.553), (0.2710705..., 0.5501997...)),
     ((0.221, 0.538), (0.2261826..., 0.5294740...)),
     ((0.135, 0.532), (0.1439693..., 0.5190984...)),
     ((0.145, 0.472), (0.1494835..., 0.4556760...)),
     ((0.163, 0.331), (0.1563172..., 0.3164151...)),
     ((0.176, 0.431), (0.1763199..., 0.4127589...)),
     ((0.244, 0.349), (0.2287638..., 0.3499324...))]
    """

    function = CORRESPONDING_CHROMATICITIES_PREDICTION_MODELS[model]

    filter_kwargs(function, **kwargs)

    return function(experiment, **kwargs)
Esempio n. 8
0
def uv_to_CCT(uv, method='Ohno 2013', **kwargs):
    """
    Returns the correlated colour temperature :math:`T_{cp}` and
    :math:`\Delta_{uv}` from given *CIE UCS* colourspace *uv* chromaticity
    coordinates using given method.

    Parameters
    ----------
    uv : array_like
        *CIE UCS* colourspace *uv* chromaticity coordinates.
    method : unicode, optional
        **{'Ohno 2013', 'Robertson 1968'}**,
        Computation method.

    Other Parameters
    ----------------
    cmfs : XYZ_ColourMatchingFunctions, optional
        {:func:`uv_to_CCT_Ohno2013`},
        Standard observer colour matching functions.
    start : numeric, optional
        {:func:`uv_to_CCT_Ohno2013`},
        Temperature range start in kelvins.
    end : numeric, optional
        {:func:`uv_to_CCT_Ohno2013`},
        Temperature range end in kelvins.
    count : int, optional
        {:func:`uv_to_CCT_Ohno2013`},
        Temperatures count in the planckian tables.
    iterations : int, optional
        {:func:`uv_to_CCT_Ohno2013`},
        Number of planckian tables to generate.

    Returns
    -------
    ndarray
        Correlated colour temperature :math:`T_{cp}`, :math:`\Delta_{uv}`.

    Examples
    --------
    >>> from colour import STANDARD_OBSERVERS_CMFS
    >>> cmfs = STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer']
    >>> uv = np.array([0.1978, 0.3122])
    >>> uv_to_CCT(uv, cmfs=cmfs)  # doctest: +ELLIPSIS
    array([  6.5075128...e+03,   3.2233587...e-03])
    """

    function = UV_TO_CCT_METHODS[method]

    filter_kwargs(function, **kwargs)

    return function(uv, **kwargs)
Esempio n. 9
0
def corresponding_chromaticities_prediction(experiment=1,
                                            model='Von Kries',
                                            **kwargs):
    """
    Returns the corresponding chromaticities prediction for given chromatic
    adaptation model.

    Parameters
    ----------
    experiment : integer, optional
        {1, 2, 3, 4, 6, 8, 9, 11, 12}
        Breneman (1987) experiment number.
    model : unicode, optional
        **{'Von Kries', 'CIE 1994', 'CMCCAT2000', 'Fairchild 1990'}**,
        Chromatic adaptation model.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    tuple
        Corresponding chromaticities prediction.

    Examples
    --------
    >>> from pprint import pprint
    >>> pr = corresponding_chromaticities_prediction(2, 'CMCCAT2000')
    >>> pr = [(p.uvp_m, p.uvp_p) for p in pr]
    >>> pprint(pr)  # doctest: +SKIP
    [((0.207, 0.486), (0.2083210..., 0.4727168...)),
     ((0.449, 0.511), (0.4459270..., 0.5077735...)),
     ((0.263, 0.505), (0.2640262..., 0.4955361...)),
     ((0.322, 0.545), (0.3316884..., 0.5431580...)),
     ((0.316, 0.537), (0.3222624..., 0.5357624...)),
     ((0.265, 0.553), (0.2710705..., 0.5501997...)),
     ((0.221, 0.538), (0.2261826..., 0.5294740...)),
     ((0.135, 0.532), (0.1439693..., 0.5190984...)),
     ((0.145, 0.472), (0.1494835..., 0.4556760...)),
     ((0.163, 0.331), (0.1563172..., 0.3164151...)),
     ((0.176, 0.431), (0.1763199..., 0.4127589...)),
     ((0.244, 0.349), (0.2287638..., 0.3499324...))]
    """

    function = CORRESPONDING_CHROMATICITIES_PREDICTION_MODELS[model]

    filter_kwargs(function, **kwargs)

    return function(experiment, **kwargs)
Esempio n. 10
0
def ootf(value, function='ITU-R BT.2100 PQ', **kwargs):
    """
    Maps relative scene linear light to display linear light using given
    opto-optical transfer function (OOTF / OOCF).

    Parameters
    ----------
    value : numeric or array_like
        Value.
    function : unicode, optional
        **{'ITU-R BT.2100 HLG', 'ITU-R BT.2100 PQ'}**
        Opto-optical transfer function (OOTF / OOCF).

    Returns
    -------
    numeric or ndarray
        Luminance of a displayed linear component.

    Examples
    --------
    >>> ootf(0.1)  # doctest: +ELLIPSIS
    779.9883608...
    >>> ootf(0.1, function='ITU-R BT.2100 HLG')  # doctest: +ELLIPSIS
    63.0957344...
    """

    function = OOTFS[function]

    return function(value, **filter_kwargs(function, **kwargs))
Esempio n. 11
0
def ootf(value, function='ITU-R BT.2100 PQ', **kwargs):
    """
    Maps relative scene linear light to display linear light using given
    opto-optical transfer function (OOTF / OOCF).

    Parameters
    ----------
    value : numeric or array_like
        Value.
    function : unicode, optional
        **{'ITU-R BT.2100 HLG', 'ITU-R BT.2100 PQ'}**
        Opto-optical transfer function (OOTF / OOCF).

    Returns
    -------
    numeric or ndarray
        Luminance of a displayed linear component.

    Examples
    --------
    >>> ootf(0.1)  # doctest: +ELLIPSIS
    779.9883608...
    >>> ootf(0.1, function='ITU-R BT.2100 HLG')  # doctest: +ELLIPSIS
    63.0957344...
    """

    function = OOTFS[function]

    return function(value, **filter_kwargs(function, **kwargs))
Esempio n. 12
0
def substrate_concentration_MichaelisMenten(
    v: FloatingOrArrayLike,
    V_max: FloatingOrArrayLike,
    K_m: FloatingOrArrayLike,
    method: Union[Literal["Michaelis 1913", "Abebe 2017"],
                  str] = "Michaelis 1913",
    **kwargs: Any,
) -> FloatingOrNDArray:
    """
    Describe the rate of enzymatic reactions, by relating concentration of a
    substrate :math:`S` to reaction rate :math:`v` according to given method.

    Parameters
    ----------
    v
        Reaction rate :math:`v`.
    V_max
        Maximum rate :math:`V_{max}` achieved by the system, at saturating
        substrate concentration.
    K_m
        Substrate concentration :math:`K_m` at which the reaction rate is
        half of :math:`V_{max}`.
    method
        Computation method.

    Other Parameters
    ----------------
    b_m
        {:func:`colour.biochemistry.\
substrate_concentration_MichaelisMenten_Abebe2017`},
        Bias factor :math:`b_m`.

    Returns
    -------
    :class:`numpy.floating` or :class:`numpy.ndarray`
        Concentration of a substrate :math:`S`.

    References
    ----------
    :cite:`Wikipedia2003d`, :cite:`Abebe2017a`

    Examples
    --------
    >>> substrate_concentration_MichaelisMenten(0.961538461538461, 2.5, 0.8)
    ... # doctest: +ELLIPSIS
    0.4999999...
    >>> substrate_concentration_MichaelisMenten(
    ... 1.036054703688355, 2.5, 0.8, method='Abebe 2017', b_m=0.813)
    ... # doctest: +ELLIPSIS
    0.5000000...
    """

    method = validate_method(method,
                             SUBSTRATE_CONCENTRATION_MICHAELISMENTEN_METHODS)

    function = SUBSTRATE_CONCENTRATION_MICHAELISMENTEN_METHODS[method]

    return function(v, V_max, K_m, **filter_kwargs(function, **kwargs))
Esempio n. 13
0
def oetf(value, function='sRGB', **kwargs):
    """
    Encodes estimated tristimulus values in a scene to :math:`R'G'B'` video
    component signal value using given opto-electronic transfer function
    (OETF / OECF).

    Parameters
    ----------
    value : numeric or array_like
        Value.
    function : unicode, optional
        **{'sRGB', 'ARIB STD-B67', 'DICOM GSDF', 'ITU-R BT.2020',
        'ITU-R BT.2100 HLG', 'ITU-R BT.2100 PQ', 'ITU-R BT.601',
        'ITU-R BT.709', 'ProPhoto RGB', 'RIMM RGB', 'ROMM RGB', 'SMPTE 240M',
        'ST 2084'}**,
        Opto-electronic transfer function (OETF / OECF).

    Other Parameters
    ----------------
    E_clip : numeric, optional
        {:func:`colour.models.oetf_RIMMRGB`},
        Maximum exposure level.
    I_max : numeric, optional
        {:func:`colour.models.oetf_ROMMRGB`,
        :func:`colour.models.oetf_RIMMRGB`},
        Maximum code value: 255, 4095 and 650535 for respectively 8-bit,
        12-bit and 16-bit per channel.
    L_p : numeric, optional
        {:func:`colour.models.oetf_ST2084`},
        Display peak luminance :math:`cd/m^2`.
    is_12_bits_system : bool
        {:func:`colour.models.oetf_BT2020`},
        *ITU-R BT.2020* *alpha* and *beta* constants are used
        if system is not
        12-bit.
    r : numeric, optional
        {:func:`colour.models.oetf_ARIBSTDB67`},
        Video level corresponding to reference white level.

    Returns
    -------
    numeric or ndarray
        :math:`R'G'B'` video component signal value.

    Examples
    --------
    >>> oetf(0.18)  # doctest: +ELLIPSIS
    0.4613561...
    >>> oetf(0.18, function='ITU-R BT.2020')  # doctest: +ELLIPSIS
    0.4090077...
    >>> oetf(0.18, function='ST 2084', L_p=1000)
    ... # doctest: +ELLIPSIS
    0.1820115...
    """

    function = OETFS[function]

    return function(value, **filter_kwargs(function, **kwargs))
Esempio n. 14
0
def eotf_inverse(value, function='ITU-R BT.1886', **kwargs):
    """
    Encodes estimated tristimulus values in a scene to :math:`R'G'B'` video
    component signal value using given inverse electro-optical transfer
    function (EOTF / EOCF).

    Parameters
    ----------
    value : numeric or array_like
        Value.
    function : unicode, optional
        **{'ITU-R BT.1886', 'DCDM', 'DICOM GSDF', 'ITU-R BT.2100 HLG',
        'ITU-R BT.2100 PQ', 'ST 2084', 'sRGB'}**,
        Inverse electro-optical transfer function (EOTF / EOCF).

    Other Parameters
    ----------------
    L_B : numeric, optional
        {:func:`colour.models.eotf_inverse_BT1886`,
        :func:`colour.models.eotf_inverse_HLG_BT2100`},
        Screen luminance for black.
    L_W : numeric, optional
        {:func:`colour.models.eotf_inverse_BT1886`,
        :func:`colour.models.eotf_inverse_HLG_BT2100`},
        Screen luminance for white.
    gamma : numeric, optional
        {:func:`colour.models.eotf_HLG_BT2100`},
        System gamma value, 1.2 at the nominal display peak luminance of
        :math:`1000 cd/m^2`.
    L_p : numeric, optional
        {:func:`colour.models.eotf_inverse_ST2084`},
        Display peak luminance :math:`cd/m^2`.
    method : unicode, optional
        {:func:`colour.models.eotf_inverse_HLG_BT2100`},
        **{'ITU-R BT.2100-1', 'ITU-R BT.2100-2'}**
    out_int : bool, optional
        {:func:`colour.models.eotf_inverse_DCDM`,
        :func:`colour.models.eotf_inverse_DICOMGSDF`},
        Whether to return value as integer code value or float equivalent of a
        code value at a given bit depth.

    Returns
    -------
    numeric or ndarray
        :math:`R'G'B'` video component signal value.

    Examples
    --------
    >>> eotf_inverse(0.11699185725296059)  # doctest: +ELLIPSIS
    0.4090077...
    >>> eotf_inverse(  # doctest: +ELLIPSIS
    ...     0.11699185725296059, function='ITU-R BT.1886')
    0.4090077...
    """

    function = EOTF_INVERSES[function]

    return function(value, **filter_kwargs(function, **kwargs))
Esempio n. 15
0
def oetf(value, function='sRGB', **kwargs):
    """
    Encodes estimated tristimulus values in a scene to :math:`R'G'B'` video
    component signal value using given opto-electronic transfer function
    (OETF / OECF).

    Parameters
    ----------
    value : numeric or array_like
        Value.
    function : unicode, optional
        **{'sRGB', 'ARIB STD-B67', 'DCDM', 'DICOM GSDF', 'ITU-R BT.2020',
        'ITU-R BT.2100 HLG', 'ITU-R BT.2100 PQ', 'ITU-R BT.601',
        'ITU-R BT.709', 'ProPhoto RGB', 'RIMM RGB', 'ROMM RGB', 'SMPTE 240M',
        'ST 2084'}**,
        Opto-electronic transfer function (OETF / OECF).

    Other Parameters
    ----------------
    E_clip : numeric, optional
        {:func:`colour.models.oetf_RIMMRGB`},
        Maximum exposure level.
    I_max : numeric, optional
        {:func:`colour.models.oetf_ROMMRGB`,
        :func:`colour.models.oetf_RIMMRGB`},
        Maximum code value: 255, 4095 and 650535 for respectively 8-bit,
        12-bit and 16-bit per channel.
    L_p : numeric, optional
        {:func:`colour.models.oetf_ST2084`},
        Display peak luminance :math:`cd/m^2`.
    is_12_bits_system : bool
        {:func:`colour.models.oetf_BT2020`},
        *ITU-R BT.2020* *alpha* and *beta* constants are used
        if system is not
        12-bit.
    r : numeric, optional
        {:func:`colour.models.oetf_ARIBSTDB67`},
        Video level corresponding to reference white level.

    Returns
    -------
    numeric or ndarray
        :math:`R'G'B'` video component signal value.

    Examples
    --------
    >>> oetf(0.18)  # doctest: +ELLIPSIS
    0.4613561...
    >>> oetf(0.18, function='ITU-R BT.2020')  # doctest: +ELLIPSIS
    0.4090077...
    >>> oetf(0.18, function='ST 2084', L_p=1000)
    ... # doctest: +ELLIPSIS
    0.1820115...
    """

    function = OETFS[function]

    return function(value, **filter_kwargs(function, **kwargs))
Esempio n. 16
0
def luminance(LV, method='CIE 1976', **kwargs):
    """
    Returns the *luminance* :math:`Y` of given *Lightness* :math:`L^*` or given
    *Munsell* value :math:`V`.

    Parameters
    ----------
    LV : numeric or array_like
        *Lightness* :math:`L^*` or *Munsell* value :math:`V`.
    method : unicode, optional
        **{'CIE 1976', 'Newhall 1943', 'ASTM D1535-08'}**,
        Computation method.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    numeric or array_like
        *luminance* :math:`Y`.

    Notes
    -----
    -   Input *LV* is in domain [0, 100] or [0, 10] and optional *luminance*
        :math:`Y_n` is in domain [0, 100].
    -   Output *luminance* :math:`Y` is in range [0, 100].

    Examples
    --------
    >>> luminance(37.98562910)  # doctest: +ELLIPSIS
    array(10.0800000...)
    >>> luminance(37.98562910, Y_n=100)  # doctest: +ELLIPSIS
    array(10.0800000...)
    >>> luminance(37.98562910, Y_n=95)  # doctest: +ELLIPSIS
    array(9.5760000...)
    >>> luminance(3.74629715, method='Newhall 1943')  # doctest: +ELLIPSIS
    10.4089874...
    >>> luminance(3.74629715, method='ASTM D1535-08')  # doctest: +ELLIPSIS
    10.1488096...
    """

    function = LUMINANCE_METHODS[method]

    filter_kwargs(function, **kwargs)

    return function(LV, **kwargs)
Esempio n. 17
0
def oetf_inverse(value: FloatingOrArrayLike,
                 function: Union[Literal["ARIB STD-B67",
                                         "Blackmagic Film Generation 5",
                                         "DaVinci Intermediate",
                                         "ITU-R BT.2100 HLG",
                                         "ITU-R BT.2100 PQ", "ITU-R BT.601",
                                         "ITU-R BT.709", ],
                                 str, ] = "ITU-R BT.709",
                 **kwargs: Any) -> FloatingOrNDArray:
    """
    Decode :math:`R'G'B'` video component signal value to tristimulus values
    at the display using given inverse opto-electronic transfer function
    (OETF).

    Parameters
    ----------
    value
        Value.
    function
        Inverse opto-electronic transfer function (OETF).

    Other Parameters
    ----------------
    kwargs
        {:func:`colour.models.oetf_inverse_ARIBSTDB67`,
        :func:`colour.models.oetf_inverse_BlackmagicFilmGeneration5`,
        :func:`colour.models.oetf_inverse_DaVinciIntermediate`,
        :func:`colour.models.oetf_inverse_HLG_BT2100`,
        :func:`colour.models.oetf_inverse_PQ_BT2100`,
        :func:`colour.models.oetf_inverse_BT601`,
        :func:`colour.models.oetf_inverse_BT709`},
        See the documentation of the previously listed definitions.


    Returns
    -------
    :class:`numpy.floating` or :class:`numpy.ndarray`
        Tristimulus values at the display.

    Examples
    --------
    >>> oetf_inverse(0.409007728864150)  # doctest: +ELLIPSIS
    0.1...
    >>> oetf_inverse(  # doctest: +ELLIPSIS
    ...     0.409007728864150, function='ITU-R BT.601')
    0.1...
    """

    function = validate_method(
        function,
        OETF_INVERSES,
        '"{0}" inverse "OETF" is invalid, it must be one of {1}!',
    )

    callable_ = OETF_INVERSES[function]

    return callable_(value, **filter_kwargs(callable_, **kwargs))
Esempio n. 18
0
def uv_to_CCT(uv, method='Ohno 2013', **kwargs):
    """
    Returns the correlated colour temperature :math:`T_{cp}` and
    :math:`\\Delta_{uv}` from given *CIE UCS* colourspace *uv* chromaticity
    coordinates using given method.

    Parameters
    ----------
    uv : array_like
        *CIE UCS* colourspace *uv* chromaticity coordinates.
    method : unicode, optional
        **{'Ohno 2013', 'Krystek 1985, 'Robertson 1968'}**,
        Computation method.

    Other Parameters
    ----------------
    cmfs : XYZ_ColourMatchingFunctions, optional
        {:func:`colour.temperature.uv_to_CCT_Ohno2013`},
        Standard observer colour matching functions.
    start : numeric, optional
        {:func:`colour.temperature.uv_to_CCT_Ohno2013`},
        Temperature range start in kelvins.
    end : numeric, optional
        {:func:`colour.temperature.uv_to_CCT_Ohno2013`},
        Temperature range end in kelvins.
    count : int, optional
        {:func:`colour.temperature.uv_to_CCT_Ohno2013`},
        Temperatures count in the planckian tables.
    iterations : int, optional
        {:func:`colour.temperature.uv_to_CCT_Ohno2013`},
        Number of planckian tables to generate.
    optimisation_kwargs : dict_like, optional
        {:func:`colour.temperature.uv_to_CCT_Krystek1985`},
        Parameters for :func:`scipy.optimize.minimize` definition.

    Returns
    -------
    ndarray
        Correlated colour temperature :math:`T_{cp}`, :math:`\\Delta_{uv}`.

    References
    ----------
    :cite:`AdobeSystems2013`, :cite:`AdobeSystems2013a`, :cite:`Krystek1985b`,
    :cite:`Ohno2014a`, :cite:`Wyszecki2000y`

    Examples
    --------
    >>> import numpy as np
    >>> uv = np.array([0.1978, 0.3122])
    >>> # Doctests skipping for Python 2.x compatibility.
    >>> uv_to_CCT(uv)  # doctest: +SKIP
    array([  6.5074738...e+03,   3.2233460...e-03])
    """

    function = UV_TO_CCT_METHODS[method]

    return function(uv, **filter_kwargs(function, **kwargs))
Esempio n. 19
0
def lightness(Y, method='CIE 1976', **kwargs):
    """
    Returns the *Lightness* :math:`L^*` using given method.

    Parameters
    ----------
    Y : numeric or array_like
        *luminance* :math:`Y`.
    method : unicode, optional
        **{'CIE 1976', 'Glasser 1958', 'Wyszecki 1963'}**,
        Computation method.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    numeric or array_like
        *Lightness* :math:`L^*`.

    Notes
    -----
    -   Input *luminance* :math:`Y` and optional :math:`Y_n` are in domain
        [0, 100].
    -   Output *Lightness* :math:`L^*` is in range [0, 100].

    Examples
    --------
    >>> lightness(10.08)  # doctest: +ELLIPSIS
    array(37.9856290...)
    >>> lightness(10.08, Y_n=100)  # doctest: +ELLIPSIS
    array(37.9856290...)
    >>> lightness(10.08, Y_n=95)  # doctest: +ELLIPSIS
    array(38.9165987...)
    >>> lightness(10.08, method='Glasser 1958')  # doctest: +ELLIPSIS
    36.2505626...
    >>> lightness(10.08, method='Wyszecki 1963')  # doctest: +ELLIPSIS
    37.0041149...
    """

    function = LIGHTNESS_METHODS[method]

    filter_kwargs(function, **kwargs)

    return function(Y, **kwargs)
Esempio n. 20
0
def delta_E(Lab_1, Lab_2, method='CMC', **kwargs):
    """
    Returns the difference :math:`\Delta E_{ab}` between two given *CIE Lab*
    colourspace arrays using given method.

    Parameters
    ----------
    Lab_1 : array_like
        *CIE Lab* colourspace array 1.
    Lab_2 : array_like
        *CIE Lab* colourspace array 2.
    method : unicode, optional
        **{'CMC', 'CIE 1976', 'CIE 1994', 'CIE 2000'}**,
        Computation method.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    numeric or ndarray
        Colour difference :math:`\Delta E_{ab}`.

    Examples
    --------
    >>> Lab_1 = np.array([100.00000000, 21.57210357, 272.22819350])
    >>> Lab_2 = np.array([100.00000000, 426.67945353, 72.39590835])
    >>> delta_E(Lab_1, Lab_2)  # doctest: +ELLIPSIS
    172.7047712...
    >>> delta_E(Lab_1, Lab_2, method='CIE 1976')  # doctest: +ELLIPSIS
    451.7133019...
    >>> delta_E(Lab_1, Lab_2, method='CIE 1994')  # doctest: +ELLIPSIS
    83.7792255...
    >>> delta_E(  # doctest: +ELLIPSIS
    ...     Lab_1, Lab_2, method='CIE 1994', textiles=False)
    83.7792255...
    >>> delta_E(Lab_1, Lab_2, method='CIE 2000')  # doctest: +ELLIPSIS
    94.0356490...
    """

    function = DELTA_E_METHODS[method]

    filter_kwargs(function, **kwargs)

    return function(Lab_1, Lab_2, **kwargs)
Esempio n. 21
0
def delta_E(Lab_1, Lab_2, method='CMC', **kwargs):
    """
    Returns the difference :math:`\Delta E_{ab}` between two given *CIE Lab*
    colourspace arrays using given method.

    Parameters
    ----------
    Lab_1 : array_like
        *CIE Lab* colourspace array 1.
    Lab_2 : array_like
        *CIE Lab* colourspace array 2.
    method : unicode, optional
        **{'CMC', 'CIE 1976', 'CIE 1994', 'CIE 2000'}**,
        Computation method.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    numeric or ndarray
        Colour difference :math:`\Delta E_{ab}`.

    Examples
    --------
    >>> Lab_1 = np.array([100.00000000, 21.57210357, 272.22819350])
    >>> Lab_2 = np.array([100.00000000, 426.67945353, 72.39590835])
    >>> delta_E(Lab_1, Lab_2)  # doctest: +ELLIPSIS
    172.7047712...
    >>> delta_E(Lab_1, Lab_2, method='CIE 1976')  # doctest: +ELLIPSIS
    451.7133019...
    >>> delta_E(Lab_1, Lab_2, method='CIE 1994')  # doctest: +ELLIPSIS
    83.7792255...
    >>> delta_E(  # doctest: +ELLIPSIS
    ...     Lab_1, Lab_2, method='CIE 1994', textiles=False)
    83.7792255...
    >>> delta_E(Lab_1, Lab_2, method='CIE 2000')  # doctest: +ELLIPSIS
    94.0356490...
    """

    function = DELTA_E_METHODS[method]

    filter_kwargs(function, **kwargs)

    return function(Lab_1, Lab_2, **kwargs)
Esempio n. 22
0
def cctf_decoding(value, function='sRGB', **kwargs):
    """
    Decodes non-linear :math:`R'G'B'` values to linear :math:`RGB` values using
    given decoding colour component transfer function (Decoding CCTF).

    Parameters
    ----------
    value : numeric or array_like
        Non-linear :math:`R'G'B'` values.
    function : unicode, optional
        {:attr:`colour.CCTF_DECODINGS`},
        Computation function.

    Other Parameters
    ----------------
    \\**kwargs : dict, optional
        Keywords arguments for the relevant decoding CCTF of the
        :attr:`colour.CCTF_DECODINGS` attribute collection.

    Warnings
    --------
    For *ITU-R BT.2100*, only the electro-optical transfer functions
    (EOTFs / EOCFs) are exposed by this definition, please refer to the
    :func:`colour.oetf_inverse` definition for the inverse opto-electronic
    transfer functions (OETF / OECF).

    Returns
    -------
    numeric or ndarray
        Linear :math:`RGB` values.

    Examples
    --------
    >>> cctf_decoding(0.391006842619746, function='PLog', log_reference=400)
    ... # doctest: +ELLIPSIS
    0.1...
    >>> cctf_decoding(0.182011532850008, function='ST 2084', L_p=1000)
    ... # doctest: +ELLIPSIS
    0.1...
    >>> cctf_decoding(  # doctest: +ELLIPSIS
    ...     0.461356129500442, function='ITU-R BT.1886')
    0.1...
    """

    if 'itu-r bt.2100' in function.lower():
        usage_warning(
            'With the "ITU-R BT.2100" method, only the electro-optical '
            'transfer functions (EOTFs / EOCFs) are exposed by this '
            'definition, please refer to the "colour.oetf_inverse" definition '
            'for the inverse opto-electronic transfer functions (OETF / OECF).'
        )

    function = CCTF_DECODINGS[function]

    return function(value, **filter_kwargs(function, **kwargs))
Esempio n. 23
0
def polynomial_expansion(
    a: ArrayLike,
    method: Union[Literal["Cheung 2004", "Finlayson 2015", "Vandermonde"],
                  str] = "Cheung 2004",
    **kwargs: Any,
) -> NDArray:
    """
    Perform polynomial expansion of given :math:`a` array.

    Parameters
    ----------
    a
        :math:`a` array to expand.
    method
        Computation method.

    Other Parameters
    ----------------
    degree
        {:func:`colour.characterisation.polynomial_expansion_Finlayson2015`,
        :func:`colour.characterisation.polynomial_expansion_Vandermonde`},
        Expanded polynomial degree, must be one of *[1, 2, 3, 4]* for
        :func:`colour.characterisation.polynomial_expansion_Finlayson2015`
        definition.
    root_polynomial_expansion
        {:func:`colour.characterisation.polynomial_expansion_Finlayson2015`},
        Whether to use the root-polynomials set for the expansion.
    terms
        {:func:`colour.characterisation.matrix_augmented_Cheung2004`},
        Number of terms of the expanded polynomial.

    Returns
    -------
    :class:`numpy.ndarray`
        Expanded :math:`a` array.

    References
    ----------
    :cite:`Cheung2004`, :cite:`Finlayson2015`, :cite:`Westland2004`,
    :cite:`Wikipedia2003e`

    Examples
    --------
    >>> RGB = np.array([0.17224810, 0.09170660, 0.06416938])
    >>> polynomial_expansion(RGB)  # doctest: +ELLIPSIS
    array([ 0.1722481...,  0.0917066...,  0.0641693...])
    >>> polynomial_expansion(RGB, 'Cheung 2004', terms=5)  # doctest: +ELLIPSIS
    array([ 0.1722481...,  0.0917066...,  0.0641693...,  0.0010136...,  1...])
    """

    method = validate_method(method, POLYNOMIAL_EXPANSION_METHODS)

    function = POLYNOMIAL_EXPANSION_METHODS[method]

    return function(a, **filter_kwargs(function, **kwargs))
Esempio n. 24
0
def CCT_to_uv(CCT, method='Ohno 2013', **kwargs):
    """
    Returns the *CIE UCS* colourspace *uv* chromaticity coordinates from given
    correlated colour temperature :math:`T_{cp}` using given method.

    Parameters
    ----------
    CCT : numeric
        Correlated colour temperature :math:`T_{cp}`.
    method : unicode, optional
        **{'Ohno 2013', 'Robertson 1968', 'Krystek 1985}**,
        Computation method.

    Other Parameters
    ----------------
    D_uv : numeric
       {:func:`CCT_to_uv_Ohno2013, CCT_to_uv_Robertson1968`},
       :math:`\Delta_{uv}`.
    cmfs : XYZ_ColourMatchingFunctions, optional
        {:func:`CCT_to_uv_Ohno2013`},
        Standard observer colour matching functions.

    Returns
    -------
    ndarray
        *CIE UCS* colourspace *uv* chromaticity coordinates.

    Examples
    --------
    >>> from colour import STANDARD_OBSERVERS_CMFS
    >>> cmfs = STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer']
    >>> CCT = 6507.4342201047066
    >>> D_uv = 0.003223690901513
    >>> CCT_to_uv(CCT, D_uv=D_uv, cmfs=cmfs)  # doctest: +ELLIPSIS
    array([ 0.1977999...,  0.3122004...])
    """

    function = CCT_TO_UV_METHODS[method]

    filter_kwargs(function, **kwargs)

    return function(CCT, **kwargs)
Esempio n. 25
0
def log_decoding_curve(value, curve='Cineon', **kwargs):
    """
    Decodes :math:`R'G'B'` video component signal value to linear-light values
    using given *log* curve.

    Parameters
    ----------
    value : numeric or array_like
        Value.
    curve : unicode, optional
        **{'Cineon', 'Panalog', 'ViperLog', 'PLog', 'Canon Log', 'ACEScc',
        'ACESproxy', 'ALEXA Log C', 'REDLog', 'REDLogFilm', 'S-Log', 'S-Log2',
        'S-Log3', 'V-Log'}**,
        Computation curve.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    numeric or ndarray
        *Log* value.

    Examples
    --------
    >>> log_decoding_curve(0.457319613085418)  # doctest: +ELLIPSIS
    0.1...
    >>> log_decoding_curve(  # doctest: +ELLIPSIS
    ...     0.413588402492442, curve='ACEScc')
    0.1...
    >>> log_decoding_curve(  # doctest: +ELLIPSIS
    ...     0.391006842619746, curve='PLog', log_reference=400)
    0.1...
    >>> log_decoding_curve(  # doctest: +ELLIPSIS
    ...     0.359987846422154, curve='S-Log')
    0.1...
    """

    function = LOG_DECODING_CURVES[curve]

    filter_kwargs(function, **kwargs)

    return function(value, **kwargs)
Esempio n. 26
0
def decoding_cctf(value, function='Cineon', **kwargs):
    """
    Decodes non-linear :math:`R'G'B'` values to linear :math:`RGB` values using
    given decoding colour component transfer function (Decoding CCTF).

    Parameters
    ----------
    value : numeric or array_like
        Non-linear :math:`R'G'B'` values.
    function : unicode, optional
        {:attr:`colour.DECODING_CCTFS`},
        Computation function.

    Other Parameters
    ----------------
    \\**kwargs : dict, optional
        Keywords arguments for the relevant decoding CCTF of the
        :attr:`colour.DECODING_CCTFS` attribute collection.

    Warning
    -------
    For *ITU-R BT.2100*, only the electro-optical transfer functions
    (EOTFs / EOCFs) are exposed by this definition, please refer to the
    :func:`colour.oetf_reverse` definition for the reverse opto-electronic
    transfer functions (OETF / OECF).

    Returns
    -------
    numeric or ndarray
        Linear :math:`RGB` values.

    Examples
    --------
    >>> decoding_cctf(0.391006842619746, function='PLog', log_reference=400)
    ... # doctest: +ELLIPSIS
    0.1...
    >>> decoding_cctf(0.182011532850008, function='ST 2084', L_p=1000)
    ... # doctest: +ELLIPSIS
    0.1...
    >>> decoding_cctf(  # doctest: +ELLIPSIS
    ...     0.461356129500442, function='ITU-R BT.1886')
    0.1...
    """

    if 'itu-r bt.2100' in function.lower():
        usage_warning(
            'For "ITU-R BT.2100", only the electro-optical transfer functions '
            '(EOTFs / EOCFs) are exposed by this definition, please refer to '
            'the "colour.oetf_reverse" definition for the reverse '
            'opto-electronic transfer functions (OETF / OECF).')

    function = DECODING_CCTFS[function]

    return function(value, **filter_kwargs(function, **kwargs))
Esempio n. 27
0
def encoding_cctf(value, function='sRGB', **kwargs):
    """
    Encodes linear :math:`RGB` values to non linear :math:`R'G'B'` values using
    given encoding colour component transfer function (Encoding CCTF).

    Parameters
    ----------
    value : numeric or array_like
        Linear :math:`RGB` values.
    function : unicode, optional
        {:attr:`colour.ENCODING_CCTFS`},
        Computation function.

    Other Parameters
    ----------------
    \\**kwargs : dict, optional
        Keywords arguments for the relevant encoding CCTF of the
        :attr:`colour.ENCODING_CCTFS` attribute collection.

    Warning
    -------
    For *ITU-R BT.2100*, only the reverse electro-optical transfer functions
    (EOTFs / EOCFs) are exposed by this definition, please refer to the
    :func:`colour.oetf` definition for the opto-electronic transfer functions
    (OETF / OECF).

    Returns
    -------
    numeric or ndarray
        Non linear :math:`R'G'B'` values.

    Examples
    --------
    >>> encoding_cctf(0.18, function='PLog', log_reference=400)
    ... # doctest: +ELLIPSIS
    0.3910068...
    >>> encoding_cctf(0.18, function='ST 2084', L_p=1000)
    ... # doctest: +ELLIPSIS
    0.1820115...
    >>> encoding_cctf(  # doctest: +ELLIPSIS
    ...     0.11699185725296059, function='ITU-R BT.1886')
    0.4090077...
    """

    if 'itu-r bt.2100' in function.lower():
        usage_warning(
            'For "ITU-R BT.2100", only the reverse electro-optical transfer '
            'functions (EOTFs / EOCFs) are exposed by this definition, please '
            'refer to the "colour.oetf" definition for the opto-electronic '
            'transfer functions (OETF / OECF).')

    function = ENCODING_CCTFS[function]

    return function(value, **filter_kwargs(function, **kwargs))
Esempio n. 28
0
def uv_to_CCT(uv, method='Ohno 2013', **kwargs):
    """
    Returns the correlated colour temperature :math:`T_{cp}` and
    :math:`\\Delta_{uv}` from given *CIE UCS* colourspace *uv* chromaticity
    coordinates using given method.

    Parameters
    ----------
    uv : array_like
        *CIE UCS* colourspace *uv* chromaticity coordinates.
    method : unicode, optional
        **{'Ohno 2013', 'Robertson 1968'}**,
        Computation method.

    Other Parameters
    ----------------
    cmfs : XYZ_ColourMatchingFunctions, optional
        {:func:`colour.temperature.uv_to_CCT_Ohno2013`},
        Standard observer colour matching functions.
    start : numeric, optional
        {:func:`colour.temperature.uv_to_CCT_Ohno2013`},
        Temperature range start in kelvins.
    end : numeric, optional
        {:func:`colour.temperature.uv_to_CCT_Ohno2013`},
        Temperature range end in kelvins.
    count : int, optional
        {:func:`colour.temperature.uv_to_CCT_Ohno2013`},
        Temperatures count in the planckian tables.
    iterations : int, optional
        {:func:`colour.temperature.uv_to_CCT_Ohno2013`},
        Number of planckian tables to generate.

    Returns
    -------
    ndarray
        Correlated colour temperature :math:`T_{cp}`, :math:`\\Delta_{uv}`.

    References
    ----------
    :cite:`AdobeSystems2013`, :cite:`AdobeSystems2013a`, :cite:`Ohno2014a`,
    :cite:`Wyszecki2000y`

    Examples
    --------
    >>> from colour import STANDARD_OBSERVERS_CMFS
    >>> cmfs = STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer']
    >>> uv = np.array([0.1978, 0.3122])
    >>> uv_to_CCT(uv, cmfs=cmfs)  # doctest: +ELLIPSIS
    array([  6.5074738...e+03,   3.2233461...e-03])
    """

    function = UV_TO_CCT_METHODS[method]

    return function(uv, **filter_kwargs(function, **kwargs))
Esempio n. 29
0
def eotf(value: Union[FloatingOrArrayLike, IntegerOrArrayLike],
         function: Union[Literal["DCDM", "DICOM GSDF", "ITU-R BT.1886",
                                 "ITU-R BT.2020", "ITU-R BT.2100 HLG",
                                 "ITU-R BT.2100 PQ", "SMPTE 240M", "ST 2084",
                                 "sRGB", ], str, ] = "ITU-R BT.1886",
         **kwargs: Any) -> FloatingOrNDArray:
    """
    Decode :math:`R'G'B'` video component signal value to tristimulus values
    at the display using given electro-optical transfer function (EOTF).

    Parameters
    ----------
    value
        Value.
    function
        Electro-optical transfer function (EOTF).

    Other Parameters
    ----------------
    kwargs
        {:func:`colour.models.eotf_DCDM`,
        :func:`colour.models.eotf_DICOMGSDF`,
        :func:`colour.models.eotf_BT1886`,
        :func:`colour.models.eotf_BT2020`,
        :func:`colour.models.eotf_HLG_BT2100`,
        :func:`colour.models.eotf_PQ_BT2100`,
        :func:`colour.models.eotf_SMPTE240M`,
        :func:`colour.models.eotf_ST2084`,
        :func:`colour.models.eotf_sRGB`},
        See the documentation of the previously listed definitions.

    Returns
    -------
    :class:`numpy.floating` or :class:`numpy.ndarray`
        Tristimulus values at the display.

    Examples
    --------
    >>> eotf(0.461356129500442)  # doctest: +ELLIPSIS
    0.1...
    >>> eotf(0.409007728864150, function='ITU-R BT.2020')
    ... # doctest: +ELLIPSIS
    0.1...
    >>> eotf(0.182011532850008, function='ST 2084', L_p=1000)
    ... # doctest: +ELLIPSIS
    0.1...
    """

    function = validate_method(
        function, EOTFS, '"{0}" "EOTF" is invalid, it must be one of {1}!')

    callable_ = EOTFS[function]

    return callable_(value, **filter_kwargs(callable_, **kwargs))
Esempio n. 30
0
def encoding_cctf(value, function='sRGB', **kwargs):
    """
    Encodes linear :math:`RGB` values to non linear :math:`R'G'B'` values using
    given encoding colour component transfer function (Encoding CCTF).

    Parameters
    ----------
    value : numeric or array_like
        Linear :math:`RGB` values.
    function : unicode, optional
        {:attr:`colour.ENCODING_CCTFS`},
        Computation function.

    Other Parameters
    ----------------
    \\**kwargs : dict, optional
        Keywords arguments for the relevant encoding CCTF of the
        :attr:`colour.ENCODING_CCTFS` attribute collection.

    Warning
    -------
    For *ITU-R BT.2100*, only the reverse electro-optical transfer functions
    (EOTFs / EOCFs) are exposed by this definition, please refer to the
    :func:`colour.oetf` definition for the opto-electronic transfer functions
    (OETF / OECF).

    Returns
    -------
    numeric or ndarray
        Non linear :math:`R'G'B'` values.

    Examples
    --------
    >>> encoding_cctf(0.18, function='PLog', log_reference=400)
    ... # doctest: +ELLIPSIS
    0.3910068...
    >>> encoding_cctf(0.18, function='ST 2084', L_p=1000)
    ... # doctest: +ELLIPSIS
    0.1820115...
    >>> encoding_cctf(  # doctest: +ELLIPSIS
    ...     0.11699185725296059, function='ITU-R BT.1886')
    0.4090077...
    """

    if 'itu-r bt.2100' in function.lower():
        usage_warning(
            'For "ITU-R BT.2100", only the reverse electro-optical transfer '
            'functions (EOTFs / EOCFs) are exposed by this definition, please '
            'refer to the "colour.oetf" definition for the opto-electronic '
            'transfer functions (OETF / OECF).')

    function = ENCODING_CCTFS[function]

    return function(value, **filter_kwargs(function, **kwargs))
Esempio n. 31
0
def eotf_inverse(value: FloatingOrArrayLike,
                 function: Union[Literal["DCDM", "DICOM GSDF", "ITU-R BT.1886",
                                         "ITU-R BT.2020", "ITU-R BT.2100 HLG",
                                         "ITU-R BT.2100 PQ", "ST 2084",
                                         "sRGB", ], str, ] = "ITU-R BT.1886",
                 **kwargs) -> Union[FloatingOrNDArray, IntegerOrNDArray]:
    """
    Encode estimated tristimulus values in a scene to :math:`R'G'B'` video
    component signal value using given inverse electro-optical transfer
    function (EOTF).

    Parameters
    ----------
    value
        Value.
    function
        Inverse electro-optical transfer function (EOTF).

    Other Parameters
    ----------------
    kwargs
        {:func:`colour.models.eotf_inverse_DCDM`,
        :func:`colour.models.eotf_inverse_DICOMGSDF`,
        :func:`colour.models.eotf_inverse_BT1886`,
        :func:`colour.models.eotf_inverse_BT2020`,
        :func:`colour.models.eotf_inverse_HLG_BT2100`,
        :func:`colour.models.eotf_inverse_PQ_BT2100`,
        :func:`colour.models.eotf_inverse_ST2084`,
        :func:`colour.models.eotf_inverse_sRGB`},
        See the documentation of the previously listed definitions.

    Returns
    -------
    :class:`numpy.floating` or :class:`numpy.integer` or :class:`numpy.ndarray`
        :math:`R'G'B'` video component signal value.

    Examples
    --------
    >>> eotf_inverse(0.11699185725296059)  # doctest: +ELLIPSIS
    0.4090077...
    >>> eotf_inverse(  # doctest: +ELLIPSIS
    ...     0.11699185725296059, function='ITU-R BT.1886')
    0.4090077...
    """

    function = validate_method(
        function,
        EOTF_INVERSES,
        '"{0}" inverse "EOTF" is invalid, it must be one of {1}!',
    )

    callable_ = EOTF_INVERSES[function]

    return callable_(value, **filter_kwargs(callable_, **kwargs))
Esempio n. 32
0
def oetf(value: FloatingOrArrayLike,
         function: Union[Literal["ARIB STD-B67",
                                 "Blackmagic Film Generation 5",
                                 "DaVinci Intermediate", "ITU-R BT.2100 HLG",
                                 "ITU-R BT.2100 PQ", "ITU-R BT.601",
                                 "ITU-R BT.709", "SMPTE 240M", ],
                         str, ] = "ITU-R BT.709",
         **kwargs: Any) -> FloatingOrNDArray:
    """
    Encode estimated tristimulus values in a scene to :math:`R'G'B'` video
    component signal value using given opto-electronic transfer function
    (OETF).

    Parameters
    ----------
    value
        Value.
    function
        Opto-electronic transfer function (OETF).

    Other Parameters
    ----------------
    kwargs
        {:func:`colour.models.oetf_ARIBSTDB67`,
        :func:`colour.models.oetf_BlackmagicFilmGeneration5`,
        :func:`colour.models.oetf_DaVinciIntermediate`,
        :func:`colour.models.oetf_HLG_BT2100`,
        :func:`colour.models.oetf_PQ_BT2100`,
        :func:`colour.models.oetf_BT601`,
        :func:`colour.models.oetf_BT709`,
        :func:`colour.models.oetf_SMPTE240M`},
        See the documentation of the previously listed definitions.

    Returns
    -------
    :class:`numpy.floating` or :class:`numpy.ndarray`
        :math:`R'G'B'` video component signal value.

    Examples
    --------
    >>> oetf(0.18)  # doctest: +ELLIPSIS
    0.4090077...
    >>> oetf(0.18, function='ITU-R BT.601')  # doctest: +ELLIPSIS
    0.4090077...
    """

    function = validate_method(
        function, OETFS, '"{0}" "OETF" is invalid, it must be one of {1}!')

    callable_ = OETFS[function]

    return callable_(value, **filter_kwargs(callable_, **kwargs))
Esempio n. 33
0
def oetf(value, function='sRGB', **kwargs):
    """
    Encodes estimated tristimulus values in a scene to :math:`R'G'B'` video
    component signal value using given opto-electronic transfer function
    (OETF / OECF).

    Parameters
    ----------
    value : numeric or array_like
        Value.
    function : unicode, optional
        **{'sRGB', 'BT.1886', 'BT.2020', 'BT.709', 'DCI-P3', 'ProPhoto RGB',
        'ST 2084'}**,
        Computation function.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    numeric or ndarray
        :math:`R'G'B'` video component signal value.

    Examples
    --------
    >>> oetf(0.18)  # doctest: +ELLIPSIS
    0.4613561...
    >>> oetf(0.18, function='BT.2020')  # doctest: +ELLIPSIS
    0.4090077...
    >>> oetf(  # doctest: +ELLIPSIS
    ...     0.18, function='ST 2084', L_p=1000)
    0.1820115...
    """

    function = OETFS[function]

    filter_kwargs(function, **kwargs)

    return function(value, **kwargs)
Esempio n. 34
0
def eotf(value, function='sRGB', **kwargs):
    """
    Decodes :math:`R'G'B'` video component signal value to tristimulus values
    at the display using given electro-optical transfer function (EOTF / EOCF).

    Parameters
    ----------
    value : numeric or array_like
        Value.
    function : unicode, optional
        **{'sRGB', 'BT.1886', 'BT.2020', 'BT.709', 'DCI-P3', 'ProPhoto RGB',
        'ST 2084'}**,
        Computation function.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    numeric or ndarray
        Tristimulus values at the display.

    Examples
    --------
    >>> eotf(0.461356129500442)  # doctest: +ELLIPSIS
    0.1...
    >>> eotf(0.409007728864150,
    ...     function='BT.2020')  # doctest: +ELLIPSIS
    0.1...
    >>> eotf(  # doctest: +ELLIPSIS
    ...     0.182011532850008, function='ST 2084', L_p=1000)
    0.1...
    """

    function = EOTFS[function]

    filter_kwargs(function, **kwargs)

    return function(value, **kwargs)
Esempio n. 35
0
def eotf_reverse(value, function='ITU-R BT.1886', **kwargs):
    """
    Encodes estimated tristimulus values in a scene to :math:`R'G'B'` video
    component signal value using given reverse electro-optical transfer
    function (EOTF / EOCF).

    Parameters
    ----------
    value : numeric or array_like
        Value.
    function : unicode, optional
        **{'ITU-R BT.1886', 'DCDM', 'ITU-R BT.2100 HLG', 'ITU-R BT.2100 PQ'}**,
        Reverse electro-optical transfer function (EOTF / EOCF).

    Other Parameters
    ----------------
    L_B : numeric, optional
        {:func:`colour.models.eotf_reverse_BT1886`,
        :func:`colour.models.eotf_reverse_BT2100_HLG`},
        Screen luminance for black.
    L_W : numeric, optional
        {:func:`colour.models.eotf_reverse_BT1886`,
        :func:`colour.models.eotf_reverse_BT2100_HLG`},
        Screen luminance for white.
    gamma : numeric, optional
        {:func:`colour.models.eotf_BT2100_HLG`},
        System gamma value, 1.2 at the nominal display peak luminance of
        :math:`1000 cd/m^2`.
    out_int : bool, optional
        {:func:`colour.models.eotf_reverse_DCDM`},
        Whether to return value as integer code value or float equivalent of a
        code value at a given bit depth.

    Returns
    -------
    numeric or ndarray
        :math:`R'G'B'` video component signal value.

    Examples
    --------
    >>> eotf_reverse(0.11699185725296059)  # doctest: +ELLIPSIS
    0.4090077...
    >>> eotf_reverse(  # doctest: +ELLIPSIS
    ...     0.11699185725296059, function='ITU-R BT.1886')
    0.4090077...
    """

    function = EOTFS_REVERSE[function]

    return function(value, **filter_kwargs(function, **kwargs))
Esempio n. 36
0
def polynomial_expansion(a, method='Cheung 2004', **kwargs):
    """
    Performs polynomial expansion of given :math:`a` array.

    Parameters
    ----------
    a : array_like, (3, n)
        :math:`a` array to expand.
    method : unicode, optional
        **{'Cheung 2004', 'Finlayson 2015', 'Vandermonde'}**,
        Computation method.

    Other Parameters
    ----------------
    degree : int
        {:func:`colour.characterisation.polynomial_expansion_Finlayson2015`,
        :func:`colour.characterisation.polynomial_expansion_Vandermonde`},
        Expanded polynomial degree, must be one of *[1, 2, 3, 4]* for
        :func:`colour.characterisation.polynomial_expansion_Finlayson2015`
        definition.
    terms : int
        {:func:`colour.characterisation.augmented_matrix_Cheung2004`},
        Number of terms of the expanded polynomial, must be one of
        *[3, 5, 7, 8, 10, 11, 14, 16, 17, 19, 20, 22]*.
    root_polynomial_expansion : bool
        {:func:`colour.characterisation.polynomial_expansion_Finlayson2015`},
        Whether to use the root-polynomials set for the expansion.

    Returns
    -------
    ndarray, (3, n)
        Expanded :math:`a` array.

    References
    ----------
    :cite:`Cheung2004`, :cite:`Finlayson2015`, :cite:`Westland2004`,
    :cite:`Wikipedia2003e`

    Examples
    --------
    >>> RGB = np.array([0.17224810, 0.09170660, 0.06416938])
    >>> polynomial_expansion(RGB)  # doctest: +ELLIPSIS
    array([ 0.1722481...,  0.0917066...,  0.0641693...])
    >>> polynomial_expansion(RGB, 'Cheung 2004', terms=5)  # doctest: +ELLIPSIS
    array([ 0.1722481...,  0.0917066...,  0.0641693...,  0.0010136...,  1...])
    """

    function = POLYNOMIAL_EXPANSION_METHODS[method]

    return function(a, **filter_kwargs(function, **kwargs))
Esempio n. 37
0
def polynomial_expansion(a, method='Cheung 2004', **kwargs):
    """
    Performs polynomial expansion of given :math:`a` array.

    Parameters
    ----------
    a : array_like, (3, n)
        :math:`a` array to expand.
    method : unicode, optional
        **{'Cheung 2004', 'Finlayson 2015', 'Vandermonde'}**,
        Computation method.

    Other Parameters
    ----------------
    degree : int
        {:func:`colour.characterisation.polynomial_expansion_Finlayson2015`,
        :func:`colour.characterisation.polynomial_expansion_Vandermonde`},
        Expanded polynomial degree, must be one of *[1, 2, 3, 4]* for
        :func:`colour.characterisation.polynomial_expansion_Finlayson2015`
        definition.
    terms : int
        {:func:`colour.characterisation.matrix_augmented_Cheung2004`},
        Number of terms of the expanded polynomial, must be one of
        *[3, 5, 7, 8, 10, 11, 14, 16, 17, 19, 20, 22]*.
    root_polynomial_expansion : bool
        {:func:`colour.characterisation.polynomial_expansion_Finlayson2015`},
        Whether to use the root-polynomials set for the expansion.

    Returns
    -------
    ndarray, (3, n)
        Expanded :math:`a` array.

    References
    ----------
    :cite:`Cheung2004`, :cite:`Finlayson2015`, :cite:`Westland2004`,
    :cite:`Wikipedia2003e`

    Examples
    --------
    >>> RGB = np.array([0.17224810, 0.09170660, 0.06416938])
    >>> polynomial_expansion(RGB)  # doctest: +ELLIPSIS
    array([ 0.1722481...,  0.0917066...,  0.0641693...])
    >>> polynomial_expansion(RGB, 'Cheung 2004', terms=5)  # doctest: +ELLIPSIS
    array([ 0.1722481...,  0.0917066...,  0.0641693...,  0.0010136...,  1...])
    """

    function = POLYNOMIAL_EXPANSION_METHODS[method]

    return function(a, **filter_kwargs(function, **kwargs))
Esempio n. 38
0
    def test_filter_kwargs(self):
        """
        Tests :func:`colour.utilities.common.filter_kwargs` definition.
        """
        def fn_a(a):
            """
            :func:`filter_kwargs` unit tests :func:`fn_a` definition.
            """
            return a

        def fn_b(a, b=0):
            """
            :func:`filter_kwargs` unit tests :func:`fn_b` definition.
            """

            return a, b

        def fn_c(a, b=0, c=0):
            """
            :func:`filter_kwargs` unit tests :func:`fn_c` definition.
            """

            return a, b, c

        self.assertEqual(1, fn_a(1, **filter_kwargs(fn_a, b=2, c=3)))

        self.assertTupleEqual((1, 2), fn_b(1, **filter_kwargs(fn_b, b=2, c=3)))

        self.assertTupleEqual((1, 2, 3),
                              fn_c(1, **filter_kwargs(fn_c, b=2, c=3)))

        if six.PY2:  # pragma: no cover
            self.assertDictEqual(filter_kwargs(partial(fn_c, b=1), b=1), {})
        else:  # pragma: no cover
            self.assertDictEqual(filter_kwargs(partial(fn_c, b=1), b=1),
                                 {'b': 1})
Esempio n. 39
0
def CCT_to_uv(
    CCT_D_uv: ArrayLike,
    method: Union[
        Literal["Krystek 1985", "Ohno 2013", "Robertson 1968"], str
    ] = "Ohno 2013",
    **kwargs: Any,
) -> NDArray:
    """
    Return the *CIE UCS* colourspace *uv* chromaticity coordinates from given
    correlated colour temperature :math:`T_{cp}` using given method.

    Parameters
    ----------
    CCT_D_uv
        Correlated colour temperature :math:`T_{cp}`, :math:`\\Delta_{uv}`.
    method
        Computation method.

    Other Parameters
    ----------------
    cmfs
        {:func:`colour.temperature.CCT_to_uv_Ohno2013`},
        Standard observer colour matching functions.

    Returns
    -------
    :class:`numpy.ndarray`
        *CIE UCS* colourspace *uv* chromaticity coordinates.

    References
    ----------
    :cite:`AdobeSystems2013`, :cite:`AdobeSystems2013a`, :cite:`Krystek1985b`,
    :cite:`Ohno2014a`, :cite:`Wyszecki2000y`

    Examples
    --------
    >>> import numpy as np
    >>> CCT_D_uv = np.array([6507.47380460, 0.00322335])
    >>> CCT_to_uv(CCT_D_uv)  # doctest: +ELLIPSIS
    array([ 0.1977999...,  0.3121999...])
    """

    method = validate_method(method, CCT_TO_UV_METHODS)

    function = CCT_TO_UV_METHODS[method]

    return function(CCT_D_uv, **filter_kwargs(function, **kwargs))
Esempio n. 40
0
def eotf_reverse(value, function='ITU-R BT.1886', **kwargs):
    """
    Encodes estimated tristimulus values in a scene to :math:`R'G'B'` video
    component signal value using given reverse electro-optical transfer
    function (EOTF / EOCF).

    Parameters
    ----------
    value : numeric or array_like
        Value.
    function : unicode, optional
        **{'ITU-R BT.1886', 'ITU-R BT.2100 HLG', 'ITU-R BT.2100 PQ'}**,
        Reverse electro-optical transfer function (EOTF / EOCF).

    Other Parameters
    ----------------
    L_B : numeric, optional
        {:func:`colour.models.eotf_reverse_BT1886`,
        :func:`colour.models.eotf_reverse_BT2100_HLG`},
        Screen luminance for black.
    L_W : numeric, optional
        {:func:`colour.models.eotf_reverse_BT1886`,
        :func:`colour.models.eotf_reverse_BT2100_HLG`},
        Screen luminance for white.
    gamma : numeric, optional
        {:func:`colour.models.eotf_BT2100_HLG`},
        System gamma value, 1.2 at the nominal display peak luminance of
        :math:`1000 cd/m^2`.

    Returns
    -------
    numeric or ndarray
        :math:`R'G'B'` video component signal value.

    Examples
    --------
    >>> eotf_reverse(0.11699185725296059)  # doctest: +ELLIPSIS
    0.4090077...
    >>> eotf_reverse(  # doctest: +ELLIPSIS
    ...     0.11699185725296059, function='ITU-R BT.1886')
    0.4090077...
    """

    function = EOTFS_REVERSE[function]

    return function(value, **filter_kwargs(function, **kwargs))
Esempio n. 41
0
def ootf_reverse(value, function='ITU-R BT.2100 PQ', **kwargs):
    """
    Maps relative display linear light to scene linear light using given
    reverse opto-optical transfer function (OOTF / OOCF).

    Parameters
    ----------
    value : numeric or array_like
        Value.
    function : unicode, optional
        **{'ITU-R BT.2100 HLG', 'ITU-R BT.2100 PQ'}**
        Reverse opto-optical transfer function (OOTF / OOCF).

    Other Parameters
    ----------------
    L_B : numeric, optional
        {:func:`colour.models.ootf_reverse_BT2100_HLG`},
        :math:`L_B` is the display luminance for black in :math:`cd/m^2`.
    L_W : numeric, optional
        {:func:`colour.models.ootf_reverse_BT2100_HLG`},
        :math:`L_W` is nominal peak luminance of the display in :math:`cd/m^2`
        for achromatic pixels.
    gamma : numeric, optional
        {:func:`colour.models.ootf_reverse_BT2100_HLG`},
        System gamma value, 1.2 at the nominal display peak luminance of
        :math:`1000 cd/m^2`.

    Returns
    -------
    numeric or ndarray
        Luminance of scene linear light.

    Examples
    --------
    >>> ootf_reverse(779.988360834115840)  # doctest: +ELLIPSIS
    0.1000000...
    >>> ootf_reverse(  # doctest: +ELLIPSIS
    ...     63.095734448019336, function='ITU-R BT.2100 HLG')
    0.1000000...
    """

    function = OOTFS_REVERSE[function]

    return function(value, **filter_kwargs(function, **kwargs))
Esempio n. 42
0
def CCT_to_uv(CCT_D_uv, method='Ohno 2013', **kwargs):
    """
    Returns the *CIE UCS* colourspace *uv* chromaticity coordinates from given
    correlated colour temperature :math:`T_{cp}` using given method.

    Parameters
    ----------
    CCT_D_uv : ndarray
        Correlated colour temperature :math:`T_{cp}`, :math:`\\Delta_{uv}`.
    method : unicode, optional
        **{'Ohno 2013', 'Robertson 1968', 'Krystek 1985}**,
        Computation method.

    Other Parameters
    ----------------
    cmfs : XYZ_ColourMatchingFunctions, optional
        {:func:`colour.temperature.CCT_to_uv_Ohno2013`},
        Standard observer colour matching functions.

    Returns
    -------
    ndarray
        *CIE UCS* colourspace *uv* chromaticity coordinates.

    References
    ----------
    :cite:`AdobeSystems2013`, :cite:`AdobeSystems2013a`, :cite:`Krystek1985b`,
    :cite:`Ohno2014a`, :cite:`Wyszecki2000y`

    Examples
    --------
    >>> from colour import STANDARD_OBSERVERS_CMFS
    >>> cmfs = STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer']
    >>> CCT_D_uv = np.array([6507.47380460, 0.00322335])
    >>> CCT_to_uv(CCT_D_uv, cmfs=cmfs)  # doctest: +ELLIPSIS
    array([ 0.1977999...,  0.3121999...])
    """

    function = CCT_TO_UV_METHODS[method]

    return function(CCT_D_uv, **filter_kwargs(function, **kwargs))
Esempio n. 43
0
def oetf_reverse(value, function='sRGB', **kwargs):
    """
    Decodes :math:`R'G'B'` video component signal value to tristimulus values
    at the display using given reverse opto-electronic transfer function
    (OETF / OECF).

    Parameters
    ----------
    value : numeric or array_like
        Value.
    function : unicode, optional
        **{'sRGB', 'ARIB STD-B67', 'ITU-R BT.2100 HLD', 'ITU-R BT.2100 PQ',
        'ITU-R BT.601', 'ITU-R BT.709'}**,
        Reverse opto-electronic transfer function (OETF / OECF).

    Other Parameters
    ----------------
    r : numeric, optional
        {:func:`colour.models.oetf_ARIBSTDB67`},
        Video level corresponding to reference white level.

    Returns
    -------
    numeric or ndarray
        Tristimulus values at the display.

    Examples
    --------
    >>> oetf_reverse(0.461356129500442)  # doctest: +ELLIPSIS
    0.1...
    >>> oetf_reverse(  # doctest: +ELLIPSIS
    ...     0.409007728864150, function='ITU-R BT.601')
    0.1...
    """

    function = OETFS_REVERSE[function]

    return function(value, **filter_kwargs(function, **kwargs))
Esempio n. 44
0
def luminance(LV, method='CIE 1976', **kwargs):
    """
    Returns the *luminance* :math:`Y` of given *Lightness* :math:`L^*` or given
    *Munsell* value :math:`V`.

    Parameters
    ----------
    LV : numeric or array_like
        *Lightness* :math:`L^*` or *Munsell* value :math:`V`.
    method : unicode, optional
        **{'CIE 1976', 'Newhall 1943', 'ASTM D1535-08', 'Fairchild 2010',
        'Fairchild 2011'}**,
        Computation method.

    Other Parameters
    ----------------
    Y_n : numeric or array_like, optional
        {:func:`colour.colorimetry.luminance_CIE1976`},
        White reference *luminance* :math:`Y_n`.
    epsilon : numeric or array_like, optional
        {:func:`colour.colorimetry.lightness_Fairchild2010`,
        :func:`colour.colorimetry.lightness_Fairchild2011`},
        :math:`\\epsilon` exponent.

    Returns
    -------
    numeric or array_like
        *luminance* :math:`Y`.

    Notes
    -----

    +------------+-----------------------+---------------+
    | **Domain** | **Scale - Reference** | **Scale - 1** |
    +============+=======================+===============+
    | ``LV``     | [0, 100]              | [0, 1]        |
    +------------+-----------------------+---------------+

    +------------+-----------------------+---------------+
    | **Range**  | **Scale - Reference** | **Scale - 1** |
    +============+=======================+===============+
    | ``Y``      | [0, 100]              | [0, 1]        |
    +------------+-----------------------+---------------+

    References
    ----------
    :cite:`ASTMInternational2008a`, :cite:`CIETC1-482004m`,
    :cite:`Fairchild2010`, :cite:`Fairchild2011`, :cite:`Newhall1943a`,
    :cite:`Wikipedia2001b`, :cite:`Wyszecki2000bd`

    Examples
    --------
    >>> luminance(41.527875844653451)  # doctest: +ELLIPSIS
    12.1972253...
    >>> luminance(41.527875844653451, Y_n=100)  # doctest: +ELLIPSIS
    12.1972253...
    >>> luminance(42.51993072812094, Y_n=95)  # doctest: +ELLIPSIS
    12.1972253...
    >>> luminance(4.08244375 * 10, method='Newhall 1943')
    ... # doctest: +ELLIPSIS
    12.5500788...
    >>> luminance(4.08244375 * 10, method='ASTM D1535-08')
    ... # doctest: +ELLIPSIS
    12.2363426...
    >>> luminance(29.829510892279330, epsilon=0.710, method='Fairchild 2011')
    ... # doctest: +ELLIPSIS
    12.1972253...
    """

    function = LUMINANCE_METHODS[method]

    domain_range_reference = get_domain_range_scale() == 'reference'
    domain_1 = (luminance_Fairchild2010, luminance_Fairchild2011)
    domain_10 = (luminance_Newhall1943, luminance_ASTMD153508)

    if function in domain_10 and domain_range_reference:
        LV /= 10

    Y_V = function(LV, **filter_kwargs(function, **kwargs))

    if function in domain_1 and domain_range_reference:
        Y_V *= 100

    return Y_V
Esempio n. 45
0
def write_LUT(LUT, path, decimals=7, method=None, **kwargs):
    """
    Writes given *LUT* to given file using given method.

    Parameters
    ----------
    LUT : LUT1D or LUT3x1D or LUT3D
        :class:`LUT1D`, :class:`LUT3x1D` or :class:`LUT3D` class instance to
        write at given path.
    path : unicode
        *LUT* path.
    decimals : int, optional
        Formatting decimals.
    method : unicode, optional
        **{None, 'Cinespace', 'Iridas Cube', 'Resolve Cube', 'Sony SPI1D',
        'Sony SPI3D'}**, Writing method, if *None*, the method will be
        auto-detected according to extension.

    Returns
    -------
    bool
        Definition success.

    References
    ----------
    :cite:`AdobeSystems2013b`, :cite:`Chamberlain2015`,
    :cite:`RisingSunResearch`

    Examples
    --------
    Writing a 3x1D *Iridas* *.cube* *LUT*:

    >>> import numpy as np
    >>> from colour.algebra import spow
    >>> domain = np.array([[-0.1, -0.2, -0.4], [1.5, 3.0, 6.0]])
    >>> LUT = LUT3x1D(
    ...     spow(LUT3x1D.linear_table(16, domain), 1 / 2.2),
    ...     'My LUT',
    ...     domain,
    ...     comments=['A first comment.', 'A second comment.'])
    >>> write_LUT(LUT, 'My_LUT.cube')  # doctest: +SKIP

    Writing a 1D *Sony* *.spi1d* *LUT*:

    >>> domain = np.array([-0.1, 1.5])
    >>> LUT = LUT1D(
    ...     spow(LUT1D.linear_table(16, domain), 1 / 2.2),
    ...     'My LUT',
    ...     domain,
    ...     comments=['A first comment.', 'A second comment.'])
    >>> write_LUT(LUT, 'My_LUT.spi1d')  # doctest: +SKIP

    Writing a 3D *Sony* *.spi3d* *LUT*:

    >>> LUT = LUT3D(
    ...     LUT3D.linear_table(16) ** (1 / 2.2),
    ...     'My LUT',
    ...     np.array([[0, 0, 0], [1, 1, 1]]),
    ...     comments=['A first comment.', 'A second comment.'])
    >>> write_LUT(LUT, 'My_LUT.cube')  # doctest: +SKIP
    """

    if method is None:
        method = EXTENSION_TO_LUT_FORMAT_MAPPING[os.path.splitext(path)[-1]]
        if method == 'Iridas Cube' and isinstance(LUT, LUTSequence):
            method = 'Resolve Cube'

    function = LUT_WRITE_METHODS[method]

    return function(LUT, path, decimals, **filter_kwargs(function, **kwargs))
Esempio n. 46
0
def lightness(Y, method='CIE 1976', **kwargs):
    """
    Returns the *Lightness* :math:`L` of given *luminance* :math:`Y` using
    given method.

    Parameters
    ----------
    Y : numeric or array_like
        *luminance* :math:`Y`.
    method : unicode, optional
        **{'CIE 1976', 'Glasser 1958', 'Wyszecki 1963', 'Fairchild 2010',
        'Fairchild 2011'}**,
        Computation method.

    Other Parameters
    ----------------
    Y_n : numeric or array_like, optional
        {:func:`colour.colorimetry.lightness_CIE1976`},
        White reference *luminance* :math:`Y_n`.
    epsilon : numeric or array_like, optional
        {:func:`colour.colorimetry.lightness_Fairchild2010`,
        :func:`colour.colorimetry.lightness_Fairchild2011`},
        :math:`\\epsilon` exponent.

    Returns
    -------
    numeric or array_like
        *Lightness* :math:`L`.

    Notes
    -----

    +------------+-----------------------+---------------+
    | **Domain** | **Scale - Reference** | **Scale - 1** |
    +============+=======================+===============+
    | ``Y``      | [0, 100]              | [0, 1]        |
    +------------+-----------------------+---------------+

    +------------+-----------------------+---------------+
    | **Range**  | **Scale - Reference** | **Scale - 1** |
    +============+=======================+===============+
    | ``L``      | [0, 100]              | [0, 1]        |
    +------------+-----------------------+---------------+

    References
    ----------
    :cite:`CIETC1-482004m`, :cite:`Fairchild2010`, :cite:`Fairchild2011`,
    :cite:`Glasser1958a`, :cite:`Wikipedia2007c`, :cite:`Wyszecki1963b`,
    :cite:`Wyszecki2000bd`

    Examples
    --------
    >>> lightness(12.19722535)  # doctest: +ELLIPSIS
    41.5278758...
    >>> lightness(12.19722535, Y_n=100)  # doctest: +ELLIPSIS
    41.5278758...
    >>> lightness(12.19722535, Y_n=95)  # doctest: +ELLIPSIS
    42.5199307...
    >>> lightness(12.19722535, method='Glasser 1958')  # doctest: +ELLIPSIS
    39.8351264...
    >>> lightness(12.19722535, method='Wyszecki 1963')  # doctest: +ELLIPSIS
    40.5475745...
    >>> lightness(12.19722535, epsilon=0.710, method='Fairchild 2011')
    ... # doctest: +ELLIPSIS
    29.8295108...
    """

    Y = as_float_array(Y)

    function = LIGHTNESS_METHODS[method]

    domain_range_reference = get_domain_range_scale() == 'reference'
    domain_1 = (lightness_Fairchild2010, lightness_Fairchild2011)

    if function in domain_1 and domain_range_reference:
        Y = Y / 100

    return function(Y, **filter_kwargs(function, **kwargs))
Esempio n. 47
0
def colour_correction(RGB, M_T, M_R, method='Cheung 2004', **kwargs):
    """
    Performs colour correction of given *RGB* colourspace array using the
    colour correction matrix from given :math:`M_T` colour array to
    :math:`M_R` colour array.

    Parameters
    ----------
    RGB : array_like, (3, n)
        *RGB* colourspace array to colour correct.
    M_T : array_like, (3, n)
        Test array :math:`M_T` to fit onto array :math:`M_R`.
    M_R : array_like, (3, n)
        Reference array the array :math:`M_T` will be colour fitted against.
    method : unicode, optional
        **{'Cheung 2004', 'Finlayson 2015', 'Vandermonde'}**,
        Computation method.

    Other Parameters
    ----------------
    degree : int
        {:func:`colour.characterisation.polynomial_expansion_Finlayson2015`,
        :func:`colour.characterisation.polynomial_expansion_Vandermonde`},
        Expanded polynomial degree, must be one of *[1, 2, 3, 4]* for
        :func:`colour.characterisation.polynomial_expansion_Finlayson2015`
        definition.
    terms : int
        {:func:`colour.characterisation.augmented_matrix_Cheung2004`},
        Number of terms of the expanded polynomial, must be one of
        *[3, 5, 7, 8, 10, 11, 14, 16, 17, 19, 20, 22]*.
    root_polynomial_expansion : bool
        {:func:`colour.characterisation.polynomial_expansion_Finlayson2015`},
        Whether to use the root-polynomials set for the expansion.

    Returns
    -------
    ndarray
        Colour corrected *RGB* colourspace array.

    References
    ----------
    :cite:`Cheung2004`, :cite:`Finlayson2015`, :cite:`Westland2004`,
    :cite:`Wikipedia2003e`

    Examples
    --------
    >>> RGB = np.array([0.17224810, 0.09170660, 0.06416938])
    >>> M_T = np.array(
    ...     [[0.17224810, 0.09170660, 0.06416938],
    ...      [0.49189645, 0.27802050, 0.21923399],
    ...      [0.10999751, 0.18658946, 0.29938611],
    ...      [0.11666120, 0.14327905, 0.05713804],
    ...      [0.18988879, 0.18227649, 0.36056247],
    ...      [0.12501329, 0.42223442, 0.37027445],
    ...      [0.64785606, 0.22396782, 0.03365194],
    ...      [0.06761093, 0.11076896, 0.39779139],
    ...      [0.49101797, 0.09448929, 0.11623839],
    ...      [0.11622386, 0.04425753, 0.14469986],
    ...      [0.36867946, 0.44545230, 0.06028681],
    ...      [0.61632937, 0.32323906, 0.02437089],
    ...      [0.03016472, 0.06153243, 0.29014596],
    ...      [0.11103655, 0.30553067, 0.08149137],
    ...      [0.41162190, 0.05816656, 0.04845934],
    ...      [0.73339206, 0.53075188, 0.02475212],
    ...      [0.47347718, 0.08834792, 0.30310315],
    ...      [0.00000000, 0.25187016, 0.35062450],
    ...      [0.76809639, 0.78486240, 0.77808297],
    ...      [0.53822392, 0.54307997, 0.54710883],
    ...      [0.35458526, 0.35318419, 0.35524431],
    ...      [0.17976704, 0.18000531, 0.17991488],
    ...      [0.09351417, 0.09510603, 0.09675027],
    ...      [0.03405071, 0.03295077, 0.03702047]]
    ... )
    >>> M_R = np.array(
    ...     [[0.15579559, 0.09715755, 0.07514556],
    ...      [0.39113140, 0.25943419, 0.21266708],
    ...      [0.12824821, 0.18463570, 0.31508023],
    ...      [0.12028974, 0.13455659, 0.07408400],
    ...      [0.19368988, 0.21158946, 0.37955964],
    ...      [0.19957425, 0.36085439, 0.40678123],
    ...      [0.48896605, 0.20691688, 0.05816533],
    ...      [0.09775522, 0.16710693, 0.47147724],
    ...      [0.39358649, 0.12233400, 0.10526425],
    ...      [0.10780332, 0.07258529, 0.16151473],
    ...      [0.27502671, 0.34705454, 0.09728099],
    ...      [0.43980441, 0.26880559, 0.05430533],
    ...      [0.05887212, 0.11126272, 0.38552469],
    ...      [0.12705825, 0.25787860, 0.13566464],
    ...      [0.35612929, 0.07933258, 0.05118732],
    ...      [0.48131976, 0.42082843, 0.07120612],
    ...      [0.34665585, 0.15170714, 0.24969804],
    ...      [0.08261116, 0.24588716, 0.48707733],
    ...      [0.66054904, 0.65941137, 0.66376412],
    ...      [0.48051509, 0.47870296, 0.48230082],
    ...      [0.33045354, 0.32904184, 0.33228886],
    ...      [0.18001305, 0.17978567, 0.18004416],
    ...      [0.10283975, 0.10424680, 0.10384975],
    ...      [0.04742204, 0.04772203, 0.04914226]]
    ... )
    >>> colour_correction(RGB, M_T, M_R)  # doctest: +ELLIPSIS
    array([ 0.1334872...,  0.0843921...,  0.0599014...])
    """

    function = COLOUR_CORRECTION_METHODS[method]

    return function(RGB, M_T, M_R, **filter_kwargs(function, **kwargs))
Esempio n. 48
0
def read_LUT(path, method=None, **kwargs):
    """
    Reads given *LUT* file using given method.

    Parameters
    ----------
    path : unicode
        *LUT* path.
    method : unicode, optional
        **{None, 'Cinespace', 'Iridas Cube', 'Resolve Cube', 'Sony SPI1D',
        'Sony SPI3D'}**, Reading method, if *None*, the method will be
        auto-detected according to extension.

    Returns
    -------
    LUT1D or LUT3x1D or LUT3D
        :class:`LUT1D`, :class:`LUT3x1D` or :class:`LUT3D` class instance.

    References
    ----------
    :cite:`AdobeSystems2013b`, :cite:`Chamberlain2015`,
    :cite:`RisingSunResearch`

    Examples
    --------
    Reading a 3x1D *Iridas* *.cube* *LUT*:

    >>> path = os.path.join(
    ...     os.path.dirname(__file__), 'tests', 'resources', 'iridas_cube',
    ...     'ACES_Proxy_10_to_ACES.cube')
    >>> print(read_LUT(path))
    LUT3x1D - ACES Proxy 10 to ACES
    -------------------------------
    <BLANKLINE>
    Dimensions : 2
    Domain     : [[ 0.  0.  0.]
                  [ 1.  1.  1.]]
    Size       : (32, 3)

    Reading a 1D *Sony* *.spi1d* *LUT*:

    >>> path = os.path.join(
    ...     os.path.dirname(__file__), 'tests', 'resources', 'sony_spi1d',
    ...     'oetf_reverse_sRGB_1D.spi1d')
    >>> print(read_LUT(path))
    LUT1D - oetf reverse sRGB 1D
    ----------------------------
    <BLANKLINE>
    Dimensions : 1
    Domain     : [-0.1  1.5]
    Size       : (16,)
    Comment 01 : Generated by "Colour 0.3.11".
    Comment 02 : "colour.models.oetf_reverse_sRGB".

    Reading a 3D *Sony* *.spi3d* *LUT*:

    >>> path = os.path.join(
    ...     os.path.dirname(__file__), 'tests', 'resources', 'sony_spi3d',
    ...     'ColourCorrect.spi3d')
    >>> print(read_LUT(path))
    LUT3D - ColourCorrect
    ---------------------
    <BLANKLINE>
    Dimensions : 3
    Domain     : [[ 0.  0.  0.]
                  [ 1.  1.  1.]]
    Size       : (4, 4, 4, 3)
    Comment 01 : Adapted from a LUT generated by Foundry::LUT.
    """

    if method is None:
        method = EXTENSION_TO_LUT_FORMAT_MAPPING[os.path.splitext(path)[-1]]

    function = LUT_READ_METHODS[method]

    return function(path, **filter_kwargs(function, **kwargs))
Esempio n. 49
0
def delta_E(a, b, method='CIE 2000', **kwargs):
    """
    Returns the difference :math:`\\Delta E_{ab}` between two given
    *CIE L\\*a\\*b\\** or :math:`J'a'b'` colourspace arrays using given method.

    Parameters
    ----------
    a : array_like
        *CIE L\\*a\\*b\\** or :math:`J'a'b'` colourspace array :math:`a`.
    b : array_like
        *CIE L\\*a\\*b\\** or :math:`J'a'b'` colourspace array :math:`b`.
    method : unicode, optional
        **{'CIE 2000', 'CIE 1976', 'CIE 1994', 'CMC', 'CAM02-LCD', 'CAM02-SCD',
        'CAM02-UCS', 'CAM16-LCD', 'CAM16-SCD', 'CAM16-UCS', 'DIN99'}**
        Computation method.

    Other Parameters
    ----------------
    textiles : bool, optional
        {:func:`colour.difference.delta_E_CIE1994`,
        :func:`colour.difference.delta_E_CIE2000`,
        :func:`colour.difference.delta_E_DIN99`},
        Textiles application specific parametric factors
        :math:`k_L=2,\\ k_C=k_H=1,\\ k_1=0.048,\\ k_2=0.014,\\ k_E=2,\
\\ k_CH=0.5` weights are used instead of
        :math:`k_L=k_C=k_H=1,\\ k_1=0.045,\\ k_2=0.015,\\ k_E=k_CH=1.0`.
    l : numeric, optional
        {:func:`colour.difference.delta_E_CIE2000`},
        Lightness weighting factor.
    c : numeric, optional
        {:func:`colour.difference.delta_E_CIE2000`},
        Chroma weighting factor.

    Returns
    -------
    numeric or ndarray
        Colour difference :math:`\\Delta E_{ab}`.

    References
    ----------
    :cite:`ASTMInternational2007`, :cite:`Li2017`, :cite:`Lindbloom2003c`,
    :cite:`Lindbloom2011a`, :cite:`Lindbloom2009e`, :cite:`Lindbloom2009f`,
    :cite:`Luo2006b`, :cite:`Melgosa2013b`, :cite:`Wikipedia2008b`

    Examples
    --------
    >>> import numpy as np
    >>> a = np.array([100.00000000, 21.57210357, 272.22819350])
    >>> b = np.array([100.00000000, 426.67945353, 72.39590835])
    >>> delta_E(a, b)  # doctest: +ELLIPSIS
    94.0356490...
    >>> delta_E(a, b, method='CIE 2000')  # doctest: +ELLIPSIS
    94.0356490...
    >>> delta_E(a, b, method='CIE 1976')  # doctest: +ELLIPSIS
    451.7133019...
    >>> delta_E(a, b, method='CIE 1994')  # doctest: +ELLIPSIS
    83.7792255...
    >>> delta_E(a, b, method='CIE 1994', textiles=False)
    ... # doctest: +ELLIPSIS
    83.7792255...
    >>> delta_E(a, b, method='DIN99')  # doctest: +ELLIPSIS
    66.1119282...
    >>> a = np.array([54.90433134, -0.08450395, -0.06854831])
    >>> b = np.array([54.90433134, -0.08442362, -0.06848314])
    >>> delta_E(a, b, method='CAM02-UCS')  # doctest: +ELLIPSIS
    0.0001034...
    >>> delta_E(a, b, method='CAM16-LCD')  # doctest: +ELLIPSIS
    0.0001034...
    """

    function = DELTA_E_METHODS[method]

    return function(a, b, **filter_kwargs(function, **kwargs))
Esempio n. 50
0
def contrast_sensitivity_function(method='Barten 1999', **kwargs):
    """
    Returns the contrast sensitivity :math:`S` of the human eye according to
    the contrast sensitivity function (CSF) described by given method.

    Parameters
    ----------
    method : unicode, optional
        **{'Barten 1999'}**,
        Computation method.

    Other Parameters
    ----------------
    E : numeric or array_like, optional
        {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`},
        Retinal illuminance :math:`E` in Trolands.
    N_max : numeric or array_like, optional
        {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`},
        Maximum number of cycles :math:`N_{max}` over which the eye can
        integrate the information.
    T : numeric or array_like, optional
        {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`},
        Integration time :math:`T` in seconds of the eye.
    X_0 : numeric or array_like, optional
        {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`},
        Angular size :math:`X_0` in degrees of the object in the x direction.
    Y_0 : numeric or array_like, optional
        {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`},
        Angular size :math:`Y_0` in degrees of the object in the y direction.
    X_max : numeric or array_like, optional
        {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`},
        Maximum angular size :math:`X_{max}` in degrees of the integration
        area in the x direction.
    Y_max : numeric or array_like, optional
        {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`},
        Maximum angular size :math:`Y_{max}` in degrees of the integration
        area in the y direction.
    k : numeric or array_like, optional
        {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`},
        Signal-to-noise (SNR) ratio :math:`k`.
    n : numeric or array_like, optional
        {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`},
        Quantum efficiency of the eye :math:`n`.
    p : numeric or array_like, optional
        {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`},
        Photon conversion factor :math:`p` in
        :math:`photons\\div seconds\\div degrees^2\\div Trolands` that
        depends on the light source.
    phi_0 : numeric or array_like, optional
        {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`},
        Spectral density :math:`\\phi_0` in :math:`seconds degrees^2` of the
        neural noise.
    sigma : numeric or array_like, optional
        {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`},
        Standard deviation :math:`\\sigma` of the line-spread function
        resulting from the convolution of the different elements of the
        convolution process.
    u : numeric
        {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`},
        Spatial frequency :math:`u`, the cycles per degree.
    u_0 : numeric or array_like, optional
        {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`},
        Spatial frequency :math:`u_0` in :math:`cycles\\div degrees` above
        which the lateral inhibition ceases.

    Returns
    -------
    ndarray
        Contrast sensitivity :math:`S`.

    References
    ----------
    :cite:`Barten1999`, :cite:`Barten2003`, :cite:`Cowan2004`,
    :cite:`InternationalTelecommunicationUnion2015`,

    Examples
    --------
    >>> contrast_sensitivity_function(u=4)  # doctest: +ELLIPSIS
    360.8691122...
    >>> contrast_sensitivity_function('Barten 1999', u=4)  # doctest: +ELLIPSIS
    360.8691122...
    """

    function = CONTRAST_SENSITIVITY_METHODS[method]

    S = function(**filter_kwargs(function, **kwargs))

    return S
Esempio n. 51
0
def chromatic_adaptation(XYZ, XYZ_w, XYZ_wr, method='Von Kries', **kwargs):
    """
    Adapts given stimulus from test viewing conditions to reference viewing
    conditions.

    Parameters
    ----------
    XYZ : array_like
        *CIE XYZ* tristimulus values of stimulus to adapt.
    XYZ_w : array_like
        Test viewing condition *CIE XYZ* tristimulus values of the whitepoint.
    XYZ_wr : array_like
        Reference viewing condition *CIE XYZ* tristimulus values of the
        whitepoint.
    method : unicode, optional
        **{'Von Kries', 'CIE 1994', 'CMCCAT2000', 'Fairchild 1990'}**,
        Computation method.

    Other Parameters
    ----------------
    E_o1 : numeric
        {:func:`colour.adaptation.chromatic_adaptation_CIE1994`},
        Test illuminance :math:`E_{o1}` in :math:`cd/m^2`.
    E_o2 : numeric
        {:func:`colour.adaptation.chromatic_adaptation_CIE1994`},
        Reference illuminance :math:`E_{o2}` in :math:`cd/m^2`.
    L_A1 : numeric or array_like
        {:func:`colour.adaptation.chromatic_adaptation_CMCCAT2000`},
        Luminance of test adapting field :math:`L_{A1}` in :math:`cd/m^2`.
    L_A2 : numeric or array_like
        {:func:`colour.adaptation.chromatic_adaptation_CMCCAT2000`},
        Luminance of reference adapting field :math:`L_{A2}` in :math:`cd/m^2`.
    Y_n : numeric or array_like
        {:func:`colour.adaptation.chromatic_adaptation_Fairchild1990`},
        Luminance :math:`Y_n` of test adapting stimulus in :math:`cd/m^2`.
    Y_o : numeric
        {:func:`colour.adaptation.chromatic_adaptation_CIE1994`},
        Luminance factor :math:`Y_o` of achromatic background normalised to
        domain [0.18, 1] in **'Reference'** domain-range scale.
    direction : unicode, optional
        {:func:`colour.adaptation.chromatic_adaptation_CMCCAT2000`},
        **{'Forward', 'Reverse'}**,
        Chromatic adaptation direction.
    discount_illuminant : bool, optional
        {:func:`colour.adaptation.chromatic_adaptation_Fairchild1990`},
        Truth value indicating if the illuminant should be discounted.
    n : numeric, optional
        {:func:`colour.adaptation.chromatic_adaptation_CIE1994`},
        Noise component in fundamental primary system.
    surround : CMCCAT2000_InductionFactors, optional
        {:func:`colour.adaptation.chromatic_adaptation_CMCCAT2000`},
        Surround viewing conditions induction factors.
    transform : unicode, optional
        {:func:`colour.adaptation.chromatic_adaptation_VonKries`},
        **{'CAT02', 'XYZ Scaling', 'Von Kries', 'Bradford', 'Sharp',
        'Fairchild', 'CMCCAT97', 'CMCCAT2000', 'CAT02_BRILL_CAT', 'Bianco',
        'Bianco PC'}**,
        Chromatic adaptation transform.

    Returns
    -------
    ndarray
        *CIE XYZ_c* tristimulus values of the stimulus corresponding colour.

    Notes
    -----

    +------------+-----------------------+---------------+
    | **Domain** | **Scale - Reference** | **Scale - 1** |
    +============+=======================+===============+
    | ``XYZ``    | [0, 1]                | [0, 1]        |
    +------------+-----------------------+---------------+
    | ``XYZ_w``  | [0, 1]                | [0, 1]        |
    +------------+-----------------------+---------------+
    | ``XYZ_wr`` | [0, 1]                | [0, 1]        |
    +------------+-----------------------+---------------+
    | ``Y_o``    | [0, 1]                | [0, 1]        |
    +------------+-----------------------+---------------+

    +------------+-----------------------+---------------+
    | **Range**  | **Scale - Reference** | **Scale - 1** |
    +============+=======================+===============+
    | ``XYZ_c``  | [0, 1]                | [0, 1]        |
    +------------+-----------------------+---------------+

    References
    ----------
    :cite:`CIETC1-321994b`, :cite:`Fairchild1991a`, :cite:`Fairchild2013s`,
    :cite:`Fairchild2013t`, :cite:`Li2002a`, :cite:`Westland2012k`

    Examples
    --------

    *Von Kries* chromatic adaptation:

    >>> import numpy as np
    >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
    >>> XYZ_w = np.array([0.95045593, 1.00000000, 1.08905775])
    >>> XYZ_wr = np.array([0.96429568, 1.00000000, 0.82510460])
    >>> chromatic_adaptation(XYZ, XYZ_w, XYZ_wr)
    ... # doctest: +ELLIPSIS
    array([ 0.2163881...,  0.1257    ,  0.0384749...])

    *CIE 1994* chromatic adaptation, requires extra *kwargs*:

    >>> XYZ = np.array([0.2800, 0.2126, 0.0527])
    >>> XYZ_w = np.array([1.09867452, 1.00000000, 0.35591556])
    >>> XYZ_wr = np.array([0.95045593, 1.00000000, 1.08905775])
    >>> Y_o = 0.20
    >>> E_o = 1000
    >>> chromatic_adaptation(
    ...     XYZ, XYZ_w, XYZ_wr, method='CIE 1994', Y_o=Y_o, E_o1=E_o, E_o2=E_o)
    ... # doctest: +ELLIPSIS
    array([ 0.2403379...,  0.2115621...,  0.1764301...])

    *CMCCAT2000* chromatic adaptation, requires extra *kwargs*:

    >>> XYZ = np.array([0.2248, 0.2274, 0.0854])
    >>> XYZ_w = np.array([1.1115, 1.0000, 0.3520])
    >>> XYZ_wr = np.array([0.9481, 1.0000, 1.0730])
    >>> L_A = 200
    >>> chromatic_adaptation(
    ...     XYZ, XYZ_w, XYZ_wr, method='CMCCAT2000', L_A1=L_A, L_A2=L_A)
    ... # doctest: +ELLIPSIS
    array([ 0.1952698...,  0.2306834...,  0.2497175...])

    *Fairchild (1990)* chromatic adaptation, requires extra *kwargs*:

    >>> XYZ = np.array([0.1953, 0.2307, 0.2497])
    >>> Y_n = 200
    >>> chromatic_adaptation(
    ...     XYZ, XYZ_w, XYZ_wr, method='Fairchild 1990', Y_n=Y_n)
    ... # doctest: +ELLIPSIS
    array([ 0.2332526...,  0.2332455...,  0.7611593...])
    """

    function = CHROMATIC_ADAPTATION_METHODS[method]

    domain_range_reference = get_domain_range_scale() == 'reference'
    domain_100 = (chromatic_adaptation_CIE1994,
                  chromatic_adaptation_CMCCAT2000,
                  chromatic_adaptation_Fairchild1990)

    if function in domain_100 and domain_range_reference:
        XYZ = as_float_array(XYZ) * 100
        XYZ_w = as_float_array(XYZ_w) * 100
        XYZ_wr = as_float_array(XYZ_wr) * 100
        if kwargs.get('Y_o'):
            kwargs['Y_o'] = kwargs['Y_o'] * 100

    kwargs.update({'XYZ_w': XYZ_w, 'XYZ_wr': XYZ_wr})

    if function is chromatic_adaptation_CIE1994:
        from colour import XYZ_to_xy

        kwargs.update({'xy_o1': XYZ_to_xy(XYZ_w), 'xy_o2': XYZ_to_xy(XYZ_wr)})

    elif function is chromatic_adaptation_Fairchild1990:
        kwargs.update({'XYZ_n': XYZ_w, 'XYZ_r': XYZ_wr})

    XYZ_c = function(XYZ, **filter_kwargs(function, **kwargs))

    if function in domain_100 and domain_range_reference:
        XYZ_c /= 100

    return XYZ_c
Esempio n. 52
0
def eotf(value, function='ITU-R BT.1886', **kwargs):
    """
    Decodes :math:`R'G'B'` video component signal value to tristimulus values
    at the display using given electro-optical transfer function (EOTF / EOCF).

    Parameters
    ----------
    value : numeric or array_like
        Value.
    function : unicode, optional
        **{'ITU-R BT.1886', 'DCDM', 'DICOM GSDF', 'ITU-R BT.2020',
        'ITU-R BT.2100 HLG', 'ITU-R BT.2100 PQ', 'ProPhoto RGB', 'RIMM RGB',
        'ROMM RGB', 'SMPTE 240M', 'ST 2084'}**,
        Electro-optical transfer function (EOTF / EOCF).

    Other Parameters
    ----------------
    E_clip : numeric, optional
        {:func:`colour.models.eotf_RIMMRGB`},
        Maximum exposure level.
    I_max : numeric, optional
        {:func:`colour.models.eotf_ROMMRGB`,
        :func:`colour.models.eotf_RIMMRGB`},
        Maximum code value: 255, 4095 and 650535 for respectively 8-bit,
        12-bit and 16-bit per channel.
    L_B : numeric, optional
        {:func:`colour.models.eotf_BT1886`,
        :func:`colour.models.eotf_BT2100_HLG`},
        Screen luminance for black.
    L_W : numeric, optional
        {:func:`colour.models.eotf_BT1886`,
        :func:`colour.models.eotf_BT2100_HLG`},
        Screen luminance for white.
    L_p : numeric, optional
        {:func:`colour.models.eotf_ST2084`},
        Display peak luminance :math:`cd/m^2`.
    gamma : numeric, optional
        {:func:`colour.models.eotf_BT2100_HLG`},
        System gamma value, 1.2 at the nominal display peak luminance of
        :math:`1000 cd/m^2`.
    is_12_bits_system : bool
        {:func:`colour.models.eotf_BT2020`},
        *ITU-R BT.2020* *alpha* and *beta* constants are used if system is not
        12-bit.

    Returns
    -------
    numeric or ndarray
        Tristimulus values at the display.

    Examples
    --------
    >>> eotf(0.461356129500442)  # doctest: +ELLIPSIS
    0.1...
    >>> eotf(0.409007728864150, function='ITU-R BT.2020')
    ... # doctest: +ELLIPSIS
    0.1...
    >>> eotf(0.182011532850008, function='ST 2084', L_p=1000)
    ... # doctest: +ELLIPSIS
    0.1...
    """

    function = EOTFS[function]

    return function(value, **filter_kwargs(function, **kwargs))
Esempio n. 53
0
def scattering_cross_section(wavelength,
                             CO2_concentration=STANDARD_CO2_CONCENTRATION,
                             temperature=STANDARD_AIR_TEMPERATURE,
                             avogadro_constant=AVOGADRO_CONSTANT,
                             n_s=air_refraction_index_Bodhaine1999,
                             F_air=F_air_Bodhaine1999):
    """
    Returns the scattering cross section per molecule :math:`\\sigma` of dry
    air as function of wavelength :math:`\\lambda` in centimeters (cm) using
    given :math:`CO_2` concentration in parts per million (ppm) and temperature
    :math:`T[K]` in kelvin degrees following *Van de Hulst (1957)* method.

    Parameters
    ----------
    wavelength : numeric or array_like
        Wavelength :math:`\\lambda` in centimeters (cm).
    CO2_concentration : numeric or array_like, optional
        :math:`CO_2` concentration in parts per million (ppm).
    temperature : numeric or array_like, optional
        Air temperature :math:`T[K]` in kelvin degrees.
    avogadro_constant : numeric or array_like, optional
        *Avogadro*'s number (molecules :math:`mol^{-1}`).
    n_s : object
        Air refraction index :math:`n_s` computation method.
    F_air : object
        :math:`(6+3_p)/(6-7_p)`, the depolarisation term :math:`F(air)` or
        *King Factor* computation method.

    Returns
    -------
    numeric or ndarray
        Scattering cross section per molecule :math:`\\sigma` of dry air.

    Warning
    -------
    Unlike most objects of :mod:`colour.phenomena.rayleigh` module,
    :func:`colour.scattering_cross_section` expects wavelength :math:`\\lambda`
    to be expressed in centimeters (cm).

    References
    ----------
    :cite:`Bodhaine1999a`, :cite:`Wikipedia2001c`

    Examples
    --------
    >>> scattering_cross_section(555 * 10e-8)  # doctest: +ELLIPSIS
    4.6613309...e-27
    """

    wl = as_float_array(wavelength)
    CO2_c = as_float_array(CO2_concentration)
    temperature = as_float_array(temperature)

    wl_micrometers = wl * 10e3

    n_s = n_s(wl_micrometers)
    # n_s = n_s(**filter_kwargs(
    #     n_s, wavelength=wl_micrometers, CO2_concentration=CO2_c))
    N_s = molecular_density(temperature, avogadro_constant)
    F_air = F_air(**filter_kwargs(
        F_air, wavelength=wl_micrometers, CO2_concentration=CO2_c))

    sigma = (24 * np.pi ** 3 * (n_s ** 2 - 1) ** 2 / (wl ** 4 * N_s ** 2 *
                                                      (n_s ** 2 + 2) ** 2))
    sigma *= F_air

    return sigma
Esempio n. 54
0
def log_decoding_curve(value, curve='Cineon', **kwargs):
    """
    Decodes :math:`R'G'B'` video component signal value to linear-light values
    using given *log* curve.

    Parameters
    ----------
    value : numeric or array_like
        Value.
    curve : unicode, optional
        **{'ACEScc', 'ACEScct', 'ACESproxy', 'ALEXA Log C', 'Canon Log 2',
        'Canon Log 3', 'Canon Log', 'Cineon', 'D-Log', 'ERIMM RGB',
        'Filmic Pro 6', 'Log3G10', 'Log3G12', 'Panalog', 'PLog', 'Protune',
        'REDLog', 'REDLogFilm', 'S-Log', 'S-Log2', 'S-Log3', 'T-Log',
        'V-Log', 'ViperLog'}**,
        Computation curve.

    Other Parameters
    ----------------
    EI : int,  optional
        {:func:`colour.models.log_decoding_ALEXALogC`},
        Ei.
    E_clip : numeric, optional
        {:func:`colour.models.log_decoding_ERIMMRGB`},
        Maximum exposure limit.
    E_min : numeric, optional
        {:func:`colour.models.log_decoding_ERIMMRGB`},
        Minimum exposure limit.
    I_max : numeric, optional
        {:func:`colour.models.log_decoding_ERIMMRGB`},
        Maximum code value: 255, 4095 and 650535 for respectively 8-bit,
        12-bit and 16-bit per channel.
    bit_depth : int, optional
        {:func:`colour.models.log_decoding_ACESproxy`,
        :func:`colour.models.log_decoding_SLog`,
        :func:`colour.models.log_decoding_SLog2`},
        **{8, 10, 12}**,
        Bit depth used for conversion, *ACESproxy* uses **{10, 12}**.
    black_offset : numeric or array_like
        {:func:`colour.models.log_decoding_Cineon`,
        :func:`colour.models.log_decoding_Panalog`,
        :func:`colour.models.log_decoding_REDLog`,
        :func:`colour.models.log_decoding_REDLogFilm`},
        Black offset.
    density_per_code_value : numeric or array_like
        {:func:`colour.models.log_decoding_PivotedLog`},
        Density per code value.
    firmware : unicode, optional
        {:func:`colour.models.log_decoding_ALEXALogC`},
        **{'SUP 3.x', 'SUP 2.x'}**,
        Alexa firmware version.
    in_legal : bool, optional
        {:func:`colour.models.log_decoding_SLog`,
        :func:`colour.models.log_decoding_SLog2`,
        :func:`colour.models.log_decoding_SLog3`},
        Whether the non-linear *Sony S-Log*, *Sony S-Log2* or *Sony S-Log3*
        data :math:`y` is encoded in legal range.
    linear_reference : numeric or array_like
        {:func:`colour.models.log_decoding_PivotedLog`},
        Linear reference.
    log_reference : numeric or array_like
        {:func:`colour.models.log_decoding_PivotedLog`},
        Log reference.
    negative_gamma : numeric or array_like
        {:func:`colour.models.log_decoding_PivotedLog`},
        Negative gamma.
    out_reflection : bool, optional
        {:func:`colour.models.log_decoding_SLog`,
        :func:`colour.models.log_decoding_SLog2`},
        Whether the light level :math:`x` to a camera is reflection.
    method : unicode, optional
        {:func:`colour.models.log_decoding_ALEXALogC`},
        **{'Linear Scene Exposure Factor', 'Normalised Sensor Signal'}**,
        Conversion method.

    Returns
    -------
    numeric or ndarray
        *Log* value.

    Examples
    --------
    >>> log_decoding_curve(0.457319613085418)  # doctest: +ELLIPSIS
    0.1...
    >>> log_decoding_curve(0.413588402492442, curve='ACEScc')
    ... # doctest: +ELLIPSIS
    0.1...
    >>> log_decoding_curve(0.391006842619746, curve='PLog', log_reference=400)
    ... # doctest: +ELLIPSIS
    0.1...
    >>> log_decoding_curve(0.376512722254600, curve='S-Log')
    ... # doctest: +ELLIPSIS
    0.1...
    """

    function = LOG_DECODING_CURVES[curve]

    return function(value, **filter_kwargs(function, **kwargs))
Esempio n. 55
0
def whiteness(XYZ, XYZ_0, method='CIE 2004', **kwargs):
    """
    Returns the *whiteness* :math:`W` using given method.

    Parameters
    ----------
    XYZ : array_like
        *CIE XYZ* tristimulus values of sample.
    XYZ_0 : array_like
        *CIE XYZ* tristimulus values of reference white.
    method : unicode, optional
        **{'CIE 2004', 'Berger 1959', 'Taube 1960', 'Stensby 1968',
        'ASTM E313', 'Ganz 1979'}**,
        Computation method.

    Other Parameters
    ----------------
    observer : unicode, optional
        {:func:`colour.colorimetry.whiteness_CIE2004`},
        **{'CIE 1931 2 Degree Standard Observer',
        'CIE 1964 10 Degree Standard Observer'}**,
        *CIE Standard Observer* used for computations, *tint* :math:`T` or
        :math:`T_{10}` value is dependent on viewing field angular subtense.

    Returns
    -------
    numeric or ndarray
        *whiteness* :math:`W`.

    Notes
    -----

    +------------+-----------------------+-----------------+
    | **Domain** | **Scale - Reference** |   **Scale - 1** |
    +============+=======================+=================+
    +------------+-----------------------+-----------------+
    | ``XYZ``    | [0, 100]              |   [0, 1]        |
    +------------+-----------------------+-----------------+
    | ``XYZ_0``  | [0, 100]              |   [0, 1]        |
    +------------+-----------------------+-----------------+

    +------------+-----------------------+-----------------+
    | **Range**  | **Scale - Reference** |   **Scale - 1** |
    +============+=======================+=================+
    | ``W``      | [0, 100]              |   [0, 1]        |
    +------------+-----------------------+-----------------+

    References
    ----------
    :cite:`CIETC1-482004k`, :cite:`Wyszecki2000ba`, :cite:`X-Rite2012a`,
    :cite:`Wikipedia2004b`

    Examples
    --------
    >>> import numpy as np
    >>> from colour.models import xyY_to_XYZ
    >>> XYZ = xyY_to_XYZ(np.array([0.3167, 0.3334, 100]))
    >>> XYZ_0 = xyY_to_XYZ(np.array([0.3139, 0.3311, 100]))
    >>> whiteness(XYZ, XYZ_0)  # doctest: +ELLIPSIS
    array([ 93.85...,  -1.305...])
    >>> XYZ = np.array([95.00000000, 100.00000000, 105.00000000])
    >>> XYZ_0 = np.array([94.80966767, 100.00000000, 107.30513595])
    >>> whiteness(XYZ, XYZ_0, method='Taube 1960')  # doctest: +ELLIPSIS
    91.4071738...
    """

    kwargs.update({'XYZ': XYZ, 'XYZ_0': XYZ_0})

    function = WHITENESS_METHODS.get(method)

    if function is whiteness_Stensby1968:
        from colour.models import XYZ_to_Lab, XYZ_to_xy

        if get_domain_range_scale() == 'reference':
            XYZ = XYZ / 100
            XYZ_0 = XYZ_0 / 100

        kwargs.update({'Lab': XYZ_to_Lab(XYZ, XYZ_to_xy(XYZ_0))})
    elif function in (whiteness_Ganz1979, whiteness_CIE2004):
        from colour.models import XYZ_to_xy

        _X_0, Y_0, _Z_0 = tsplit(XYZ_0)
        kwargs.update({
            'xy': XYZ_to_xy(XYZ),
            'Y': Y_0,
            'xy_n': XYZ_to_xy(XYZ_0)
        })

    return function(**filter_kwargs(function, **kwargs))