Ejemplo n.º 1
0
def ICTCP_to_RGB(ICTCP, L_p=10000):
    """
    Converts from :math:`IC_TC_P` colour encoding to *Rec. 2020* colourspace.

    Parameters
    ----------
    ICTCP : array_like
        :math:`IC_TC_P` colour encoding array.
    L_p : numeric, optional
        Display peak luminance :math:`cd/m^2` for *SMPTE ST 2084:2014*
        non-linear encoding.

    Returns
    -------
    ndarray
        *Rec. 2020* colourspace array.

    Examples
    --------
    >>> ICTCP = np.array([0.09554079, -0.00890639, 0.01389286])
    >>> ICTCP_to_RGB(ICTCP)  # doctest: +ELLIPSIS
    array([ 0.3518145...,  0.2693475...,  0.2128802...])
    """

    LMS_p = dot_vector(ICTCP_ICTCP_TO_LMS_P_MATRIX, ICTCP)
    LMS = eotf_ST2084(LMS_p, L_p)
    RGB = dot_vector(ICTCP_LMS_TO_RGB_MATRIX, LMS)

    return RGB
Ejemplo n.º 2
0
Archivo: ipt.py Proyecto: brehm/colour
def IPT_to_XYZ(IPT):
    """
    Converts from *IPT* colourspace to *CIE XYZ* tristimulus values.

    Parameters
    ----------
    IPT : array_like
        *IPT* colourspace array.

    Returns
    -------
    ndarray
        *CIE XYZ* tristimulus values.

    Examples
    --------
    >>> IPT = np.array([1.00300825, 0.01906918, -0.01369292])
    >>> IPT_to_XYZ(IPT)  # doctest: +ELLIPSIS
    array([ 0.9690723...,  1.        ,  1.1217921...])
    """

    LMS = dot_vector(IPT_IPT_TO_LMS_MATRIX, IPT)
    LMS_prime = np.sign(LMS) * np.abs(LMS) ** (1 / 0.43)
    XYZ = dot_vector(IPT_LMS_TO_XYZ_MATRIX, LMS_prime)

    return XYZ
Ejemplo n.º 3
0
Archivo: ipt.py Proyecto: brehm/colour
def XYZ_to_IPT(XYZ):
    """
    Converts from *CIE XYZ* tristimulus values to *IPT* colourspace.

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

    Returns
    -------
    ndarray
        *IPT* colourspace array.

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

    Examples
    --------
    >>> XYZ = np.array([0.96907232, 1, 1.12179215])
    >>> XYZ_to_IPT(XYZ)  # doctest: +ELLIPSIS
    array([ 1.0030082...,  0.0190691..., -0.0136929...])
    """

    LMS = dot_vector(IPT_XYZ_TO_LMS_MATRIX, XYZ)
    LMS_prime = np.sign(LMS) * np.abs(LMS) ** 0.43
    IPT = dot_vector(IPT_LMS_TO_IPT_MATRIX, LMS_prime)

    return IPT
Ejemplo n.º 4
0
def IPT_to_XYZ(IPT):
    """
    Converts from *IPT* colourspace to *CIE XYZ* tristimulus values.

    Parameters
    ----------
    IPT : array_like
        *IPT* colourspace array.

    Returns
    -------
    ndarray
        *CIE XYZ* tristimulus values.

    References
    ----------
    -   :cite:`Fairchild2013y`

    Examples
    --------
    >>> IPT = np.array([1.00300825, 0.01906918, -0.01369292])
    >>> IPT_to_XYZ(IPT)  # doctest: +ELLIPSIS
    array([ 0.9690723...,  1.        ,  1.1217921...])
    """

    LMS = dot_vector(IPT_IPT_TO_LMS_MATRIX, IPT)
    LMS_prime = np.sign(LMS) * np.abs(LMS) ** (1 / 0.43)
    XYZ = dot_vector(IPT_LMS_TO_XYZ_MATRIX, LMS_prime)

    return XYZ
Ejemplo n.º 5
0
def RGB_to_ICTCP(RGB, L_p=10000):
    """
    Converts from *Rec. 2020* colourspace to :math:`IC_TC_P` colour encoding.

    Parameters
    ----------
    RGB : array_like
        *Rec. 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.

    Examples
    --------
    >>> RGB = np.array([0.35181454, 0.26934757, 0.21288023])
    >>> RGB_to_ICTCP(RGB)  # doctest: +ELLIPSIS
    array([ 0.0955407..., -0.0089063...,  0.0138928...])
    """

    LMS = dot_vector(ICTCP_RGB_TO_LMS_MATRIX, RGB)
    LMS_p = oetf_ST2084(LMS, L_p)
    ICTCP = dot_vector(ICTCP_LMS_P_TO_ICTCP_MATRIX, LMS_p)

    return ICTCP
Ejemplo n.º 6
0
def hdr_IPT_to_XYZ(IPT_hdr, Y_s=0.2, Y_abs=100):
    """
    Converts from *hdr-IPT* colourspace to *CIE XYZ* tristimulus values.

    Parameters
    ----------
    IPT_hdr : array_like
        *hdr-IPT* colourspace array.
    Y_s : numeric or array_like
        Relative luminance :math:`Y_s` of the surround in domain [0, 1].
    Y_abs : numeric or array_like
        Absolute luminance :math:`Y_{abs}` of the scene diffuse white in
        :math:`cd/m^2`.

    Returns
    -------
    ndarray
        *CIE XYZ* tristimulus values.

    Examples
    --------
    >>> IPT_hdr = np.array([94.65929175, 0.38041773, -0.26731187])
    >>> hdr_IPT_to_XYZ(IPT_hdr)  # doctest: +ELLIPSIS
    array([ 0.9690723...,  1.        ,  1.1217921...])
    """

    e = exponent_hdr_IPT(Y_s, Y_abs)[..., np.newaxis]

    LMS = dot_vector(IPT_IPT_TO_LMS_MATRIX, IPT_hdr)
    LMS_prime = np.sign(LMS) * np.abs(luminance_Fairchild2010(LMS, e))
    XYZ = dot_vector(IPT_LMS_TO_XYZ_MATRIX, LMS_prime)

    return XYZ
Ejemplo n.º 7
0
def XYZ_to_IPT(XYZ):
    """
    Converts from *CIE XYZ* tristimulus values to *IPT* colourspace.

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

    Returns
    -------
    ndarray
        *IPT* colourspace array.

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

    References
    ----------
    -   :cite:`Fairchild2013y`

    Examples
    --------
    >>> XYZ = np.array([0.96907232, 1.00000000, 1.12179215])
    >>> XYZ_to_IPT(XYZ)  # doctest: +ELLIPSIS
    array([ 1.0030082...,  0.0190691..., -0.0136929...])
    """

    LMS = dot_vector(IPT_XYZ_TO_LMS_MATRIX, XYZ)
    LMS_prime = np.sign(LMS) * np.abs(LMS) ** 0.43
    IPT = dot_vector(IPT_LMS_TO_IPT_MATRIX, LMS_prime)

    return IPT
Ejemplo n.º 8
0
def XYZ_to_hdr_IPT(XYZ, Y_s=0.2, Y_abs=100, method='Fairchild 2011'):
    """
    Converts from *CIE XYZ* tristimulus values to *hdr-IPT* colourspace.

    Parameters
    ----------
    XYZ : array_like
        *CIE XYZ* tristimulus values.
    Y_s : numeric or array_like
        Relative luminance :math:`Y_s` of the surround in domain [0, 1].
    Y_abs : numeric or array_like
        Absolute luminance :math:`Y_{abs}` of the scene diffuse white in
        :math:`cd/m^2`.
    method : unicode, optional
        **{'Fairchild 2011', 'Fairchild 2010'}**,
        Computation method.

    Returns
    -------
    ndarray
        *hdr-IPT* colourspace array.

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

    References
    ----------
    -   :cite:`Fairchild2010`
    -   :cite:`Fairchild2011`

    Examples
    --------
    >>> XYZ = np.array([0.96907232, 1.00000000, 1.12179215])
    >>> XYZ_to_hdr_IPT(XYZ)  # doctest: +ELLIPSIS
    array([ 93.5317473...,   1.8564156...,  -1.3292254...])
    >>> XYZ_to_hdr_IPT(XYZ, method='Fairchild 2010')  # doctest: +ELLIPSIS
    array([ 94.6592917...,   0.3804177...,  -0.2673118...])
    """

    method_l = method.lower()
    assert method.lower() in [
        m.lower() for m in HDR_IPT_METHODS
    ], ('"{0}" method is invalid, must be one of {1}!'.format(
        method, HDR_IPT_METHODS))

    if method_l == 'fairchild 2010':
        lightness_callable = lightness_Fairchild2010
    else:
        lightness_callable = lightness_Fairchild2011

    e = exponent_hdr_IPT(Y_s, Y_abs, method)[..., np.newaxis]

    LMS = dot_vector(IPT_XYZ_TO_LMS_MATRIX, XYZ)
    LMS_prime = np.sign(LMS) * np.abs(lightness_callable(LMS, e))
    IPT = dot_vector(IPT_LMS_TO_IPT_MATRIX, LMS_prime)

    return IPT
Ejemplo n.º 9
0
Archivo: ictcp.py Proyecto: 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)
Ejemplo n.º 10
0
Archivo: ictcp.py Proyecto: yixw/colour
def ICTCP_to_RGB(ICTCP, L_p=10000):
    """
    Converts from :math:`IC_TC_P` colour encoding to *ITU-R BT.2020*
    colourspace.

    Parameters
    ----------
    ICTCP : array_like
        :math:`IC_TC_P` colour encoding array.
    L_p : numeric, optional
        Display peak luminance :math:`cd/m^2` for *SMPTE ST 2084:2014*
        non-linear encoding.

    Returns
    -------
    ndarray
        *ITU-R BT.2020* colourspace array.

    Notes
    -----

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

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

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

    Examples
    --------
    >>> ICTCP = np.array([0.07351364, 0.00475253, 0.09351596])
    >>> ICTCP_to_RGB(ICTCP)  # doctest: +ELLIPSIS
    array([ 0.4562052...,  0.0308107...,  0.0409195...])
    """

    ICTCP = to_domain_1(ICTCP)

    LMS_p = dot_vector(ICTCP_ICTCP_TO_LMS_P_MATRIX, ICTCP)

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

    RGB = dot_vector(ICTCP_LMS_TO_RGB_MATRIX, LMS)

    return from_range_1(RGB)
Ejemplo n.º 11
0
def hdr_IPT_to_XYZ(IPT_hdr, Y_s=0.2, Y_abs=100, method='Fairchild 2011'):
    """
    Converts from *hdr-IPT* colourspace to *CIE XYZ* tristimulus values.

    Parameters
    ----------
    IPT_hdr : array_like
        *hdr-IPT* colourspace array.
    Y_s : numeric or array_like
        Relative luminance :math:`Y_s` of the surround in domain [0, 1].
    Y_abs : numeric or array_like
        Absolute luminance :math:`Y_{abs}` of the scene diffuse white in
        :math:`cd/m^2`.
    method : unicode, optional
        **{'Fairchild 2011', 'Fairchild 2010'}**,
        Computation method.

    Returns
    -------
    ndarray
        *CIE XYZ* tristimulus values.

    References
    ----------
    -   :cite:`Fairchild2010`
    -   :cite:`Fairchild2011`

    Examples
    --------
    >>> IPT_hdr = np.array([93.53174734, 1.85641567, -1.32922546])
    >>> hdr_IPT_to_XYZ(IPT_hdr)  # doctest: +ELLIPSIS
    array([ 0.9690723...,  1.        ,  1.1217921...])
    >>> IPT_hdr = np.array([94.65929175, 0.38041773, -0.26731187])
    >>> hdr_IPT_to_XYZ(IPT_hdr, method='Fairchild 2010')
    ... # doctest: +ELLIPSIS
    array([ 0.9690723...,  1.        ,  1.1217921...])
    """

    method_l = method.lower()
    assert method.lower() in [
        m.lower() for m in HDR_IPT_METHODS
    ], ('"{0}" method is invalid, must be one of {1}!'.format(
        method, HDR_IPT_METHODS))

    if method_l == 'fairchild 2010':
        luminance_callable = luminance_Fairchild2010
    else:
        luminance_callable = luminance_Fairchild2011

    e = exponent_hdr_IPT(Y_s, Y_abs, method)[..., np.newaxis]

    LMS = dot_vector(IPT_IPT_TO_LMS_MATRIX, IPT_hdr)
    LMS_prime = np.sign(LMS) * np.abs(luminance_callable(LMS, e))
    XYZ = dot_vector(IPT_LMS_TO_XYZ_MATRIX, LMS_prime)

    return XYZ
Ejemplo n.º 12
0
def XYZ_to_IPT(XYZ):
    """
    Converts from *CIE XYZ* tristimulus values to *IPT* colourspace.

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

    Returns
    -------
    ndarray
        *IPT* colourspace array.

    Notes
    -----

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

    +------------+-----------------------+-----------------+
    | **Range**  | **Scale - Reference** | **Scale - 1**   |
    +============+=======================+=================+
    | ``IPT``    | ``I`` : [0, 1]        | ``I`` : [0, 1]  |
    |            |                       |                 |
    |            | ``P`` : [-1, 1]       | ``P`` : [-1, 1] |
    |            |                       |                 |
    |            | ``T`` : [-1, 1]       | ``T`` : [-1, 1] |
    +------------+-----------------------+-----------------+

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

    References
    ----------
    :cite:`Fairchild2013y`

    Examples
    --------
    >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
    >>> XYZ_to_IPT(XYZ)  # doctest: +ELLIPSIS
    array([ 0.3842619...,  0.3848730...,  0.1888683...])
    """

    XYZ = to_domain_1(XYZ)

    LMS = dot_vector(IPT_XYZ_TO_LMS_MATRIX, XYZ)
    LMS_prime = spow(LMS, 0.43)
    IPT = dot_vector(IPT_LMS_TO_IPT_MATRIX, LMS_prime)

    return from_range_1(IPT)
Ejemplo n.º 13
0
def XYZ_to_IPT(XYZ):
    """
    Converts from *CIE XYZ* tristimulus values to *IPT* colourspace.

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

    Returns
    -------
    ndarray
        *IPT* colourspace array.

    Notes
    -----

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

    +------------+-----------------------+-----------------+
    | **Range**  | **Scale - Reference** | **Scale - 1**   |
    +============+=======================+=================+
    | ``IPT``    | ``I`` : [0, 1]        | ``I`` : [0, 1]  |
    |            |                       |                 |
    |            | ``P`` : [-1, 1]       | ``P`` : [-1, 1] |
    |            |                       |                 |
    |            | ``T`` : [-1, 1]       | ``T`` : [-1, 1] |
    +------------+-----------------------+-----------------+

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

    References
    ----------
    :cite:`Fairchild2013y`

    Examples
    --------
    >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
    >>> XYZ_to_IPT(XYZ)  # doctest: +ELLIPSIS
    array([ 0.3842619...,  0.3848730...,  0.1888683...])
    """

    XYZ = to_domain_1(XYZ)

    LMS = dot_vector(IPT_XYZ_TO_LMS_MATRIX, XYZ)
    LMS_prime = spow(LMS, 0.43)
    IPT = dot_vector(IPT_LMS_TO_IPT_MATRIX, LMS_prime)

    return from_range_1(IPT)
Ejemplo n.º 14
0
def IPT_to_XYZ(IPT):
    """
    Converts from *IPT* colourspace to *CIE XYZ* tristimulus values.

    Parameters
    ----------
    IPT : array_like
        *IPT* colourspace array.

    Returns
    -------
    ndarray
        *CIE XYZ* tristimulus values.

    Notes
    -----

    +------------+-----------------------+-----------------+
    | **Domain** | **Scale - Reference** | **Scale - 1**   |
    +============+=======================+=================+
    | ``IPT``    | ``I`` : [0, 1]        | ``I`` : [0, 1]  |
    |            |                       |                 |
    |            | ``P`` : [-1, 1]       | ``P`` : [-1, 1] |
    |            |                       |                 |
    |            | ``T`` : [-1, 1]       | ``T`` : [-1, 1] |
    +------------+-----------------------+-----------------+

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

    References
    ----------
    :cite:`Fairchild2013y`

    Examples
    --------
    >>> IPT = np.array([0.38426191, 0.38487306, 0.18886838])
    >>> IPT_to_XYZ(IPT)  # doctest: +ELLIPSIS
    array([ 0.2065400...,  0.1219722...,  0.0513695...])
    """

    IPT = to_domain_1(IPT)

    LMS = dot_vector(IPT_IPT_TO_LMS_MATRIX, IPT)
    LMS_prime = spow(LMS, 1 / 0.43)
    XYZ = dot_vector(IPT_LMS_TO_XYZ_MATRIX, LMS_prime)

    return from_range_1(XYZ)
Ejemplo n.º 15
0
def IPT_to_XYZ(IPT):
    """
    Converts from *IPT* colourspace to *CIE XYZ* tristimulus values.

    Parameters
    ----------
    IPT : array_like
        *IPT* colourspace array.

    Returns
    -------
    ndarray
        *CIE XYZ* tristimulus values.

    Notes
    -----

    +------------+-----------------------+-----------------+
    | **Domain** | **Scale - Reference** | **Scale - 1**   |
    +============+=======================+=================+
    | ``IPT``    | ``I`` : [0, 1]        | ``I`` : [0, 1]  |
    |            |                       |                 |
    |            | ``P`` : [-1, 1]       | ``P`` : [-1, 1] |
    |            |                       |                 |
    |            | ``T`` : [-1, 1]       | ``T`` : [-1, 1] |
    +------------+-----------------------+-----------------+

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

    References
    ----------
    :cite:`Fairchild2013y`

    Examples
    --------
    >>> IPT = np.array([0.38426191, 0.38487306, 0.18886838])
    >>> IPT_to_XYZ(IPT)  # doctest: +ELLIPSIS
    array([ 0.2065400...,  0.1219722...,  0.0513695...])
    """

    IPT = to_domain_1(IPT)

    LMS = dot_vector(IPT_IPT_TO_LMS_MATRIX, IPT)
    LMS_prime = spow(LMS, 1 / 0.43)
    XYZ = dot_vector(IPT_LMS_TO_XYZ_MATRIX, LMS_prime)

    return from_range_1(XYZ)
Ejemplo n.º 16
0
def plot_cvd_simulation_Machado2009(RGB,
                                    deficiency='Protanomaly',
                                    severity=0.5,
                                    M_a=None,
                                    **kwargs):
    """
    Performs colour vision deficiency simulation on given *RGB* colourspace
    array using *Machado et al. (2009)* model.

    Parameters
    ----------
    RGB : array_like
        *RGB* colourspace array.
    deficiency : unicode, optional
        {'Protanomaly', 'Deuteranomaly', 'Tritanomaly'}
        Colour blindness / vision deficiency type.
    severity : numeric, optional
        Severity of the colour vision deficiency in domain [0, 1].
    M_a : array_like, optional
        Anomalous trichromacy matrix to use instead of Machado (2010)
        pre-computed matrix.

    Other Parameters
    ----------------
    \\**kwargs : dict, optional
        {:func:`colour.plotting.artist`, :func:`colour.plotting.plot_image`,
        :func:`colour.plotting.render`},
        Please refer to the documentation of the previously listed definitions.

    Notes
    -----
    -  Input *RGB* array is expected to be linearly encoded.

    Returns
    -------
    tuple
        Current figure and axes.

    Examples
    --------
    >>> import numpy as np
    >>> RGB = np.random.rand(32, 32, 3)
    >>> plot_cvd_simulation_Machado2009(RGB)  # doctest: +SKIP

    .. image:: ../_static/Plotting_Plot_CVD_Simulation_Machado2009.png
        :align: center
        :alt: plot_cvd_simulation_Machado2009
    """

    if M_a is None:
        M_a = cvd_matrix_Machado2009(deficiency, severity)

    text = 'Deficiency: {0} - Severity: {1}'.format(deficiency, severity)

    settings = {'text_parameters': {'text': None if M_a is None else text}}
    settings.update(kwargs)

    return plot_image(
        COLOUR_STYLE_CONSTANTS.colour.colourspace.encoding_cctf(
            dot_vector(M_a, RGB)), **settings)
Ejemplo n.º 17
0
def XYZ_to_RGB_LLAB(XYZ):
    """
    Converts from *CIE XYZ* tristimulus values to normalised cone responses.

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

    Returns
    -------
    ndarray
        Normalised cone responses.

    Examples
    --------
    >>> XYZ = np.array([19.01, 20.00, 21.78])
    >>> XYZ_to_RGB_LLAB(XYZ)  # doctest: +ELLIPSIS
    array([ 0.9414279...,  1.0404012...,  1.0897088...])
    """

    _X, Y, _Z = tsplit(XYZ)

    Y = tstack((Y, Y, Y))
    XYZ_n = XYZ / Y

    return dot_vector(LLAB_XYZ_TO_RGB_MATRIX, XYZ_n)
Ejemplo n.º 18
0
def XYZ_to_RGB_LLAB(XYZ):
    """
    Converts from *CIE XYZ* tristimulus values to normalised cone responses.

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

    Returns
    -------
    ndarray
        Normalised cone responses.

    Examples
    --------
    >>> XYZ = np.array([19.01, 20.00, 21.78])
    >>> XYZ_to_RGB_LLAB(XYZ)  # doctest: +ELLIPSIS
    array([ 0.9414279...,  1.0404012...,  1.0897088...])
    """

    _X, Y, Z = tsplit(XYZ)

    Y = tstack((Y, Y, Y))
    XYZ_n = XYZ / Y

    return dot_vector(LLAB_XYZ_TO_RGB_MATRIX, XYZ_n)
Ejemplo n.º 19
0
def XYZ_to_LMS_ATD95(XYZ):
    """
    Converts from *CIE XYZ* tristimulus values to *LMS* cone responses.

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

    Returns
    -------
    ndarray
        *LMS* cone responses.

    Examples
    --------
    >>> XYZ = np.array([19.01, 20.00, 21.78])
    >>> XYZ_to_LMS_ATD95(XYZ)  # doctest: +ELLIPSIS
    array([ 6.2283272...,  7.4780666...,  3.8859772...])
    """

    LMS = dot_vector([
        [0.2435, 0.8524, -0.0516],
        [-0.3954, 1.1642, 0.0837],
        [0.0000, 0.0400, 0.6225],
    ], XYZ)

    LMS *= np.array([0.66, 1.0, 0.43])
    LMS = spow(LMS, 0.7)
    LMS += np.array([0.024, 0.036, 0.31])

    return LMS
Ejemplo n.º 20
0
    def test_dot_vector(self):
        """
        Tests :func:`colour.utilities.array.dot_vector` definition.
        """

        m = np.array([
            [0.7328, 0.4296, -0.1624],
            [-0.7036, 1.6975, 0.0061],
            [0.0030, 0.0136, 0.9834],
        ])
        m = np.reshape(np.tile(m, (6, 1)), (6, 3, 3))

        v = np.array([0.20654008, 0.12197225, 0.05136952])
        v = np.tile(v, (6, 1))

        np.testing.assert_almost_equal(
            dot_vector(m, v),
            np.array([
                [0.19540944, 0.06203965, 0.05279523],
                [0.19540944, 0.06203965, 0.05279523],
                [0.19540944, 0.06203965, 0.05279523],
                [0.19540944, 0.06203965, 0.05279523],
                [0.19540944, 0.06203965, 0.05279523],
                [0.19540944, 0.06203965, 0.05279523],
            ]),
            decimal=7)
Ejemplo n.º 21
0
def RGB_to_YCoCg(RGB):
    """
    Converts an array of *R'G'B'* values to the corresponding *YCoCg* colour
    encoding values array.

    Parameters
    ----------
    RGB : array_like
        Input *R'G'B'* array.

    Returns
    -------
    ndarray
        *YCoCg* colour encoding array.

    References
    ----------
    :cite:`Malvar2003`

    Examples
    --------
    >>> RGB_to_YCoCg(np.array([1.0, 1.0, 1.0]))
    array([ 1.,  0.,  0.])
    >>> RGB_to_YCoCg(np.array([0.75, 0.5, 0.5]))
    array([ 0.5625,  0.125 , -0.0625])
    """

    return dot_vector(RGB_TO_YCOCG_MATRIX, RGB)
Ejemplo n.º 22
0
def YCoCg_to_RGB(YCoCg):
    """
    Converts an array of *YCoCg* colour encoding values to the corresponding
    *R'G'B'* values array.

    Parameters
    ----------
    YCoCg : array_like
        *YCoCg* colour encoding array.

    Returns
    -------
    ndarray
        Output *R'G'B'* array.

    References
    ----------
    :cite:`Malvar2003`

    Examples
    --------
    >>> YCoCg_to_RGB(np.array([1.0, 0.0, 0.0]))
    array([ 1.,  1.,  1.])
    >>> YCoCg_to_RGB(np.array([0.5625, 0.125, -0.0625]))
    array([ 0.75,  0.5 ,  0.5 ])
    """

    return dot_vector(YCOCG_TO_RGB_MATRIX, YCoCg)
Ejemplo n.º 23
0
def RGB_to_YCoCg(RGB):
    """
    Converts an array of *R'G'B'* values to the corresponding *YCoCg* colour
    encoding values array.

    Parameters
    ----------
    RGB : array_like
        Input *R'G'B'* array.

    Returns
    -------
    ndarray
        *YCoCg* colour encoding array.

    References
    ----------
    :cite:`Malvar2003`

    Examples
    --------
    >>> RGB_to_YCoCg(np.array([1.0, 1.0, 1.0]))
    array([ 1.,  0.,  0.])
    >>> RGB_to_YCoCg(np.array([0.75, 0.5, 0.5]))
    array([ 0.5625,  0.125 , -0.0625])
    """

    return dot_vector(RGB_TO_YCOCG_MATRIX, RGB)
Ejemplo n.º 24
0
def RGB_to_rgb(RGB):
    """
    Converts given *RGB* array to *Hunt-Pointer-Estevez*
    :math:`\\rho\gamma\\beta` colourspace.

    Parameters
    ----------
    RGB : array_like
        *RGB* array.

    Returns
    -------
    ndarray
        *Hunt-Pointer-Estevez* :math:`\\rho\gamma\\beta` colourspace array.

    Examples
    --------
    >>> RGB = np.array([19.99370783, 20.00393634, 20.01326387])
    >>> RGB_to_rgb(RGB)  # doctest: +ELLIPSIS
    array([ 19.9969397...,  20.0018612...,  20.0135053...])
    """

    rgb = dot_vector(dot_matrix(XYZ_TO_HPE_MATRIX, CAT02_INVERSE_CAT), RGB)

    return rgb
Ejemplo n.º 25
0
def rgb_to_RGB(rgb):
    """
    Converts given *Hunt-Pointer-Estevez* :math:`\\rho\gamma\\beta` colourspace
    array to *RGB* array.

    Parameters
    ----------
    rgb : array_like
        *Hunt-Pointer-Estevez* :math:`\\rho\gamma\\beta` colourspace array.

    Returns
    -------
    ndarray
        *RGB* array.

    Examples
    --------
    >>> rgb = np.array([19.99693975, 20.00186123, 20.01350530])
    >>> rgb_to_RGB(rgb)  # doctest: +ELLIPSIS
    array([ 19.9937078...,  20.0039363...,  20.0132638...])
    """

    RGB = dot_vector(dot_matrix(CAT02_CAT, HPE_TO_XYZ_MATRIX), rgb)

    return RGB
Ejemplo n.º 26
0
def RGB_to_rgb(RGB):
    """
    Converts given *RGB* array to *Hunt-Pointer-Estevez*
    :math:`\\rho\gamma\\beta` colourspace.

    Parameters
    ----------
    RGB : array_like
        *RGB* array.

    Returns
    -------
    ndarray
        *Hunt-Pointer-Estevez* :math:`\\rho\gamma\\beta` colourspace array.

    Examples
    --------
    >>> RGB = np.array([19.99370783, 20.00393634, 20.01326387])
    >>> RGB_to_rgb(RGB)  # doctest: +ELLIPSIS
    array([ 19.9969397...,  20.0018612...,  20.0135053...])
    """

    rgb = dot_vector(dot_matrix(XYZ_TO_HPE_MATRIX, CAT02_INVERSE_CAT), RGB)

    return rgb
Ejemplo n.º 27
0
def YCoCg_to_RGB(YCoCg):
    """
    Converts an array of *YCoCg* colour encoding values to the corresponding
    *R'G'B'* values array.

    Parameters
    ----------
    YCoCg : array_like
        *YCoCg* colour encoding array.

    Returns
    -------
    ndarray
        Output *R'G'B'* array.

    References
    ----------
    :cite:`Malvar2003`

    Examples
    --------
    >>> YCoCg_to_RGB(np.array([1.0, 0.0, 0.0]))
    array([ 1.,  1.,  1.])
    >>> YCoCg_to_RGB(np.array([0.5625, 0.125, -0.0625]))
    array([ 0.75,  0.5 ,  0.5 ])
    """

    return dot_vector(YCOCG_TO_RGB_MATRIX, YCoCg)
Ejemplo n.º 28
0
def rgb_to_RGB(rgb):
    """
    Converts given *Hunt-Pointer-Estevez* :math:`\\rho\gamma\\beta` colourspace
    array to *RGB* array.

    Parameters
    ----------
    rgb : array_like
        *Hunt-Pointer-Estevez* :math:`\\rho\gamma\\beta` colourspace array.

    Returns
    -------
    ndarray
        *RGB* array.

    Examples
    --------
    >>> rgb = np.array([19.99693975, 20.00186123, 20.01350530])
    >>> rgb_to_RGB(rgb)  # doctest: +ELLIPSIS
    array([ 19.9937078...,  20.0039363...,  20.0132638...])
    """

    RGB = dot_vector(dot_matrix(CAT02_CAT, HPE_TO_XYZ_MATRIX), rgb)

    return RGB
Ejemplo n.º 29
0
    def test_dot_vector(self):
        """
        Tests :func:`colour.utilities.array.dot_vector` definition.
        """

        m = np.array([
            [0.7328, 0.4296, -0.1624],
            [-0.7036, 1.6975, 0.0061],
            [0.0030, 0.0136, 0.9834],
        ])
        m = np.reshape(np.tile(m, (6, 1)), (6, 3, 3))

        v = np.array([0.20654008, 0.12197225, 0.05136952])
        v = np.tile(v, (6, 1))

        np.testing.assert_almost_equal(
            dot_vector(m, v),
            np.array([
                [0.19540944, 0.06203965, 0.05279523],
                [0.19540944, 0.06203965, 0.05279523],
                [0.19540944, 0.06203965, 0.05279523],
                [0.19540944, 0.06203965, 0.05279523],
                [0.19540944, 0.06203965, 0.05279523],
                [0.19540944, 0.06203965, 0.05279523],
            ]),
            decimal=7)
Ejemplo n.º 30
0
    def test_dot_vector(self):
        """
        Tests :func:`colour.utilities.array.dot_vector` definition.
        """

        m = np.array([
            [0.7328, 0.4296, -0.1624],
            [-0.7036, 1.6975, 0.0061],
            [0.0030, 0.0136, 0.9834],
        ])
        m = np.reshape(np.tile(m, (6, 1)), (6, 3, 3))

        v = np.array([0.07049534, 0.10080000, 0.09558313])
        v = np.tile(v, (6, 1))

        np.testing.assert_almost_equal(
            dot_vector(m, v),
            np.array([
                [0.07943996, 0.12209054, 0.09557882],
                [0.07943996, 0.12209054, 0.09557882],
                [0.07943996, 0.12209054, 0.09557882],
                [0.07943996, 0.12209054, 0.09557882],
                [0.07943996, 0.12209054, 0.09557882],
                [0.07943996, 0.12209054, 0.09557882],
            ]),
            decimal=7)
Ejemplo n.º 31
0
def plot_cvd_simulation_Machado2009(RGB,
                                    deficiency='Protanomaly',
                                    severity=0.5,
                                    M_a=None,
                                    **kwargs):
    """
    Performs colour vision deficiency simulation on given *RGB* colourspace
    array using *Machado et al. (2009)* model.

    Parameters
    ----------
    RGB : array_like
        *RGB* colourspace array.
    deficiency : unicode, optional
        {'Protanomaly', 'Deuteranomaly', 'Tritanomaly'}
        Colour blindness / vision deficiency type.
    severity : numeric, optional
        Severity of the colour vision deficiency in domain [0, 1].
    M_a : array_like, optional
        Anomalous trichromacy matrix to use instead of Machado (2010)
        pre-computed matrix.

    Other Parameters
    ----------------
    \\**kwargs : dict, optional
        {:func:`colour.plotting.artist`, :func:`colour.plotting.plot_image`,
        :func:`colour.plotting.render`},
        Please refer to the documentation of the previously listed definitions.

    Notes
    -----
    -  Input *RGB* array is expected to be linearly encoded.

    Returns
    -------
    tuple
        Current figure and axes.

    Examples
    --------
    >>> import numpy as np
    >>> RGB = np.random.rand(32, 32, 3)
    >>> plot_cvd_simulation_Machado2009(RGB)  # doctest: +SKIP

    .. image:: ../_static/Plotting_Plot_CVD_Simulation_Machado2009.png
        :align: center
        :alt: plot_cvd_simulation_Machado2009
    """

    if M_a is None:
        M_a = cvd_matrix_Machado2009(deficiency, severity)

    text = 'Deficiency: {0} - Severity: {1}'.format(deficiency, severity)

    settings = {'text_parameters': {'text': None if M_a is None else text}}
    settings.update(kwargs)

    return plot_image(
        COLOUR_STYLE_CONSTANTS.colour.colourspace.encoding_cctf(
            dot_vector(M_a, RGB)), **settings)
Ejemplo n.º 32
0
def highlights_recovery_blend(RGB, multipliers, threshold=0.99):
    """
    Performs highlights recovery using *Coffin (1997)* method from *dcraw*.

    Parameters
    ----------
    RGB : array_like
        *RGB* colourspace array.
    multipliers : array_like
        Normalised camera white level or white balance multipliers.
    threshold : numeric, optional
        Threshold for highlights selection.

    Returns
    -------
    ndarray
         Highlights recovered *RGB* colourspace array.

    References
    ----------
    :cite:`Coffin2015a`
    """

    M = np.array(
        [[1.0000000, 1.0000000, 1.0000000],
         [1.7320508, -1.7320508, 0.0000000],
         [-1.0000000, -1.0000000, 2.0000000]])  # yapf: disable

    clipping_level = np.min(multipliers) * threshold

    Lab = dot_vector(M, RGB)

    Lab_c = dot_vector(M, np.minimum(RGB, clipping_level))

    s = np.sum((Lab * Lab)[..., 1:3], axis=2)
    s_c = np.sum((Lab_c * Lab_c)[..., 1:3], axis=2)

    ratio = np.sqrt(s_c / s)
    ratio[np.logical_or(np.isnan(ratio), np.isinf(ratio))] = 1

    Lab[:, :, 1:3] *= np.rollaxis(ratio[np.newaxis], 0, 3)

    RGB_o = dot_vector(np.linalg.inv(M), Lab)

    return RGB_o
Ejemplo n.º 33
0
def degrees_of_adaptation(LMS, Y_n, v=1 / 3, discount_illuminant=False):
    """
    Computes the degrees of adaptation :math:`p_L`, :math:`p_M` and
    :math:`p_S`.

    Parameters
    ----------
    LMS : array_like
        Cone responses.
    Y_n : numeric or array_like
        Luminance :math:`Y_n` of test adapting stimulus in :math:`cd/m^2`.
    v : numeric or array_like, optional
        Exponent :math:`v`.
    discount_illuminant : bool, optional
        Truth value indicating if the illuminant should be discounted.

    Returns
    -------
    ndarray
        Degrees of adaptation :math:`p_L`, :math:`p_M` and :math:`p_S`.

    Examples
    --------
    >>> LMS = np.array([20.00052060, 19.99978300, 19.99883160])
    >>> Y_n = 31.83
    >>> degrees_of_adaptation(LMS, Y_n)  # doctest: +ELLIPSIS
    array([ 0.9799324...,  0.9960035...,  1.0233041...])
    >>> degrees_of_adaptation(LMS, Y_n, 1 / 3, True)
    array([ 1.,  1.,  1.])
    """

    LMS = np.asarray(LMS)
    if discount_illuminant:
        return np.ones(LMS.shape)

    Y_n = np.asarray(Y_n)
    v = np.asarray(v)

    L, M, S = tsplit(LMS)

    LMS_E = dot_vector(VON_KRIES_CAT, np.ones(LMS.shape))  # E illuminant.
    L_E, M_E, S_E = tsplit(LMS_E)

    Ye_n = Y_n ** v

    f_E = lambda x, y: (3 * (x / y)) / (L / L_E + M / M_E + S / S_E)
    f_P = lambda x: (1 + Ye_n + x) / (1 + Ye_n + 1 / x)

    p_L = f_P(f_E(L, L_E))
    p_M = f_P(f_E(M, M_E))
    p_S = f_P(f_E(S, S_E))

    p_LMS = tstack((p_L, p_M, p_S))

    return p_LMS
Ejemplo n.º 34
0
def RGB_to_RGB(RGB,
               input_colourspace,
               output_colourspace,
               chromatic_adaptation_transform='CAT02'):
    """
    Converts from given input *RGB* colourspace to output *RGB* colourspace
    using given *chromatic adaptation* method.

    Parameters
    ----------
    RGB : array_like
        *RGB* colourspace array.
    input_colourspace : RGB_Colourspace
        *RGB* input colourspace.
    output_colourspace : RGB_Colourspace
        *RGB* output colourspace.
    chromatic_adaptation_transform : unicode, optional
        **{'CAT02', 'XYZ Scaling', 'Von Kries', 'Bradford', 'Sharp',
        'Fairchild', 'CMCCAT97', 'CMCCAT2000', 'CAT02_BRILL_CAT', 'Bianco',
        'Bianco PC'}**,
        *Chromatic adaptation* transform.

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

    Notes
    -----
    -   Input / output *RGB* colourspace arrays are in domain / range [0, 1].
    -   Input / output *RGB* colourspace arrays are assumed to be representing
        linear light values.

    Examples
    --------
    >>> from colour import sRGB_COLOURSPACE, PROPHOTO_RGB_COLOURSPACE
    >>> RGB = np.array([0.01103742, 0.12734226, 0.11632971])
    >>> RGB_to_RGB(
    ...     RGB,
    ...     sRGB_COLOURSPACE,
    ...     PROPHOTO_RGB_COLOURSPACE)  # doctest: +ELLIPSIS
    array([ 0.0643538...,  0.1157289...,  0.1158038...])
    """

    cat = chromatic_adaptation_matrix_VonKries(
        xy_to_XYZ(input_colourspace.whitepoint),
        xy_to_XYZ(output_colourspace.whitepoint),
        chromatic_adaptation_transform)

    M = dot_matrix(cat, input_colourspace.RGB_to_XYZ_matrix)
    M = dot_matrix(output_colourspace.XYZ_to_RGB_matrix, M)

    RGB = dot_vector(M, RGB)

    return RGB
Ejemplo n.º 35
0
def degrees_of_adaptation(LMS, Y_n, v=1 / 3, discount_illuminant=False):
    """
    Computes the degrees of adaptation :math:`p_L`, :math:`p_M` and
    :math:`p_S`.

    Parameters
    ----------
    LMS : array_like
        Cone responses.
    Y_n : numeric or array_like
        Luminance :math:`Y_n` of test adapting stimulus in :math:`cd/m^2`.
    v : numeric or array_like, optional
        Exponent :math:`v`.
    discount_illuminant : bool, optional
        Truth value indicating if the illuminant should be discounted.

    Returns
    -------
    ndarray
        Degrees of adaptation :math:`p_L`, :math:`p_M` and :math:`p_S`.

    Examples
    --------
    >>> LMS = np.array([20.00052060, 19.99978300, 19.99883160])
    >>> Y_n = 31.83
    >>> degrees_of_adaptation(LMS, Y_n)  # doctest: +ELLIPSIS
    array([ 0.9799324...,  0.9960035...,  1.0233041...])
    >>> degrees_of_adaptation(LMS, Y_n, 1 / 3, True)
    array([ 1.,  1.,  1.])
    """

    LMS = np.asarray(LMS)
    if discount_illuminant:
        return np.ones(LMS.shape)

    Y_n = np.asarray(Y_n)
    v = np.asarray(v)

    L, M, S = tsplit(LMS)

    LMS_E = dot_vector(VON_KRIES_CAT, np.ones(LMS.shape))  # E illuminant.
    L_E, M_E, S_E = tsplit(LMS_E)

    Ye_n = Y_n**v

    f_E = lambda x, y: (3 * (x / y)) / (L / L_E + M / M_E + S / S_E)
    f_P = lambda x: (1 + Ye_n + x) / (1 + Ye_n + 1 / x)

    p_L = f_P(f_E(L, L_E))
    p_M = f_P(f_E(M, M_E))
    p_S = f_P(f_E(S, S_E))

    p_LMS = tstack((p_L, p_M, p_S))

    return p_LMS
Ejemplo n.º 36
0
Archivo: rgb.py Proyecto: brehm/colour
def RGB_to_RGB(RGB,
               input_colourspace,
               output_colourspace,
               chromatic_adaptation_transform='CAT02'):
    """
    Converts from given input *RGB* colourspace to output *RGB* colourspace
    using given *chromatic adaptation* method.

    Parameters
    ----------
    RGB : array_like
        *RGB* colourspace array.
    input_colourspace : RGB_Colourspace
        *RGB* input colourspace.
    output_colourspace : RGB_Colourspace
        *RGB* output colourspace.
    chromatic_adaptation_transform : unicode, optional
        **{'CAT02', 'XYZ Scaling', 'Von Kries', 'Bradford', 'Sharp',
        'Fairchild, 'CMCCAT97', 'CMCCAT2000', 'CAT02_BRILL_CAT', 'Bianco',
        'Bianco PC'}**,
        *Chromatic adaptation* transform.

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

    Notes
    -----
    -   *RGB* colourspace arrays are in domain [0, 1].

    Examples
    --------
    >>> from colour import sRGB_COLOURSPACE, PROPHOTO_RGB_COLOURSPACE
    >>> RGB = np.array([0.01103604, 0.12734466, 0.11631037])
    >>> RGB_to_RGB(
    ...     RGB,
    ...     sRGB_COLOURSPACE,
    ...     PROPHOTO_RGB_COLOURSPACE)  # doctest: +ELLIPSIS
    array([ 0.0643338...,  0.1157362...,  0.1157614...])
    """

    cat = chromatic_adaptation_matrix_VonKries(
        xy_to_XYZ(input_colourspace.whitepoint),
        xy_to_XYZ(output_colourspace.whitepoint),
        chromatic_adaptation_transform)

    M = dot_matrix(cat, input_colourspace.RGB_to_XYZ_matrix)
    M = dot_matrix(output_colourspace.XYZ_to_RGB_matrix, M)

    RGB = dot_vector(M, RGB)

    return RGB
Ejemplo n.º 37
0
def chromatic_adaptation(RGB, RGB_0, RGB_0r, Y, D=1):
    """
    Applies chromatic adaptation to given *RGB* normalised cone responses
    array.

    Parameters
    ----------
    RGB : array_like
        *RGB* normalised cone responses array of test sample / stimulus.
    RGB_0 : array_like
        *RGB* normalised cone responses array of reference white.
    RGB_0r : array_like
        *RGB* normalised cone responses array of reference illuminant
        *CIE Standard Illuminant D Series* *D65*.
    Y : numeric or array_like
        Tristimulus values :math:`Y` of the stimulus.
    D : numeric or array_like, optional
         *Discounting-the-Illuminant* factor in domain [0, 1].

    Returns
    -------
    ndarray
        Adapted *CIE XYZ* tristimulus values.

    Examples
    --------
    >>> RGB = np.array([0.94142795, 1.04040120, 1.08970885])
    >>> RGB_0 = np.array([0.94146023, 1.04039386, 1.08950293])
    >>> RGB_0r = np.array([0.94146023, 1.04039386, 1.08950293])
    >>> Y = 20.0
    >>> chromatic_adaptation(RGB, RGB_0, RGB_0r, Y)  # doctest: +ELLIPSIS
    array([ 19.01,  20.  ,  21.78])
    """

    R, G, B = tsplit(RGB)
    R_0, G_0, B_0 = tsplit(RGB_0)
    R_0r, G_0r, B_0r = tsplit(RGB_0r)
    Y = np.asarray(Y)

    beta = (B_0 / B_0r) ** 0.0834

    R_r = (D * (R_0r / R_0) + 1 - D) * R
    G_r = (D * (G_0r / G_0) + 1 - D) * G
    B_r = (D * (B_0r / (B_0 ** beta)) + 1 - D) * (abs(B) ** beta)

    RGB_r = tstack((R_r, G_r, B_r))

    Y = tstack((Y, Y, Y))

    XYZ_r = dot_vector(LLAB_RGB_TO_XYZ_MATRIX, RGB_r * Y)

    return XYZ_r
Ejemplo n.º 38
0
def chromatic_adaptation(RGB, RGB_0, RGB_0r, Y, D=1):
    """
    Applies chromatic adaptation to given *RGB* normalised cone responses
    array.

    Parameters
    ----------
    RGB : array_like
        *RGB* normalised cone responses array of test sample / stimulus.
    RGB_0 : array_like
        *RGB* normalised cone responses array of reference white.
    RGB_0r : array_like
        *RGB* normalised cone responses array of reference illuminant
        *CIE Standard Illuminant D Series* *D65*.
    Y : numeric or array_like
        Tristimulus values :math:`Y` of the stimulus.
    D : numeric or array_like, optional
         *Discounting-the-Illuminant* factor in domain [0, 1].

    Returns
    -------
    ndarray
        Adapted *CIE XYZ* tristimulus values.

    Examples
    --------
    >>> RGB = np.array([0.94142795, 1.04040120, 1.08970885])
    >>> RGB_0 = np.array([0.94146023, 1.04039386, 1.08950293])
    >>> RGB_0r = np.array([0.94146023, 1.04039386, 1.08950293])
    >>> Y = 20.0
    >>> chromatic_adaptation(RGB, RGB_0, RGB_0r, Y)  # doctest: +ELLIPSIS
    array([ 19.01,  20.  ,  21.78])
    """

    R, G, B = tsplit(RGB)
    R_0, G_0, B_0 = tsplit(RGB_0)
    R_0r, G_0r, B_0r = tsplit(RGB_0r)
    Y = np.asarray(Y)

    beta = (B_0 / B_0r) ** 0.0834

    R_r = (D * (R_0r / R_0) + 1 - D) * R
    G_r = (D * (G_0r / G_0) + 1 - D) * G
    B_r = (D * (B_0r / (B_0 ** beta)) + 1 - D) * (abs(B) ** beta)

    RGB_r = tstack((R_r, G_r, B_r))

    Y = tstack((Y, Y, Y))

    XYZ_r = dot_vector(LLAB_RGB_TO_XYZ_MATRIX, RGB_r * Y)

    return XYZ_r
Ejemplo n.º 39
0
def chromatic_adaptation_VonKries(XYZ, XYZ_w, XYZ_wr, transform='CAT02'):
    """
    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 whitepoint.
    XYZ_wr : array_like
        Reference viewing condition *CIE XYZ* tristimulus values of whitepoint.
    transform : unicode, optional
        **{'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.

    References
    ----------
    -   :cite:`Fairchild2013t`

    Examples
    --------
    >>> XYZ = np.array([0.07049534, 0.10080000, 0.09558313])
    >>> XYZ_w = np.array([1.09846607, 1.00000000, 0.35582280])
    >>> XYZ_wr = np.array([0.95042855, 1.00000000, 1.08890037])
    >>> chromatic_adaptation_VonKries(XYZ, XYZ_w, XYZ_wr)  # doctest: +ELLIPSIS
    array([ 0.0839746...,  0.1141321...,  0.2862554...])

    Using Bradford method:

    >>> XYZ = np.array([0.07049534, 0.10080000, 0.09558313])
    >>> XYZ_w = np.array([1.09846607, 1.00000000, 0.35582280])
    >>> XYZ_wr = np.array([0.95042855, 1.00000000, 1.08890037])
    >>> transform = 'Bradford'
    >>> chromatic_adaptation_VonKries(XYZ, XYZ_w, XYZ_wr, transform)
    ... # doctest: +ELLIPSIS
    array([ 0.0854032...,  0.1140122...,  0.2972149...])
    """

    cat = chromatic_adaptation_matrix_VonKries(XYZ_w, XYZ_wr, transform)
    XYZ_a = dot_vector(cat, XYZ)

    return XYZ_a
Ejemplo n.º 40
0
def XYZ_to_hdr_IPT(XYZ, Y_s=0.2, Y_abs=100):
    """
    Converts from *CIE XYZ* tristimulus values to *hdr-IPT* colourspace.

    Parameters
    ----------
    XYZ : array_like
        *CIE XYZ* tristimulus values.
    Y_s : numeric or array_like
        Relative luminance :math:`Y_s` of the surround in domain [0, 1].
    Y_abs : numeric or array_like
        Absolute luminance :math:`Y_{abs}` of the scene diffuse white in
        :math:`cd/m^2`.

    Returns
    -------
    ndarray
        *hdr-IPT* colourspace array.

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

    Examples
    --------
    >>> XYZ = np.array([0.96907232, 1.00000000, 1.12179215])
    >>> XYZ_to_hdr_IPT(XYZ)  # doctest: +ELLIPSIS
    array([ 94.6592917...,   0.3804177...,  -0.2673118...])
    """

    e = exponent_hdr_IPT(Y_s, Y_abs)[..., np.newaxis]

    LMS = dot_vector(IPT_XYZ_TO_LMS_MATRIX, XYZ)
    LMS_prime = np.sign(LMS) * np.abs(lightness_Fairchild2010(LMS, e))
    IPT = dot_vector(IPT_LMS_TO_IPT_MATRIX, LMS_prime)

    return IPT
Ejemplo n.º 41
0
def RGB_10_degree_cmfs_to_XYZ_10_degree_cmfs(wavelength):
    """
    Converts *Stiles & Burch 1959 10 Degree RGB CMFs* colour matching
    functions into the *CIE 1964 10 Degree Standard Observer* colour matching
    functions.

    Parameters
    ----------
    wavelength : numeric or array_like
        Wavelength :math:`\lambda` in nm.

    Returns
    -------
    ndarray
        *CIE 1964 10 Degree Standard Observer* spectral tristimulus values.

    See Also
    --------
    :attr:`colour.colorimetry.dataset.cmfs.RGB_CMFS`

    Notes
    -----
    -   Data for the *CIE 1964 10 Degree Standard Observer* already exists,
        this definition is intended for educational purpose.

    References
    ----------
    .. [2]  Wyszecki, G., & Stiles, W. S. (2000). The CIE 1964 Standard
            Observer. In Color Science: Concepts and Methods, Quantitative
            Data and Formulae (p. 141). Wiley. ISBN:978-0471399186

    Examples
    --------
    >>> RGB_10_degree_cmfs_to_XYZ_10_degree_cmfs(700)  # doctest: +ELLIPSIS
    array([  9.6432150...e-03,   3.7526317...e-03,  -4.1078830...e-06])
    """

    cmfs = RGB_CMFS['Stiles & Burch 1959 10 Degree RGB CMFs']

    rgb_bar = cmfs.get(wavelength)

    M = np.array(
        [[0.341080, 0.189145, 0.387529],
         [0.139058, 0.837460, 0.073316],
         [0.000000, 0.039553, 2.026200]])  # yapf: disable

    xyz_bar = dot_vector(M, rgb_bar)

    return xyz_bar
Ejemplo n.º 42
0
def RGB_10_degree_cmfs_to_LMS_10_degree_cmfs(wavelength):
    """
    Converts *Stiles & Burch 1959 10 Degree RGB CMFs* colour matching
    functions into the *Stockman & Sharpe 10 Degree Cone Fundamentals*
    spectral sensitivity functions.

    Parameters
    ----------
    wavelength : numeric or array_like
        Wavelength :math:`\lambda` in nm.

    Returns
    -------
    ndarray
        *Stockman & Sharpe 10 Degree Cone Fundamentals* spectral tristimulus
        values.

    Notes
    -----
    -   Data for the *Stockman & Sharpe 10 Degree Cone Fundamentals* already
        exists, this definition is intended for educational purpose.

    References
    ----------
    -   :cite:`CIETC1-362006a`

    Examples
    --------
    >>> from colour.utilities import numpy_print_options
    >>> with numpy_print_options(suppress=True):
    ...     RGB_10_degree_cmfs_to_LMS_10_degree_cmfs(700)  # doctest: +ELLIPSIS
    array([ 0.0052860...,  0.0003252...,  0.        ])
    """

    cmfs = RGB_CMFS['Stiles & Burch 1959 10 Degree RGB CMFs']

    rgb_bar = cmfs[wavelength]

    M = np.array([
        [0.1923252690, 0.749548882, 0.0675726702],
        [0.0192290085, 0.940908496, 0.113830196],
        [0.0000000000, 0.0105107859, 0.991427669],
    ])

    lms_bar = dot_vector(M, rgb_bar)
    lms_bar[..., -1][np.asarray(np.asarray(wavelength) > 505)] = 0

    return lms_bar
Ejemplo n.º 43
0
def RGB_10_degree_cmfs_to_XYZ_10_degree_cmfs(wavelength):
    """
    Converts *Stiles & Burch 1959 10 Degree RGB CMFs* colour matching
    functions into the *CIE 1964 10 Degree Standard Observer* colour matching
    functions.

    Parameters
    ----------
    wavelength : numeric or array_like
        Wavelength :math:`\lambda` in nm.

    Returns
    -------
    ndarray
        *CIE 1964 10 Degree Standard Observer* spectral tristimulus values.

    See Also
    --------
    :attr:`colour.colorimetry.dataset.cmfs.RGB_CMFS`

    Notes
    -----
    -   Data for the *CIE 1964 10 Degree Standard Observer* already exists,
        this definition is intended for educational purpose.

    References
    ----------
    .. [2]  Wyszecki, G., & Stiles, W. S. (2000). The CIE 1964 Standard
            Observer. In Color Science: Concepts and Methods, Quantitative
            Data and Formulae (p. 141). Wiley. ISBN:978-0471399186

    Examples
    --------
    >>> RGB_10_degree_cmfs_to_XYZ_10_degree_cmfs(700)  # doctest: +ELLIPSIS
    array([  9.6432150...e-03,   3.7526317...e-03,  -4.1078830...e-06])
    """

    cmfs = RGB_CMFS.get('Stiles & Burch 1959 10 Degree RGB CMFs')

    rgb_bar = cmfs.get(wavelength)

    M = np.array([[0.341080, 0.189145, 0.387529],
                  [0.139058, 0.837460, 0.073316],
                  [0.000000, 0.039553, 2.026200]])

    xyz_bar = dot_vector(M, rgb_bar)

    return xyz_bar
Ejemplo n.º 44
0
def RGB_10_degree_cmfs_to_LMS_10_degree_cmfs(wavelength):
    """
    Converts *Stiles & Burch 1959 10 Degree RGB CMFs* colour matching
    functions into the *Stockman & Sharpe 10 Degree Cone Fundamentals*
    spectral sensitivity functions.

    Parameters
    ----------
    wavelength : numeric or array_like
        Wavelength :math:`\lambda` in nm.

    Returns
    -------
    ndarray
        *Stockman & Sharpe 10 Degree Cone Fundamentals* spectral tristimulus
        values.

    Notes
    -----
    -   Data for the *Stockman & Sharpe 10 Degree Cone Fundamentals* already
        exists, this definition is intended for educational purpose.

    References
    ----------
    .. [3]  CIE TC 1-36. (2006). CIE 170-1:2006 Fundamental Chromaticity
            Diagram with Physiological Axes - Part 1 (pp. 1–56).
            ISBN:978-3-901-90646-6

    Examples
    --------
    >>> RGB_10_degree_cmfs_to_LMS_10_degree_cmfs(700)  # doctest: +ELLIPSIS
    array([ 0.0052860...,  0.0003252...,  0.        ])
    """

    cmfs = RGB_CMFS['Stiles & Burch 1959 10 Degree RGB CMFs']

    rgb_bar = cmfs.get(wavelength)

    M = np.array(
        [[0.1923252690, 0.749548882, 0.0675726702],
         [0.0192290085, 0.940908496, 0.113830196],
         [0.0000000000, 0.0105107859, 0.991427669]])  # yapf: disable

    lms_bar = dot_vector(M, rgb_bar)
    lms_bar[..., -1][np.asarray(np.asarray(wavelength) > 505)] = 0

    return lms_bar
Ejemplo n.º 45
0
def chromatic_adaptation_VonKries(XYZ, XYZ_w, XYZ_wr, transform='CAT02'):
    """
    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 whitepoint.
    XYZ_wr : array_like
        Reference viewing condition *CIE XYZ* tristimulus values of whitepoint.
    transform : unicode, optional
        **{'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.

    Examples
    --------
    >>> XYZ = np.array([0.07049534, 0.10080000, 0.09558313])
    >>> XYZ_w = np.array([1.09846607, 1.00000000, 0.35582280])
    >>> XYZ_wr = np.array([0.95042855, 1.00000000, 1.08890037])
    >>> chromatic_adaptation_VonKries(XYZ, XYZ_w, XYZ_wr)  # doctest: +ELLIPSIS
    array([ 0.0839746...,  0.1141321...,  0.2862554...])

    Using Bradford method:

    >>> XYZ = np.array([0.07049534, 0.10080000, 0.09558313])
    >>> XYZ_w = np.array([1.09846607, 1.00000000, 0.35582280])
    >>> XYZ_wr = np.array([0.95042855, 1.00000000, 1.08890037])
    >>> method = 'Bradford'
    >>> chromatic_adaptation_VonKries(  # doctest: +ELLIPSIS
    ...     XYZ, XYZ_w, XYZ_wr, method)
    array([ 0.0854032...,  0.1140122...,  0.2972149...])
    """

    cat = chromatic_adaptation_matrix_VonKries(XYZ_w, XYZ_wr, transform)
    XYZ_a = dot_vector(cat, XYZ)

    return XYZ_a
Ejemplo n.º 46
0
def LMS_10_degree_cmfs_to_XYZ_10_degree_cmfs(wavelength):
    """
    Converts *Stockman & Sharpe 10 Degree Cone Fundamentals* colour matching
    functions into the *CIE 2012 10 Degree Standard Observer* colour matching
    functions.

    Parameters
    ----------
    wavelength : numeric or array_like
        Wavelength :math:`\lambda` in nm.

    Returns
    -------
    ndarray
        *CIE 2012 10 Degree Standard Observer* spectral tristimulus values.

    Notes
    -----
    -   Data for the *CIE 2012 10 Degree Standard Observer* already exists,
        this definition is intended for educational purpose.

    References
    ----------
    -   :cite:`CVRLp`

    Examples
    --------
    >>> from colour.utilities import numpy_print_options
    >>> with numpy_print_options(suppress=True):
    ...     LMS_10_degree_cmfs_to_XYZ_10_degree_cmfs(700)  # doctest: +ELLIPSIS
    array([ 0.0098162...,  0.0037761...,  0.        ])
    """

    cmfs = LMS_CMFS['Stockman & Sharpe 10 Degree Cone Fundamentals']

    lms_bar = cmfs[wavelength]

    M = np.array([
        [1.93986443, -1.34664359, 0.43044935],
        [0.69283932, 0.34967567, 0.00000000],
        [0.00000000, 0.00000000, 2.14687945],
    ])

    xyz_bar = dot_vector(M, lms_bar)

    return xyz_bar
Ejemplo n.º 47
0
def RGB_10_degree_cmfs_to_LMS_10_degree_cmfs(wavelength):
    """
    Converts *Stiles & Burch 1959 10 Degree RGB CMFs* colour matching
    functions into the *Stockman & Sharpe 10 Degree Cone Fundamentals*
    spectral sensitivity functions.

    Parameters
    ----------
    wavelength : numeric or array_like
        Wavelength :math:`\lambda` in nm.

    Returns
    -------
    ndarray
        *Stockman & Sharpe 10 Degree Cone Fundamentals* spectral tristimulus
        values.

    Notes
    -----
    -   Data for the *Stockman & Sharpe 10 Degree Cone Fundamentals* already
        exists, this definition is intended for educational purpose.

    References
    ----------
    .. [3]  CIE TC 1-36. (2006). CIE 170-1:2006 Fundamental Chromaticity
            Diagram with Physiological Axes - Part 1 (pp. 1–56).
            ISBN:978-3-901-90646-6

    Examples
    --------
    >>> RGB_10_degree_cmfs_to_LMS_10_degree_cmfs(700)  # doctest: +ELLIPSIS
    array([ 0.0052860...,  0.0003252...,  0.        ])
    """

    cmfs = RGB_CMFS.get('Stiles & Burch 1959 10 Degree RGB CMFs')

    rgb_bar = cmfs.get(wavelength)

    M = np.array([[0.1923252690, 0.749548882, 0.0675726702],
                  [0.0192290085, 0.940908496, 0.113830196],
                  [0.0000000000, 0.0105107859, 0.991427669]])

    lms_bar = dot_vector(M, rgb_bar)
    lms_bar[..., -1][np.asarray(np.asarray(wavelength) > 505)] = 0

    return lms_bar
Ejemplo n.º 48
0
def LMS_10_degree_cmfs_to_XYZ_10_degree_cmfs(wavelength):
    """
    Converts *Stockman & Sharpe 10 Degree Cone Fundamentals* colour matching
    functions into the *CIE 2012 10 Degree Standard Observer* colour matching
    functions.

    Parameters
    ----------
    wavelength : numeric or array_like
        Wavelength :math:`\lambda` in nm.

    Returns
    -------
    ndarray
        *CIE 2012 10 Degree Standard Observer* spectral tristimulus values.

    Notes
    -----
    -   Data for the *CIE 2012 10 Degree Standard Observer* already exists,
        this definition is intended for educational purpose.

    References
    ----------
    .. [5]  CVRL. (n.d.). CIE (2012) 10-deg XYZ “physiologically-relevant”
            colour matching functions. Retrieved June 25, 2014, from
            http://www.cvrl.org/database/text/cienewxyz/cie2012xyz10.htm

    Examples
    --------
    >>> LMS_10_degree_cmfs_to_XYZ_10_degree_cmfs(700)  # doctest: +ELLIPSIS
    array([ 0.0098162...,  0.0037761...,  0.        ])
    """

    cmfs = LMS_CMFS.get('Stockman & Sharpe 10 Degree Cone Fundamentals')

    lms_bar = cmfs.get(wavelength)

    M = np.array([[1.93986443, -1.34664359, 0.43044935],
                  [0.69283932, 0.34967567, 0.00000000],
                  [0.00000000, 0.00000000, 2.14687945]])

    xyz_bar = dot_vector(M, lms_bar)

    return xyz_bar
Ejemplo n.º 49
0
def LMS_2_degree_cmfs_to_XYZ_2_degree_cmfs(wavelength):
    """
    Converts *Stockman & Sharpe 2 Degree Cone Fundamentals* colour matching
    functions into the *CIE 2012 2 Degree Standard Observer* colour matching
    functions.

    Parameters
    ----------
    wavelength : numeric or array_like
        Wavelength :math:`\lambda` in nm.

    Returns
    -------
    ndarray
        *CIE 2012 2 Degree Standard Observer* spectral tristimulus values.

    Notes
    -----
    -   Data for the *CIE 2012 2 Degree Standard Observer* already exists,
        this definition is intended for educational purpose.

    References
    ----------
    .. [4]  CVRL. (n.d.). CIE (2012) 2-deg XYZ “physiologically-relevant”
            colour matching functions. Retrieved June 25, 2014, from
            http://www.cvrl.org/database/text/cienewxyz/cie2012xyz2.htm

    Examples
    --------
    >>> LMS_2_degree_cmfs_to_XYZ_2_degree_cmfs(700)  # doctest: +ELLIPSIS
    array([ 0.0109677...,  0.0041959...,  0.        ])
    """

    cmfs = LMS_CMFS.get('Stockman & Sharpe 2 Degree Cone Fundamentals')

    lms_bar = cmfs.get(wavelength)

    M = np.array([[1.94735469, -1.41445123, 0.36476327],
                  [0.68990272, 0.34832189, 0.00000000],
                  [0.00000000, 0.00000000, 1.93485343]])

    xyz_bar = dot_vector(M, lms_bar)

    return xyz_bar
Ejemplo n.º 50
0
def XYZ_to_RGB_cie1994(XYZ):
    """
    Converts from *CIE XYZ* tristimulus values to cone responses.

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

    Returns
    -------
    ndarray
        Cone responses.

    Examples
    --------
    >>> XYZ = np.array([28.00, 21.26, 5.27])
    >>> XYZ_to_RGB_cie1994(XYZ)  # doctest: +ELLIPSIS
    array([ 25.8244273...,  18.6791422...,   4.8390194...])
    """

    return dot_vector(CIE1994_XYZ_TO_RGB_MATRIX, XYZ)
Ejemplo n.º 51
0
def RGB_to_XYZ_cie1994(RGB):
    """
    Converts from cone responses to *CIE XYZ* tristimulus values.

    Parameters
    ----------
    RGB : array_like
        Cone responses.

    Returns
    -------
    ndarray
        *CIE XYZ* tristimulus values.

    Examples
    --------
    >>> RGB = np.array([25.82442730, 18.67914220, 4.83901940])
    >>> RGB_to_XYZ_cie1994(RGB)  # doctest: +ELLIPSIS
    array([ 28.  ,  21.26,   5.27])
    """

    return dot_vector(CIE1994_RGB_TO_XYZ_MATRIX, RGB)
Ejemplo n.º 52
0
def XYZ_to_RGB_Nayatani95(XYZ):
    """
    Converts from *CIE XYZ* tristimulus values to cone responses.

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

    Returns
    -------
    ndarray
        Cone responses.

    Examples
    --------
    >>> XYZ = np.array([19.01, 20.00, 21.78])
    >>> XYZ_to_RGB_Nayatani95(XYZ)  # doctest: +ELLIPSIS
    array([ 20.000520...,  19.999783...,  19.998831...])
    """

    return dot_vector(NAYATANI95_XYZ_TO_RGB_MATRIX, XYZ)
Ejemplo n.º 53
0
def RGB_to_XYZ_Fairchild1990(RGB):
    """
    Converts from cone responses to *CIE XYZ* tristimulus values.

    Parameters
    ----------
    RGB : array_like
        Cone responses.

    Returns
    -------
    ndarray
        *CIE XYZ* tristimulus values.

    Examples
    --------
    >>> RGB = np.array([22.12319350, 23.60542240, 22.92795340])
    >>> RGB_to_XYZ_Fairchild1990(RGB)  # doctest: +ELLIPSIS
    array([ 19.53,  23.07,  24.97])
    """

    return dot_vector(FAIRCHILD1990_RGB_TO_XYZ_MATRIX, RGB)
Ejemplo n.º 54
0
def XYZ_to_RGB_Fairchild1990(XYZ):
    """
    Converts from *CIE XYZ* tristimulus values to cone responses.

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

    Returns
    -------
    ndarray
        Cone responses.

    Examples
    --------
    >>> XYZ = np.array([19.53, 23.07, 24.97])
    >>> XYZ_to_RGB_Fairchild1990(XYZ)  # doctest: +ELLIPSIS
    array([ 22.1231935...,  23.6054224...,  22.9279534...])
    """

    return dot_vector(FAIRCHILD1990_XYZ_TO_RGB_MATRIX, XYZ)
Ejemplo n.º 55
0
    def test_dot_vector(self):
        """
        Tests :func:`colour.utilities.array.dot_vector` definition.
        """

        m = np.array([[0.7328, 0.4296, -0.1624],
                      [-0.7036, 1.6975, 0.0061],
                      [0.0030, 0.0136, 0.9834]])
        m = np.reshape(np.tile(m, (6, 1)), (6, 3, 3))

        v = np.array([0.07049534, 0.10080000, 0.09558313])
        v = np.tile(v, (6, 1))

        np.testing.assert_almost_equal(
            dot_vector(m, v),
            np.array([[0.07943996, 0.12209054, 0.09557882],
                      [0.07943996, 0.12209054, 0.09557882],
                      [0.07943996, 0.12209054, 0.09557882],
                      [0.07943996, 0.12209054, 0.09557882],
                      [0.07943996, 0.12209054, 0.09557882],
                      [0.07943996, 0.12209054, 0.09557882]]),
            decimal=7)
Ejemplo n.º 56
0
def XYZ_to_rgb(XYZ):
    """
    Converts from *CIE XYZ* tristimulus values to *Hunt-Pointer-Estevez*
    :math:`\\rho\gamma\\beta` colourspace.

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

    Returns
    -------
    ndarray
        *Hunt-Pointer-Estevez* :math:`\\rho\gamma\\beta` colourspace.

    Examples
    --------
    >>> XYZ = np.array([19.01, 20.00, 21.78])
    >>> XYZ_to_rgb(XYZ)  # doctest: +ELLIPSIS
    array([ 19.4743367...,  20.3101217...,  21.78     ])
    """

    return dot_vector(XYZ_TO_HPE_MATRIX, XYZ)
Ejemplo n.º 57
0
def XYZ_to_CIECAM02(XYZ,
                    XYZ_w,
                    L_A,
                    Y_b,
                    surround=CIECAM02_VIEWING_CONDITIONS.get('Average'),
                    discount_illuminant=False):
    """
    Computes the CIECAM02 colour appearance model correlates from given
    *CIE XYZ* tristimulus values.

    This is the *forward* implementation.

    Parameters
    ----------
    XYZ : array_like
        *CIE XYZ* tristimulus values of test sample / stimulus in domain
        [0, 100].
    XYZ_w : array_like
        *CIE XYZ* tristimulus values of reference white in domain [0, 100].
    L_A : numeric or array_like
        Adapting field *luminance* :math:`L_A` in :math:`cd/m^2`.
    Y_b : numeric or array_like
        Adapting field *Y* tristimulus value :math:`Y_b`.
    surround : CIECAM02_InductionFactors, optional
        Surround viewing conditions induction factors.
    discount_illuminant : bool, optional
        Truth value indicating if the illuminant should be discounted.

    Returns
    -------
    CIECAM02_Specification
        CIECAM02 colour appearance model specification.

    Warning
    -------
    The input domain of that definition is non standard!

    Notes
    -----
    -   Input *CIE XYZ* tristimulus values are in domain [0, 100].
    -   Input *CIE XYZ_w* tristimulus values are in domain [0, 100].

    Examples
    --------
    >>> XYZ = np.array([19.01, 20.00, 21.78])
    >>> XYZ_w = np.array([95.05, 100.00, 108.88])
    >>> L_A = 318.31
    >>> Y_b = 20.0
    >>> surround = CIECAM02_VIEWING_CONDITIONS['Average']
    >>> XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b, surround)  # doctest: +ELLIPSIS
    CIECAM02_Specification(J=41.7310911..., C=0.1047077..., h=219.0484326..., \
s=2.3603053..., Q=195.3713259..., M=0.1088421..., H=array(278.0607358...), \
HC=None)
    """

    _X_w, Y_w, _Z_w = tsplit(XYZ_w)
    L_A = np.asarray(L_A)
    Y_b = np.asarray(Y_b)

    n, F_L, N_bb, N_cb, z = tsplit(viewing_condition_dependent_parameters(
        Y_b, Y_w, L_A))

    # Converting *CIE XYZ* tristimulus values to CMCCAT2000 transform
    # sharpened *RGB* values.
    RGB = dot_vector(CAT02_CAT, XYZ)
    RGB_w = dot_vector(CAT02_CAT, XYZ_w)

    # Computing degree of adaptation :math:`D`.
    D = degree_of_adaptation(surround.F,
                             L_A) if not discount_illuminant else 1

    # Computing full chromatic adaptation.
    RGB_c = full_chromatic_adaptation_forward(
        RGB, RGB_w, Y_w, D)
    RGB_wc = full_chromatic_adaptation_forward(
        RGB_w, RGB_w, Y_w, D)

    # Converting to *Hunt-Pointer-Estevez* colourspace.
    RGB_p = RGB_to_rgb(RGB_c)
    RGB_pw = RGB_to_rgb(RGB_wc)

    # Applying forward post-adaptation non linear response compression.
    RGB_a = post_adaptation_non_linear_response_compression_forward(
        RGB_p, F_L)
    RGB_aw = post_adaptation_non_linear_response_compression_forward(
        RGB_pw, F_L)

    # Converting to preliminary cartesian coordinates.
    a, b = tsplit(opponent_colour_dimensions_forward(RGB_a))

    # -------------------------------------------------------------------------
    # Computing the *hue* angle :math:`h`.
    h = hue_angle(a, b)
    # -------------------------------------------------------------------------
    # Computing hue :math:`h` quadrature :math:`H`.
    H = hue_quadrature(h)
    # TODO: Compute hue composition.

    # Computing eccentricity factor *e_t*.
    e_t = eccentricity_factor(h)

    # Computing achromatic responses for the stimulus and the whitepoint.
    A = achromatic_response_forward(RGB_a, N_bb)
    A_w = achromatic_response_forward(RGB_aw, N_bb)

    # -------------------------------------------------------------------------
    # Computing the correlate of *Lightness* :math:`J`.
    # -------------------------------------------------------------------------
    J = lightness_correlate(A, A_w, surround.c, z)

    # -------------------------------------------------------------------------
    # Computing the correlate of *brightness* :math:`Q`.
    # -------------------------------------------------------------------------
    Q = brightness_correlate(surround.c, J, A_w, F_L)

    # -------------------------------------------------------------------------
    # Computing the correlate of *chroma* :math:`C`.
    # -------------------------------------------------------------------------
    C = chroma_correlate(J, n, surround.N_c, N_cb, e_t, a, b, RGB_a)

    # -------------------------------------------------------------------------
    # Computing the correlate of *colourfulness* :math:`M`.
    # -------------------------------------------------------------------------
    M = colourfulness_correlate(C, F_L)

    # -------------------------------------------------------------------------
    # Computing the correlate of *saturation* :math:`s`.
    # -------------------------------------------------------------------------
    s = saturation_correlate(M, Q)

    return CIECAM02_Specification(J, C, h, s, Q, M, H, None)
Ejemplo n.º 58
0
def CIECAM02_to_XYZ(J,
                    C,
                    h,
                    XYZ_w,
                    L_A,
                    Y_b,
                    surround=CIECAM02_VIEWING_CONDITIONS.get(
                        'Average'),
                    discount_illuminant=False):
    """
    Converts CIECAM02 specification to *CIE XYZ* tristimulus values.

    This is the *reverse* implementation.

    Parameters
    ----------
    J : numeric or array_like
        Correlate of *Lightness* :math:`J`.
    C : numeric or array_like
        Correlate of *chroma* :math:`C`.
    h : numeric or array_like
        *Hue* angle :math:`h` in degrees.
    XYZ_w : array_like
        *CIE XYZ* tristimulus values of reference white.
    L_A : numeric or array_like
        Adapting field *luminance* :math:`L_A` in :math:`cd/m^2`.
    Y_b : numeric or array_like
        Adapting field *Y* tristimulus value :math:`Y_b`.
    surround : CIECAM02_Surround, optional
        Surround viewing conditions.
    discount_illuminant : bool, optional
        Discount the illuminant.

    Returns
    -------
    XYZ : ndarray
        *CIE XYZ* tristimulus values.

    Warning
    -------
    The output range of that definition is non standard!

    Notes
    -----
    -   Input *CIE XYZ_w* tristimulus values are in domain [0, 100].
    -   Output *CIE XYZ* tristimulus values are in range [0, 100].

    Examples
    --------
    >>> J = 41.731091132513917
    >>> C = 0.104707757171105
    >>> h = 219.04843265827190
    >>> XYZ_w = np.array([95.05, 100.00, 108.88])
    >>> L_A = 318.31
    >>> Y_b = 20.0
    >>> CIECAM02_to_XYZ(J, C, h, XYZ_w, L_A, Y_b)  # doctest: +ELLIPSIS
    array([ 19.01...,  20...  ,  21.78...])
    """

    _X_w, Y_w, _Zw = tsplit(XYZ_w)

    n, F_L, N_bb, N_cb, z = tsplit(viewing_condition_dependent_parameters(
        Y_b, Y_w, L_A))

    # Converting *CIE XYZ* tristimulus values to CMCCAT2000 transform
    # sharpened *RGB* values.
    RGB_w = dot_vector(CAT02_CAT, XYZ_w)

    # Computing degree of adaptation :math:`D`.
    D = degree_of_adaptation(surround.F, L_A) if not discount_illuminant else 1

    # Computation full chromatic adaptation.
    RGB_wc = full_chromatic_adaptation_forward(RGB_w, RGB_w, Y_w, D)

    # Converting to *Hunt-Pointer-Estevez* colourspace.
    RGB_pw = RGB_to_rgb(RGB_wc)

    # Applying post-adaptation non linear response compression.
    RGB_aw = post_adaptation_non_linear_response_compression_forward(
        RGB_pw, F_L)

    # Computing achromatic responses for the stimulus and the whitepoint.
    A_w = achromatic_response_forward(RGB_aw, N_bb)

    # Computing temporary magnitude quantity :math:`t`.
    t = temporary_magnitude_quantity_reverse(C, J, n)

    # Computing eccentricity factor *e_t*.
    e_t = eccentricity_factor(h)

    # Computing achromatic response :math:`A` for the stimulus.
    A = achromatic_response_reverse(A_w, J, surround.c, z)

    # Computing *P_1* to *P_3*.
    P_n = P(surround.N_c, N_cb, e_t, t, A, N_bb)
    _P_1, P_2, _P_3 = tsplit(P_n)

    # Computing opponent colour dimensions :math:`a` and :math:`b`.
    a, b = tsplit(opponent_colour_dimensions_reverse(P_n, h))

    # Computing post-adaptation non linear response compression matrix.
    RGB_a = post_adaptation_non_linear_response_compression_matrix(
        P_2, a, b)

    # Applying reverse post-adaptation non linear response compression.
    RGB_p = post_adaptation_non_linear_response_compression_reverse(
        RGB_a, F_L)

    # Converting to *Hunt-Pointer-Estevez* colourspace.
    RGB_c = rgb_to_RGB(RGB_p)

    # Applying reverse full chromatic adaptation.
    RGB = full_chromatic_adaptation_reverse(RGB_c, RGB_w, Y_w, D)

    # Converting CMCCAT2000 transform sharpened *RGB* values to *CIE XYZ*
    # tristimulus values.
    XYZ = dot_vector(CAT02_INVERSE_CAT, RGB)

    return XYZ
Ejemplo n.º 59
0
def chromatic_adaptation_VonKries(XYZ, XYZ_w, XYZ_wr, transform='CAT02'):
    """
    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 whitepoint.
    XYZ_wr : array_like
        Reference viewing condition *CIE XYZ* tristimulus values of whitepoint.
    transform : unicode, optional
        **{'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_n``  | [0, 1]                | [0, 1]        |
    +------------+-----------------------+---------------+
    | ``XYZ_r``  | [0, 1]                | [0, 1]        |
    +------------+-----------------------+---------------+

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

    References
    ----------
    :cite:`Fairchild2013t`

    Examples
    --------
    >>> 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_VonKries(XYZ, XYZ_w, XYZ_wr)  # doctest: +ELLIPSIS
    array([ 0.2163881...,  0.1257    ,  0.0384749...])

    Using Bradford method:

    >>> 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])
    >>> transform = 'Bradford'
    >>> chromatic_adaptation_VonKries(XYZ, XYZ_w, XYZ_wr, transform)
    ... # doctest: +ELLIPSIS
    array([ 0.2166600...,  0.1260477...,  0.0385506...])
    """

    XYZ = to_domain_1(XYZ)

    M_CAT = chromatic_adaptation_matrix_VonKries(XYZ_w, XYZ_wr, transform)
    XYZ_a = dot_vector(M_CAT, XYZ)

    return from_range_1(XYZ_a)