示例#1
0
    def test_nan_eotf_inverse_ST2084(self):
        """
        Tests :func:`colour.models.rgb.transfer_functions.st_2084.\
eotf_inverse_ST2084` definition nan support.
        """

        eotf_inverse_ST2084(
            np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]))
示例#2
0
    def test_domain_range_scale_eotf_inverse_ST2084(self):
        """
        Tests :func:`colour.models.rgb.transfer_functions.st_2084.\
eotf_inverse_ST2084` definition domain and range scale support.
        """

        C = 100
        N = eotf_inverse_ST2084(C)

        d_r = (('reference', 1), (1, 1), (100, 100))
        for scale, factor in d_r:
            with domain_range_scale(scale):
                np.testing.assert_almost_equal(
                    eotf_inverse_ST2084(C * factor), N * factor, decimal=7)
示例#3
0
    def test_eotf_inverse_ST2084(self):
        """
        Tests :func:`colour.models.rgb.transfer_functions.st_2084.\
eotf_inverse_ST2084` definition.
        """

        self.assertAlmostEqual(
            eotf_inverse_ST2084(0.0), 0.000000730955903, places=7)

        self.assertAlmostEqual(
            eotf_inverse_ST2084(100), 0.508078421517399, places=7)

        self.assertAlmostEqual(
            eotf_inverse_ST2084(400), 0.652578597563067, places=7)

        self.assertAlmostEqual(eotf_inverse_ST2084(5000, 5000), 1.0, places=7)
示例#4
0
文件: ictcp.py 项目: yixw/colour
def RGB_to_ICTCP(RGB, L_p=10000):
    """
    Converts from *ITU-R BT.2020* colourspace to :math:`IC_TC_P` colour
    encoding.

    Parameters
    ----------
    RGB : array_like
        *ITU-R BT.2020* colourspace array.
    L_p : numeric, optional
        Display peak luminance :math:`cd/m^2` for *SMPTE ST 2084:2014*
        non-linear encoding.

    Returns
    -------
    ndarray
        :math:`IC_TC_P` colour encoding array.

    Notes
    -----

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

    +------------+-----------------------+------------------+
    | **Range**  | **Scale - Reference** | **Scale - 1**    |
    +============+=======================+==================+
    | ``ICTCP``  | ``I``  : [0, 1]       | ``I``  : [0, 1]  |
    |            |                       |                  |
    |            | ``CT`` : [-1, 1]      | ``CT`` : [-1, 1] |
    |            |                       |                  |
    |            | ``CP`` : [-1, 1]      | ``CP`` : [-1, 1] |
    +------------+-----------------------+------------------+

    References
    ----------
    :cite:`Dolby2016a`, :cite:`Lu2016c`

    Examples
    --------
    >>> RGB = np.array([0.45620519, 0.03081071, 0.04091952])
    >>> RGB_to_ICTCP(RGB)  # doctest: +ELLIPSIS
    array([ 0.0735136...,  0.0047525...,  0.0935159...])
    """

    RGB = to_domain_1(RGB)

    LMS = dot_vector(ICTCP_RGB_TO_LMS_MATRIX, RGB)

    with domain_range_scale('ignore'):
        LMS_p = eotf_inverse_ST2084(LMS, L_p)

    ICTCP = dot_vector(ICTCP_LMS_P_TO_ICTCP_MATRIX, LMS_p)

    return from_range_1(ICTCP)
示例#5
0
    def test_n_dimensional_eotf_inverse_ST2084(self):
        """
        Test :func:`colour.models.rgb.transfer_functions.st_2084.\
eotf_inverse_ST2084` definition n-dimensional arrays support.
        """

        C = 100
        N = eotf_inverse_ST2084(C)

        C = np.tile(C, 6)
        N = np.tile(N, 6)
        np.testing.assert_almost_equal(eotf_inverse_ST2084(C), N, decimal=7)

        C = np.reshape(C, (2, 3))
        N = np.reshape(N, (2, 3))
        np.testing.assert_almost_equal(eotf_inverse_ST2084(C), N, decimal=7)

        C = np.reshape(C, (2, 3, 1))
        N = np.reshape(N, (2, 3, 1))
        np.testing.assert_almost_equal(eotf_inverse_ST2084(C), N, decimal=7)
示例#6
0
def XYZ_to_ICaCb(XYZ: ArrayLike) -> NDArray:
    """
    Convert from *CIE XYZ* tristimulus values to :math:`IC_AC_B` colourspace.

    Parameters
    ----------
    XYZ
        *CIE XYZ* tristimulus values.

    Returns
    -------
    :class:`numpy.ndarray`
        :math:`IC_AC_B` colourspace array.

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

    +------------+-----------------------+-----------------+
    | **Range**  | **Scale - Reference** | **Scale - 1**   |
    +============+=======================+=================+
    | ``ICaCb``  | ``I`` : [0, 1]        | ``I`` : [0, 1]  |
    |            |                       |                 |
    |            | ``Ca`` : [-1, 1]      | ``Ca``: [-1, 1] |
    |            |                       |                 |
    |            | ``Cb`` : [-1, 1]      | ``Cb``: [-1, 1] |
    +------------+-----------------------+-----------------+

    -   Input *CIE XYZ* tristimulus values must be adapted to
        *CIE Standard Illuminant D Series* *D65*.

    References
    ----------
    :cite:`Frohlich2017`

    Examples
    --------
    >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
    >>> XYZ_to_ICaCb(XYZ)
    array([ 0.06875297,  0.05753352,  0.02081548])
    """

    XYZ = to_domain_1(XYZ)
    LMS = vector_dot(MATRIX_ICACB_XYZ_TO_LMS, XYZ)

    with domain_range_scale("ignore"):
        LMS_prime = eotf_inverse_ST2084(LMS)

    return from_range_1(vector_dot(MATRIX_ICACB_XYZ_TO_LMS_2, LMS_prime))
示例#7
0
def XYZ_to_JzAzBz(XYZ_D65, constants=JZAZBZ_CONSTANTS):
    """
    Converts from *CIE XYZ* tristimulus values to :math:`J_zA_zB_z`
    colourspace.

    Parameters
    ----------
    XYZ_D65 : array_like
        *CIE XYZ* tristimulus values under
        *CIE Standard Illuminant D Series D65*.
    constants : Structure, optional
        :math:`J_zA_zB_z` colourspace constants.

    Returns
    -------
    ndarray
        :math:`J_zA_zB_z` colourspace array where :math:`J_z` is Lightness,
        :math:`A_z` is redness-greenness and :math:`B_z` is
        yellowness-blueness.

    Notes
    -----

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

    +------------+-----------------------+------------------+
    | **Range**  | **Scale - Reference** | **Scale - 1**    |
    +============+=======================+==================+
    | ``JzAzBz`` | ``Jz`` : [0, 1]       | ``Jz`` : [0, 1]  |
    |            |                       |                  |
    |            | ``Az`` : [-1, 1]      | ``Az`` : [-1, 1] |
    |            |                       |                  |
    |            | ``Bz`` : [-1, 1]      | ``Bz`` : [-1, 1] |
    +------------+-----------------------+------------------+

    References
    ----------
    :cite:`Safdar2017`

    Examples
    --------
    >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
    >>> XYZ_to_JzAzBz(XYZ)  # doctest: +ELLIPSIS
    array([ 0.0053504...,  0.0092430...,  0.0052600...])
    """

    X_D65, Y_D65, Z_D65 = tsplit(to_domain_1(XYZ_D65))

    X_p_D65 = constants.b * X_D65 - (constants.b - 1) * Z_D65
    Y_p_D65 = constants.g * Y_D65 - (constants.g - 1) * X_D65

    XYZ_p_D65 = tstack([X_p_D65, Y_p_D65, Z_D65])

    LMS = dot_vector(JZAZBZ_XYZ_TO_LMS_MATRIX, XYZ_p_D65)

    with domain_range_scale('ignore'):
        LMS_p = eotf_inverse_ST2084(LMS, 10000, constants)

    I_z, A_z, B_z = tsplit(dot_vector(JZAZBZ_LMS_P_TO_IZAZBZ_MATRIX, LMS_p))

    J_z = ((1 + constants.d) * I_z) / (1 + constants.d * I_z) - constants.d_0

    JzAzBz = tstack([J_z, A_z, B_z])

    return from_range_1(JzAzBz)
示例#8
0
文件: jzazbz.py 项目: wenh06/colour
def XYZ_to_JzAzBz(XYZ_D65, constants=CONSTANTS_JZAZBZ):
    """
    Converts from *CIE XYZ* tristimulus values to :math:`J_zA_zB_z`
    colourspace.

    Parameters
    ----------
    XYZ_D65 : array_like
        *CIE XYZ* tristimulus values under
        *CIE Standard Illuminant D Series D65*.
    constants : Structure, optional
        :math:`J_zA_zB_z` colourspace constants.

    Returns
    -------
    ndarray
        :math:`J_zA_zB_z` colourspace array where :math:`J_z` is Lightness,
        :math:`A_z` is redness-greenness and :math:`B_z` is
        yellowness-blueness.

    Warnings
    --------
    The underlying *SMPTE ST 2084:2014* transfer function is an absolute
    transfer function.

    Notes
    -----

    -   The underlying *SMPTE ST 2084:2014* transfer function is an absolute
        transfer function, thus the domain and range values for the *Reference*
        and *1* scales are only indicative that the data is not affected by
        scale transformations. The effective domain of *SMPTE ST 2084:2014*
        inverse electro-optical transfer function (EOTF / EOCF) is
        [0.0001, 10000].

    +------------+-----------------------+------------------+
    | **Domain** | **Scale - Reference** | **Scale - 1**    |
    +============+=======================+==================+
    | ``XYZ``    | ``UN``                | ``UN``           |
    +------------+-----------------------+------------------+

    +------------+-----------------------+------------------+
    | **Range**  | **Scale - Reference** | **Scale - 1**    |
    +============+=======================+==================+
    | ``JzAzBz`` | ``Jz`` : [0, 1]       | ``Jz`` : [0, 1]  |
    |            |                       |                  |
    |            | ``Az`` : [-1, 1]      | ``Az`` : [-1, 1] |
    |            |                       |                  |
    |            | ``Bz`` : [-1, 1]      | ``Bz`` : [-1, 1] |
    +------------+-----------------------+------------------+

    References
    ----------
    :cite:`Safdar2017`

    Examples
    --------
    >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
    >>> XYZ_to_JzAzBz(XYZ)  # doctest: +ELLIPSIS
    array([ 0.0053504...,  0.0092430...,  0.0052600...])
    """

    X_D65, Y_D65, Z_D65 = tsplit(to_domain_1(XYZ_D65))

    X_p_D65 = constants.b * X_D65 - (constants.b - 1) * Z_D65
    Y_p_D65 = constants.g * Y_D65 - (constants.g - 1) * X_D65

    XYZ_p_D65 = tstack([X_p_D65, Y_p_D65, Z_D65])

    LMS = vector_dot(MATRIX_JZAZBZ_XYZ_TO_LMS, XYZ_p_D65)

    with domain_range_scale('ignore'):
        LMS_p = eotf_inverse_ST2084(LMS, 10000, constants)

    I_z, A_z, B_z = tsplit(vector_dot(MATRIX_JZAZBZ_LMS_P_TO_IZAZBZ, LMS_p))

    J_z = ((1 + constants.d) * I_z) / (1 + constants.d * I_z) - constants.d_0

    JzAzBz = tstack([J_z, A_z, B_z])

    return from_range_1(JzAzBz)
示例#9
0
def RGB_to_ICtCp(
    RGB: ArrayLike,
    method: Union[Literal["Dolby 2016", "ITU-R BT.2100-1 HLG",
                          "ITU-R BT.2100-1 PQ", "ITU-R BT.2100-2 HLG",
                          "ITU-R BT.2100-2 PQ", ], str, ] = "Dolby 2016",
    L_p: Floating = 10000,
) -> NDArray:
    """
    Convert from *ITU-R BT.2020* colourspace to :math:`IC_TC_P` colour
    encoding.

    Parameters
    ----------
    RGB
        *ITU-R BT.2020* colourspace array.
    method
        Computation method. *Recommendation ITU-R BT.2100* defines multiple
        variants of the :math:`IC_TC_P` colour encoding:

        -   *ITU-R BT.2100-1*

            -   *SMPTE ST 2084:2014* inverse electro-optical transfer
                function (EOTF) and the :math:`IC_TC_P` matrix from
                :cite:`Dolby2016a`: *Dolby 2016*, *ITU-R BT.2100-1 PQ*,
                *ITU-R BT.2100-2 PQ* methods.
            -   *Recommendation ITU-R BT.2100* *Reference HLG* opto-electrical
                transfer function (OETF) and the :math:`IC_TC_P` matrix
                from :cite:`Dolby2016a`: *ITU-R BT.2100-1 HLG* method.

        -   *ITU-R BT.2100-2*

            -   *SMPTE ST 2084:2014* inverse electro-optical transfer
                function (EOTF) and the :math:`IC_TC_P` matrix from
                :cite:`Dolby2016a`: *Dolby 2016*, *ITU-R BT.2100-1 PQ*,
                *ITU-R BT.2100-2 PQ* methods.
            -   *Recommendation ITU-R BT.2100* *Reference HLG* opto-electrical
                transfer function (OETF) and a custom :math:`IC_TC_P`
                matrix from :cite:`InternationalTelecommunicationUnion2018`:
                *ITU-R BT.2100-2 HLG* method.

    L_p
        Display peak luminance :math:`cd/m^2` for *SMPTE ST 2084:2014*
        non-linear encoding. This parameter should stay at its default
        :math:`10000 cd/m^2` value for practical applications. It is exposed so
        that the definition can be used as a fitting function.

    Returns
    -------
    :class:`numpy.ndarray`
        :math:`IC_TC_P` colour encoding array.

    Warnings
    --------
    The underlying *SMPTE ST 2084:2014* transfer function is an absolute
    transfer function.

    Notes
    -----
    -   The *ITU-R BT.2100-1 PQ* and *ITU-R BT.2100-2 PQ* methods are aliases
        for the *Dolby 2016* method.
    -   The underlying *SMPTE ST 2084:2014* transfer function is an absolute
        transfer function, thus the domain and range values for the *Reference*
        and *1* scales are only indicative that the data is not affected by
        scale transformations. The effective domain of *SMPTE ST 2084:2014*
        inverse electro-optical transfer function (EOTF) is
        [0.0001, 10000].

    +------------+-----------------------+------------------+
    | **Domain** | **Scale - Reference** | **Scale - 1**    |
    +============+=======================+==================+
    | ``RGB``    | ``UN``                | ``UN``           |
    +------------+-----------------------+------------------+

    +------------+-----------------------+------------------+
    | **Range**  | **Scale - Reference** | **Scale - 1**    |
    +============+=======================+==================+
    | ``ICtCp``  | ``I``  : [0, 1]       | ``I``  : [0, 1]  |
    |            |                       |                  |
    |            | ``CT`` : [-1, 1]      | ``CT`` : [-1, 1] |
    |            |                       |                  |
    |            | ``CP`` : [-1, 1]      | ``CP`` : [-1, 1] |
    +------------+-----------------------+------------------+

    References
    ----------
    :cite:`Dolby2016a`, :cite:`Lu2016c`

    Examples
    --------
    >>> RGB = np.array([0.45620519, 0.03081071, 0.04091952])
    >>> RGB_to_ICtCp(RGB)  # doctest: +ELLIPSIS
    array([ 0.0735136...,  0.0047525...,  0.0935159...])
    >>> RGB_to_ICtCp(RGB, method='ITU-R BT.2100-2 HLG')  # doctest: +ELLIPSIS
    array([ 0.6256789..., -0.0198449...,  0.3591125...])
    """

    RGB = as_float_array(RGB)
    method = validate_method(
        method,
        [
            "Dolby 2016",
            "ITU-R BT.2100-1 HLG",
            "ITU-R BT.2100-1 PQ",
            "ITU-R BT.2100-2 HLG",
            "ITU-R BT.2100-2 PQ",
        ],
    )

    is_hlg_method = "hlg" in method
    is_BT2100_2_method = "2100-2" in method

    LMS = vector_dot(MATRIX_ICTCP_RGB_TO_LMS, RGB)

    with domain_range_scale("ignore"):
        LMS_p = (oetf_HLG_BT2100(LMS)
                 if is_hlg_method else eotf_inverse_ST2084(LMS, L_p))

    ICtCp = (vector_dot(MATRIX_ICTCP_LMS_P_TO_ICTCP_HLG_BT2100_2, LMS_p) if
             (is_hlg_method and is_BT2100_2_method) else vector_dot(
                 MATRIX_ICTCP_LMS_P_TO_ICTCP, LMS_p))

    return ICtCp
示例#10
0
文件: ictcp.py 项目: wenh06/colour
def RGB_to_ICTCP(RGB, L_p=10000):
    """
    Converts from *ITU-R BT.2020* colourspace to :math:`IC_TC_P` colour
    encoding.

    Parameters
    ----------
    RGB : array_like
        *ITU-R BT.2020* colourspace array.
    L_p : numeric, optional
        Display peak luminance :math:`cd/m^2` for *SMPTE ST 2084:2014*
        non-linear encoding. This parameter should stay at its default
        :math:`10000 cd/m^2` value for practical applications. It is exposed so
        that the definition can be used as a fitting function.

    Returns
    -------
    ndarray
        :math:`IC_TC_P` colour encoding array.

    Warnings
    --------
    The underlying *SMPTE ST 2084:2014* transfer function is an absolute
    transfer function.

    Notes
    -----

    -   The underlying *SMPTE ST 2084:2014* transfer function is an absolute
        transfer function, thus the domain and range values for the *Reference*
        and *1* scales are only indicative that the data is not affected by
        scale transformations. The effective domain of *SMPTE ST 2084:2014*
        inverse electro-optical transfer function (EOTF / EOCF) is
        [0.0001, 10000].

    +------------+-----------------------+------------------+
    | **Domain** | **Scale - Reference** | **Scale - 1**    |
    +============+=======================+==================+
    | ``RGB``    | ``UN``                | ``UN``           |
    +------------+-----------------------+------------------+

    +------------+-----------------------+------------------+
    | **Range**  | **Scale - Reference** | **Scale - 1**    |
    +============+=======================+==================+
    | ``ICTCP``  | ``I``  : [0, 1]       | ``I``  : [0, 1]  |
    |            |                       |                  |
    |            | ``CT`` : [-1, 1]      | ``CT`` : [-1, 1] |
    |            |                       |                  |
    |            | ``CP`` : [-1, 1]      | ``CP`` : [-1, 1] |
    +------------+-----------------------+------------------+

    References
    ----------
    :cite:`Dolby2016a`, :cite:`Lu2016c`

    Examples
    --------
    >>> RGB = np.array([0.45620519, 0.03081071, 0.04091952])
    >>> RGB_to_ICTCP(RGB)  # doctest: +ELLIPSIS
    array([ 0.0735136...,  0.0047525...,  0.0935159...])
    """

    RGB = to_domain_1(RGB)

    LMS = vector_dot(MATRIX_ICTCP_RGB_TO_LMS, RGB)

    with domain_range_scale('ignore'):
        LMS_p = eotf_inverse_ST2084(LMS, L_p)

    ICTCP = vector_dot(MATRIX_ICTCP_LMS_P_TO_ICTCP, LMS_p)

    return from_range_1(ICTCP)
示例#11
0
def XYZ_to_Izazbz(
    XYZ_D65: ArrayLike,
    constants: Optional[Structure] = None,
    method: Union[
        Literal["Safdar 2017", "Safdar 2021", "ZCAM"], str
    ] = "Safdar 2017",
) -> NDArray:
    """
    Convert from *CIE XYZ* tristimulus values to :math:`I_za_zb_z`
    colourspace.

    Parameters
    ----------
    XYZ_D65
        *CIE XYZ* tristimulus values under
        *CIE Standard Illuminant D Series D65*.
    constants
        :math:`J_za_zb_z` colourspace constants.
    method
        Computation methods, *Safdar 2021* and *ZCAM* methods are equivalent.

    Returns
    -------
    :class:`numpy.ndarray`
        :math:`I_za_zb_z` colourspace array where :math:`I_z` is the achromatic
        response, :math:`a_z` is redness-greenness and :math:`b_z` is
        yellowness-blueness.

    Warnings
    --------
    The underlying *SMPTE ST 2084:2014* transfer function is an absolute
    transfer function.

    Notes
    -----
    -   The underlying *SMPTE ST 2084:2014* transfer function is an absolute
        transfer function, thus the domain and range values for the *Reference*
        and *1* scales are only indicative that the data is not affected by
        scale transformations. The effective domain of *SMPTE ST 2084:2014*
        inverse electro-optical transfer function (EOTF) is
        [0.0001, 10000].

    +------------+-----------------------+------------------+
    | **Domain** | **Scale - Reference** | **Scale - 1**    |
    +============+=======================+==================+
    | ``XYZ``    | ``UN``                | ``UN``           |
    +------------+-----------------------+------------------+

    +------------+-----------------------+------------------+
    | **Range**  | **Scale - Reference** | **Scale - 1**    |
    +============+=======================+==================+
    | ``Izazbz`` | ``Iz`` : [0, 1]       | ``Iz`` : [0, 1]  |
    |            |                       |                  |
    |            | ``az`` : [-1, 1]      | ``az`` : [-1, 1] |
    |            |                       |                  |
    |            | ``bz`` : [-1, 1]      | ``bz`` : [-1, 1] |
    +------------+-----------------------+------------------+

    References
    ----------
    :cite:`Safdar2017`, :cite:`Safdar2021`

    Examples
    --------
    >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
    >>> XYZ_to_Izazbz(XYZ)  # doctest: +ELLIPSIS
    array([ 0.0120779...,  0.0092430...,  0.0052600...])
    """

    X_D65, Y_D65, Z_D65 = tsplit(as_float_array(XYZ_D65))

    method = validate_method(method, IZAZBZ_METHODS)

    constants = optional(
        constants,
        CONSTANTS_JZAZBZ_SAFDAR2017
        if method == "safdar 2017"
        else CONSTANTS_JZAZBZ_SAFDAR2021,
    )

    X_p_D65 = constants.b * X_D65 - (constants.b - 1) * Z_D65
    Y_p_D65 = constants.g * Y_D65 - (constants.g - 1) * X_D65

    XYZ_p_D65 = tstack([X_p_D65, Y_p_D65, Z_D65])

    LMS = vector_dot(MATRIX_JZAZBZ_XYZ_TO_LMS, XYZ_p_D65)

    with domain_range_scale("ignore"):
        LMS_p = eotf_inverse_ST2084(LMS, 10000, constants)

    if method == "safdar 2017":
        Izazbz = vector_dot(MATRIX_JZAZBZ_LMS_P_TO_IZAZBZ_SAFDAR2017, LMS_p)
    else:
        Izazbz = vector_dot(MATRIX_JZAZBZ_LMS_P_TO_IZAZBZ_SAFDAR2021, LMS_p)
        Izazbz[..., 0] -= constants.d_0

    return Izazbz