Example #1
0
def XYZ_to_xy(XYZ,
              illuminant=ILLUMINANTS.get(
                  'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Returns the *xy* chromaticity coordinates from given *CIE XYZ* tristimulus
    values.

    Parameters
    ----------
    XYZ : array_like
        *CIE XYZ* tristimulus values.
    illuminant : array_like, optional
        Reference *illuminant* chromaticity coordinates.

    Returns
    -------
    ndarray
        *xy* chromaticity coordinates.

    Notes
    -----
    -   Input *CIE XYZ* tristimulus values are in domain [0, 1].
    -   Output *xy* chromaticity coordinates are in range [0, 1].

    Examples
    --------
    >>> XYZ = np.array([0.07049534, 0.10080000, 0.09558313])
    >>> XYZ_to_xy(XYZ)  # doctest: +ELLIPSIS
    array([ 0.2641477...,  0.3777000...])
    """

    xy = xyY_to_xy(XYZ_to_xyY(XYZ, illuminant))

    return xy
Example #2
0
def XYZ_to_xy(XYZ, illuminant=ILLUMINANTS.get("CIE 1931 2 Degree Standard Observer").get("D50")):
    """
    Returns the *xy* chromaticity coordinates from given *CIE XYZ* tristimulus
    values.

    Parameters
    ----------
    XYZ : array_like
        *CIE XYZ* tristimulus values.
    illuminant : array_like, optional
        Reference *illuminant* chromaticity coordinates.

    Returns
    -------
    ndarray
        *xy* chromaticity coordinates.

    Notes
    -----
    -   Input *CIE XYZ* tristimulus values are in domain [0, 1].
    -   Output *xy* chromaticity coordinates are in domain [0, 1].

    Examples
    --------
    >>> XYZ = np.array([0.07049534, 0.10080000, 0.09558313])
    >>> XYZ_to_xy(XYZ)  # doctest: +ELLIPSIS
    array([ 0.2641477...,  0.3777000...])
    """

    xy = xyY_to_xy(XYZ_to_xyY(XYZ, illuminant))

    return xy
Example #3
0
def RGB_to_Lab(RGB, colourspace):
    """
    Converts given *RGB* value from given colourspace to *CIE Lab* colourspace.

    Parameters
    ----------
    RGB : array_like
        *RGB* value.
    colourspace : RGB_Colourspace
        *RGB* colourspace.

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

    return XYZ_to_Lab(
        RGB_to_XYZ(np.array(RGB),
                   colourspace.whitepoint,
                   ILLUMINANTS.get(
                       'CIE 1931 2 Degree Standard Observer').get('E'),
                   colourspace.to_XYZ,
                   'Bradford',
                   colourspace.decoding_cctf),
        colourspace.whitepoint)
Example #4
0
def XYZ_to_xy(XYZ,
              illuminant=ILLUMINANTS.get(
                  'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Returns the *xy* chromaticity coordinates from given *CIE XYZ* colourspace
    matrix.

    Parameters
    ----------
    XYZ : array_like, (3,)
        *CIE XYZ* colourspace matrix.
    illuminant : array_like, optional
        Reference *illuminant* chromaticity coordinates.

    Returns
    -------
    tuple
        *xy* chromaticity coordinates.

    Notes
    -----
    -   Input *CIE XYZ* colourspace matrix is in domain [0, 1].
    -   Output *xy* chromaticity coordinates are in domain [0, 1].

    Examples
    --------
    >>> XYZ_to_xy(np.array([0.97137399, 1, 1.04462134]))  # doctest: +ELLIPSIS
    (0.3220741..., 0.3315655...)
    >>> XYZ_to_xy((0.97137399, 1, 1.04462134))  # doctest: +ELLIPSIS
    (0.3220741..., 0.3315655...)
    """

    xyY = np.ravel(XYZ_to_xyY(XYZ, illuminant))
    return xyY[0], xyY[1]
Example #5
0
def XYZ_to_xy(XYZ,
              illuminant=ILLUMINANTS.get(
                  'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Returns the *xy* chromaticity coordinates from given *CIE XYZ* colourspace
    matrix.

    Parameters
    ----------
    XYZ : array_like, (3,)
        *CIE XYZ* colourspace matrix.
    illuminant : array_like, optional
        Reference *illuminant* chromaticity coordinates.

    Returns
    -------
    tuple
        *xy* chromaticity coordinates.

    Notes
    -----
    -   Input *CIE XYZ* colourspace matrix is in domain [0, 1].
    -   Output *xy* chromaticity coordinates are in domain [0, 1].

    Examples
    --------
    >>> XYZ = np.array([0.07049534, 0.1008, 0.09558313])
    >>> XYZ_to_xy(XYZ)  # doctest: +ELLIPSIS
    (0.2641477..., 0.3777000...)
    """

    xyY = np.ravel(XYZ_to_xyY(XYZ, illuminant))
    return xyY[0], xyY[1]
Example #6
0
def XYZ_to_xy(XYZ,
              illuminant=ILLUMINANTS.get(
                  'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Returns the *xy* chromaticity coordinates from given *CIE XYZ* colourspace
    matrix.

    Parameters
    ----------
    XYZ : array_like, (3,)
        *CIE XYZ* colourspace matrix.
    illuminant : array_like, optional
        Reference *illuminant* chromaticity coordinates.

    Returns
    -------
    tuple
        *xy* chromaticity coordinates.

    Notes
    -----
    -   Input *CIE XYZ* colourspace matrix is in domain [0, 1].
    -   Output *xy* chromaticity coordinates are in domain [0, 1].

    Examples
    --------
    >>> XYZ_to_xy(np.array([0.97137399, 1, 1.04462134]))  # doctest: +ELLIPSIS
    (0.3220741..., 0.3315655...)
    >>> XYZ_to_xy((0.97137399, 1, 1.04462134))  # doctest: +ELLIPSIS
    (0.3220741..., 0.3315655...)
    """

    xyY = np.ravel(XYZ_to_xyY(XYZ, illuminant))
    return xyY[0], xyY[1]
Example #7
0
def Luv_to_XYZ(Luv,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE Luv* colourspace to *CIE XYZ* tristimulus values.

    Parameters
    ----------
    Luv : array_like
        *CIE Luv* colourspace array.
    illuminant : array_like, optional
        Reference *illuminant* *xy* chromaticity coordinates or *CIE xyY*
        colourspace array.

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

    Notes
    -----
    -   Input :math:`L^*` is in domain [0, 100].
    -   Input *illuminant* *xy* chromaticity coordinates or *CIE xyY*
        colourspace array are in domain [0, :math:`\infty`].
    -   Output *CIE XYZ* tristimulus values are in range [0, 1].

    References
    ----------
    .. [3]  Lindbloom, B. (2003). Luv to XYZ. Retrieved February 24, 2014,
            from http://brucelindbloom.com/Eqn_Luv_to_XYZ.html

    Examples
    --------
    >>> Luv = np.array([37.9856291 , -28.80219593,  -1.35800706])
    >>> Luv_to_XYZ(Luv)  # doctest: +ELLIPSIS
    array([ 0.0704953...,  0.1008    ,  0.0955831...])
    """

    L, u, v = tsplit(Luv)
    X_r, Y_r, Z_r = tsplit(xyY_to_XYZ(xy_to_xyY(illuminant)))

    Y = np.where(L > CIE_E * CIE_K, ((L + 16) / 116) ** 3, L / CIE_K)

    a = 1 / 3 * ((52 * L / (u + 13 * L *
                            (4 * X_r / (X_r + 15 * Y_r + 3 * Z_r)))) - 1)
    b = -5 * Y
    c = -1 / 3.0
    d = Y * (39 * L / (v + 13 * L *
                       (9 * Y_r / (X_r + 15 * Y_r + 3 * Z_r))) - 5)

    X = (d - b) / (a - c)
    Z = X * a + b

    XYZ = tstack((X, Y, Z))

    return XYZ
Example #8
0
def XYZ_to_Lab(XYZ,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE XYZ* tristimulus values to *CIE Lab* colourspace.

    Parameters
    ----------
    XYZ : array_like
        *CIE XYZ* tristimulus values.
    illuminant : array_like, optional
        Reference *illuminant* *xy* chromaticity coordinates or *CIE xyY*
        colourspace array.

    Returns
    -------
    ndarray
        *CIE Lab* colourspace array.

    Notes
    -----
    -   Input *CIE XYZ* tristimulus values are in domain [0, 1].
    -   Input *illuminant* *xy* chromaticity coordinates or *CIE xyY*
        colourspace array are in domain [0, :math:`\infty`].
    -   Output *Lightness* :math:`L^*` is in range [0, 100].

    References
    ----------
    .. [2]  Lindbloom, B. (2003). XYZ to Lab. Retrieved February 24, 2014,
            from http://www.brucelindbloom.com/Eqn_XYZ_to_Lab.html

    Examples
    --------
    >>> XYZ = np.array([0.07049534, 0.10080000, 0.09558313])
    >>> XYZ_to_Lab(XYZ)  # doctest: +ELLIPSIS
    array([ 37.9856291..., -23.6290768...,  -4.4174661...])
    """

    XYZ = np.asarray(XYZ)
    XYZ_r = xyY_to_XYZ(xy_to_xyY(illuminant))

    XYZ_f = XYZ / XYZ_r

    XYZ_f = np.where(XYZ_f > CIE_E,
                     np.power(XYZ_f, 1 / 3),
                     (CIE_K * XYZ_f + 16) / 116)

    X_f, Y_f, Z_f = tsplit(XYZ_f)

    L = 116 * Y_f - 16
    a = 500 * (X_f - Y_f)
    b = 200 * (Y_f - Z_f)

    Lab = tstack((L, a, b))

    return Lab
Example #9
0
def XYZ_to_Lab(XYZ,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE XYZ* tristimulus values to *CIE Lab* colourspace.

    Parameters
    ----------
    XYZ : array_like
        *CIE XYZ* tristimulus values.
    illuminant : array_like, optional
        Reference *illuminant* *xy* chromaticity coordinates or *CIE xyY*
        colourspace array.

    Returns
    -------
    ndarray
        *CIE Lab* colourspace array.

    Notes
    -----
    -   Input *CIE XYZ* tristimulus values are in domain [0, 1].
    -   Input *illuminant* *xy* chromaticity coordinates or *CIE xyY*
        colourspace array are in domain [0, :math:`\infty`].
    -   Output *Lightness* :math:`L^*` is in domain [0, 100].

    References
    ----------
    .. [2]  Lindbloom, B. (2003). XYZ to Lab. Retrieved February 24, 2014,
            from http://www.brucelindbloom.com/Eqn_XYZ_to_Lab.html

    Examples
    --------
    >>> XYZ = np.array([0.07049534, 0.10080000, 0.09558313])
    >>> XYZ_to_Lab(XYZ)  # doctest: +ELLIPSIS
    array([ 37.9856291..., -23.6230288...,  -4.4141703...])
    """

    XYZ = np.asarray(XYZ)
    XYZ_r = xyY_to_XYZ(xy_to_xyY(illuminant))

    XYZ_f = XYZ / XYZ_r

    XYZ_f = np.where(XYZ_f > CIE_E,
                     np.power(XYZ_f, 1 / 3),
                     (CIE_K * XYZ_f + 16) / 116)

    X_f, Y_f, Z_f = tsplit(XYZ_f)

    L = 116 * Y_f - 16
    a = 500 * (X_f - Y_f)
    b = 200 * (Y_f - Z_f)

    Lab = tstack((L, a, b))

    return Lab
Example #10
0
def XYZ_to_Luv(XYZ,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE XYZ* tristimulus values to *CIE Luv* colourspace.

    Parameters
    ----------
    XYZ : array_like
        *CIE XYZ* tristimulus values.
    illuminant : array_like, optional
        Reference *illuminant* *xy* chromaticity coordinates or *CIE xyY*
        colourspace array.

    Returns
    -------
    ndarray
        *CIE Luv* colourspace array.

    Notes
    -----
    -   Input *CIE XYZ* tristimulus values are in domain [0, 1].
    -   Input *illuminant* *xy* chromaticity coordinates or *CIE xyY*
        colourspace array are in domain [0, :math:`\infty`].
    -   Output :math:`L^*` is in range [0, 100].

    References
    ----------
    .. [2]  Lindbloom, B. (2003). XYZ to Luv. Retrieved February 24, 2014,
            from http://brucelindbloom.com/Eqn_XYZ_to_Luv.html

    Examples
    --------
    >>> XYZ = np.array([0.07049534, 0.10080000, 0.09558313])
    >>> XYZ_to_Luv(XYZ)  # doctest: +ELLIPSIS
    array([ 37.9856291..., -28.8021959...,  -1.3580070...])
    """

    X, Y, Z = tsplit(XYZ)
    X_r, Y_r, Z_r = tsplit(xyY_to_XYZ(xy_to_xyY(illuminant)))

    y_r = Y / Y_r

    L = np.where(y_r > CIE_E, 116 * y_r ** (1 / 3) - 16, CIE_K * y_r)

    u = (13 * L * ((4 * X / (X + 15 * Y + 3 * Z)) -
                   (4 * X_r / (X_r + 15 * Y_r + 3 * Z_r))))
    v = (13 * L * ((9 * Y / (X + 15 * Y + 3 * Z)) -
                   (9 * Y_r / (X_r + 15 * Y_r + 3 * Z_r))))

    Luv = tstack((L, u, v))

    return Luv
Example #11
0
def XYZ_to_UVW(XYZ,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE XYZ* tristimulus values to *CIE 1964 U\*V\*W\**
    colourspace.

    Parameters
    ----------
    XYZ : array_like
        *CIE XYZ* tristimulus values.
    illuminant : array_like, optional
        Reference *illuminant* *xy* chromaticity coordinates or *CIE xyY*
        colourspace array.

    Returns
    -------
    ndarray
        *CIE 1964 U\*V\*W\** colourspace array.

    Notes
    -----
    -   Input *CIE XYZ* tristimulus values are in domain [0, 100].
    -   Input *illuminant* *xy* chromaticity coordinates or *CIE xyY*
        colourspace array are in domain [0, :math:`\infty`].
    -   Output *CIE UVW* colourspace array is in range [0, 100].

    Warning
    -------
    The input / output domains of that definition are non standard!

    Examples
    --------
    >>> import numpy as np
    >>> XYZ = np.array([0.07049534, 0.10080000, 0.09558313]) * 100
    >>> XYZ_to_UVW(XYZ)  # doctest: +ELLIPSIS
    array([-28.0579733...,  -0.8819449...,  37.0041149...])
    """

    xyY = XYZ_to_xyY(XYZ, xyY_to_xy(illuminant))
    _x, _y, Y = tsplit(xyY)

    u, v = tsplit(UCS_to_uv(XYZ_to_UCS(XYZ)))
    u_0, v_0 = tsplit(
        UCS_to_uv(XYZ_to_UCS(xyY_to_XYZ(xy_to_xyY(illuminant)))))

    W = 25 * Y ** (1 / 3) - 17
    U = 13 * W * (u - u_0)
    V = 13 * W * (v - v_0)

    UVW = tstack((U, V, W))

    return UVW
Example #12
0
def XYZ_to_UVW(XYZ,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE XYZ* tristimulus values to *CIE 1964 U\*V\*W\**
    colourspace.

    Parameters
    ----------
    XYZ : array_like
        *CIE XYZ* tristimulus values.
    illuminant : array_like, optional
        Reference *illuminant* *xy* chromaticity coordinates or *CIE xyY*
        colourspace array.

    Returns
    -------
    ndarray
        *CIE 1964 U\*V\*W\** colourspace array.

    Notes
    -----
    -   Input *CIE XYZ* tristimulus values are in domain [0, 100].
    -   Input *illuminant* *xy* chromaticity coordinates or *CIE xyY*
        colourspace array are in domain [0, :math:`\infty`].
    -   Output *CIE UVW* colourspace array is in domain [0, 100].

    Warning
    -------
    The input / output domains of that definition are non standard!

    Examples
    --------
    >>> import numpy as np
    >>> XYZ = np.array([0.07049534, 0.10080000, 0.09558313]) * 100
    >>> XYZ_to_UVW(XYZ)  # doctest: +ELLIPSIS
    array([-28.0483277...,  -0.8805242...,  37.0041149...])
    """

    xyY = XYZ_to_xyY(XYZ, xyY_to_xy(illuminant))
    _x, _y, Y = tsplit(xyY)

    u, v = tsplit(UCS_to_uv(XYZ_to_UCS(XYZ)))
    u_0, v_0 = tsplit(UCS_to_uv(XYZ_to_UCS(xyY_to_XYZ(xy_to_xyY(illuminant)))))

    W = 25 * Y**(1 / 3) - 17
    U = 13 * W * (u - u_0)
    V = 13 * W * (v - v_0)

    UVW = tstack((U, V, W))

    return UVW
Example #13
0
def Lab_to_XYZ(Lab,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE Lab* colourspace to *CIE XYZ* tristimulus values.

    Parameters
    ----------
    Lab : array_like
        *CIE Lab* colourspace array.
    illuminant : array_like, optional
        Reference *illuminant* *xy* chromaticity coordinates or *CIE xyY*
        colourspace array.

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

    Notes
    -----
    -   Input *Lightness* :math:`L^*` is in domain [0, 100].
    -   Input *illuminant* *xy* chromaticity coordinates or *CIE xyY*
        colourspace array are in domain [0, :math:`\infty`].
    -   Output *CIE XYZ* tristimulus values are in domain [0, 1].

    References
    ----------
    .. [3]  Lindbloom, B. (2008). Lab to XYZ. Retrieved February 24, 2014,
            from http://www.brucelindbloom.com/Eqn_Lab_to_XYZ.html

    Examples
    --------
    >>> Lab = np.array([37.98562910, -23.62302887, -4.41417036])
    >>> Lab_to_XYZ(Lab)  # doctest: +ELLIPSIS
    array([ 0.0704953...,  0.1008    ,  0.0955831...])
    """

    L, a, b = tsplit(Lab)
    XYZ_r = xyY_to_XYZ(xy_to_xyY(illuminant))

    f_y = (L + 16) / 116
    f_x = a / 500 + f_y
    f_z = f_y - b / 200

    x_r = np.where(f_x**3 > CIE_E, f_x**3, (116 * f_x - 16) / CIE_K)
    y_r = np.where(L > CIE_K * CIE_E, ((L + 16) / 116)**3, L / CIE_K)
    z_r = np.where(f_z**3 > CIE_E, f_z**3, (116 * f_z - 16) / CIE_K)

    XYZ = tstack((x_r, y_r, z_r)) * XYZ_r

    return XYZ
Example #14
0
def Lab_to_XYZ(Lab,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE Lab* colourspace to *CIE XYZ* colourspace.

    Parameters
    ----------
    Lab : array_like, (3,)
        *CIE Lab* colourspace matrix.
    illuminant : array_like, optional
        Reference *illuminant* chromaticity coordinates.

    Returns
    -------
    ndarray, (3,)
        *CIE XYZ* colourspace matrix.

    Notes
    -----
    -   Input *Lightness* :math:`L^*` is in domain [0, 100].
    -   Input *illuminant* chromaticity coordinates are in domain [0, 1].
    -   Output *CIE XYZ* colourspace matrix is in domain [0, 1].

    References
    ----------
    .. [3]  http://www.brucelindbloom.com/Eqn_Lab_to_XYZ.html
            (Last accessed 24 February 2014)

    Examples
    --------
    >>> Lab = np.array([100, -7.41787844, -15.85742105])
    >>> Lab_to_XYZ(Lab)  # doctest: +ELLIPSIS
    array([ 0.9219310...,  1.        ,  1.0374424...])
    """

    L, a, b = np.ravel(Lab)
    Xr, Yr, Zr = np.ravel(xy_to_XYZ(illuminant))

    fy = (L + 16) / 116
    fx = a / 500 + fy
    fz = fy - b / 200

    xr = fx ** 3 if fx ** 3 > CIE_E else (116 * fx - 16) / CIE_K
    yr = ((L + 16) / 116) ** 3 if L > CIE_K * CIE_E else L / CIE_K
    zr = fz ** 3 if fz ** 3 > CIE_E else (116 * fz - 16) / CIE_K

    X = xr * Xr
    Y = yr * Yr
    Z = zr * Zr

    return np.array([X, Y, Z])
Example #15
0
def Luv_to_XYZ(Luv,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE Luv* colourspace to *CIE XYZ* colourspace.

    Parameters
    ----------
    Luv : array_like, (3,)
        *CIE Luv* colourspace matrix.
    illuminant : array_like, optional
        Reference *illuminant* chromaticity coordinates.

    Returns
    -------
    ndarray, (3,)
        *CIE XYZ* colourspace matrix.

    Notes
    -----
    -   Input :math:`L^*` is in domain [0, 100].
    -   Input *illuminant* chromaticity coordinates are in domain [0, 1].
    -   Output *CIE XYZ* colourspace matrix is in domain [0, 1].

    References
    ----------
    .. [3]  http://brucelindbloom.com/Eqn_Luv_to_XYZ.html
            (Last accessed 24 February 2014)

    Examples
    --------
    >>> Luv = np.array([100, -20.04304247, -19.81676035])
    >>> Luv_to_XYZ(Luv)  # doctest: +ELLIPSIS
    array([ 0.9219310...,  1.        ,  1.0374424...])
    """

    L, u, v = np.ravel(Luv)
    Xr, Yr, Zr = np.ravel(xy_to_XYZ(illuminant))

    Y = ((L + 16) / 116) ** 3 if L > CIE_E * CIE_K else L / CIE_K

    a = 1 / 3 * ((52 * L / (u + 13 * L *
                            (4 * Xr / (Xr + 15 * Yr + 3 * Zr)))) - 1)
    b = -5 * Y
    c = -1 / 3.0
    d = Y * (39 * L / (v + 13 * L *
                       (9 * Yr / (Xr + 15 * Yr + 3 * Zr))) - 5)

    X = (d - b) / (a - c)
    Z = X * a + b

    return np.array([X, Y, Z])
Example #16
0
def Lab_to_XYZ(Lab,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE Lab* colourspace to *CIE XYZ* tristimulus values.

    Parameters
    ----------
    Lab : array_like
        *CIE Lab* colourspace array.
    illuminant : array_like, optional
        Reference *illuminant* *xy* chromaticity coordinates or *CIE xyY*
        colourspace array.

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

    Notes
    -----
    -   Input *Lightness* :math:`L^*` is in domain [0, 100].
    -   Input *illuminant* *xy* chromaticity coordinates or *CIE xyY*
        colourspace array are in domain [0, :math:`\infty`].
    -   Output *CIE XYZ* tristimulus values are in domain [0, 1].

    References
    ----------
    .. [3]  Lindbloom, B. (2008). Lab to XYZ. Retrieved February 24, 2014,
            from http://www.brucelindbloom.com/Eqn_Lab_to_XYZ.html

    Examples
    --------
    >>> Lab = np.array([37.98562910, -23.62302887, -4.41417036])
    >>> Lab_to_XYZ(Lab)  # doctest: +ELLIPSIS
    array([ 0.0704953...,  0.1008    ,  0.0955831...])
    """

    L, a, b = tsplit(Lab)
    XYZ_r = xyY_to_XYZ(xy_to_xyY(illuminant))

    f_y = (L + 16) / 116
    f_x = a / 500 + f_y
    f_z = f_y - b / 200

    x_r = np.where(f_x ** 3 > CIE_E, f_x ** 3, (116 * f_x - 16) / CIE_K)
    y_r = np.where(L > CIE_K * CIE_E, ((L + 16) / 116) ** 3, L / CIE_K)
    z_r = np.where(f_z ** 3 > CIE_E, f_z ** 3, (116 * f_z - 16) / CIE_K)

    XYZ = tstack((x_r, y_r, z_r)) * XYZ_r

    return XYZ
Example #17
0
def Lab_to_XYZ(Lab,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE Lab* colourspace to *CIE XYZ* colourspace.

    Parameters
    ----------
    Lab : array_like, (3,)
        *CIE Lab* colourspace matrix.
    illuminant : array_like, optional
        Reference *illuminant* chromaticity coordinates.

    Returns
    -------
    ndarray, (3,)
        *CIE XYZ* colourspace matrix.

    Notes
    -----
    -   Input *Lightness* :math:`L^*` is in domain [0, 100].
    -   Input *illuminant* chromaticity coordinates are in domain [0, 1].
    -   Output *CIE XYZ* colourspace matrix is in domain [0, 1].

    References
    ----------
    .. [3]  http://www.brucelindbloom.com/Eqn_Lab_to_XYZ.html
            (Last accessed 24 February 2014)

    Examples
    --------
    >>> Lab = np.array([100, -7.41787844, -15.85742105])
    >>> Lab_to_XYZ(Lab)  # doctest: +ELLIPSIS
    array([ 0.9219310...,  1.        ,  1.0374424...])
    """

    L, a, b = np.ravel(Lab)
    Xr, Yr, Zr = np.ravel(xy_to_XYZ(illuminant))

    fy = (L + 16) / 116
    fx = a / 500 + fy
    fz = fy - b / 200

    xr = fx**3 if fx**3 > CIE_E else (116 * fx - 16) / CIE_K
    yr = ((L + 16) / 116)**3 if L > CIE_K * CIE_E else L / CIE_K
    zr = fz**3 if fz**3 > CIE_E else (116 * fz - 16) / CIE_K

    X = xr * Xr
    Y = yr * Yr
    Z = zr * Zr

    return np.array([X, Y, Z])
Example #18
0
def Luv_to_XYZ(Luv,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE Luv* colourspace to *CIE XYZ* colourspace.

    Parameters
    ----------
    Luv : array_like, (3,)
        *CIE Luv* colourspace matrix.
    illuminant : array_like, optional
        Reference *illuminant* chromaticity coordinates.

    Returns
    -------
    ndarray, (3,)
        *CIE XYZ* colourspace matrix.

    Notes
    -----
    -   Input :math:`L^*` is in domain [0, 100].
    -   Input *illuminant* chromaticity coordinates are in domain [0, 1].
    -   Output *CIE XYZ* colourspace matrix is in domain [0, 1].

    References
    ----------
    .. [3]  Lindbloom, B. (2003). Luv to XYZ. Retrieved February 24, 2014,
            from http://brucelindbloom.com/Eqn_Luv_to_XYZ.html

    Examples
    --------
    >>> Luv = np.array([37.9856291, -28.79229446, -1.3558195])
    >>> Luv_to_XYZ(Luv)  # doctest: +ELLIPSIS
    array([ 0.0704953...,  0.1008    ,  0.0955831...])
    """

    L, u, v = np.ravel(Luv)
    Xr, Yr, Zr = np.ravel(xy_to_XYZ(illuminant))

    Y = ((L + 16) / 116) ** 3 if L > CIE_E * CIE_K else L / CIE_K

    a = 1 / 3 * ((52 * L / (u + 13 * L *
                            (4 * Xr / (Xr + 15 * Yr + 3 * Zr)))) - 1)
    b = -5 * Y
    c = -1 / 3.0
    d = Y * (39 * L / (v + 13 * L *
                       (9 * Yr / (Xr + 15 * Yr + 3 * Zr))) - 5)

    X = (d - b) / (a - c)
    Z = X * a + b

    return np.array([X, Y, Z])
Example #19
0
def XYZ_to_Lab(XYZ,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE XYZ* colourspace to *CIE Lab* colourspace.

    Parameters
    ----------
    XYZ : array_like, (3,)
        *CIE XYZ* colourspace matrix.
    illuminant : array_like, optional
        Reference *illuminant* chromaticity coordinates.

    Returns
    -------
    ndarray, (3,)
        *CIE Lab* colourspace matrix.

    Notes
    -----
    -   Input *CIE XYZ* is in domain [0, 1].
    -   Input *illuminant* chromaticity coordinates are in domain [0, 1].
    -   Output *Lightness* :math:`L^*` is in domain [0, 100].

    References
    ----------
    .. [2]  http://www.brucelindbloom.com/Eqn_XYZ_to_Lab.html
            (Last accessed 24 February 2014)

    Examples
    --------
    >>> XYZ_to_Lab(np.array([0.92193107, 1, 1.03744246]))  # doctest: +ELLIPSIS
    array([ 100.        ,   -7.4178784...,  -15.8574210...])
    """

    X, Y, Z = np.ravel(XYZ)
    Xr, Yr, Zr = np.ravel(xy_to_XYZ(illuminant))

    xr = X / Xr
    yr = Y / Yr
    zr = Z / Zr

    fx = xr ** (1 / 3) if xr > CIE_E else (CIE_K * xr + 16) / 116
    fy = yr ** (1 / 3) if yr > CIE_E else (CIE_K * yr + 16) / 116
    fz = zr ** (1 / 3) if zr > CIE_E else (CIE_K * zr + 16) / 116

    L = 116 * fy - 16
    a = 500 * (fx - fy)
    b = 200 * (fy - fz)

    return np.array([L, a, b])
Example #20
0
def XYZ_to_Lab(XYZ,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE XYZ* colourspace to *CIE Lab* colourspace.

    Parameters
    ----------
    XYZ : array_like, (3,)
        *CIE XYZ* colourspace matrix.
    illuminant : array_like, optional
        Reference *illuminant* chromaticity coordinates.

    Returns
    -------
    ndarray, (3,)
        *CIE Lab* colourspace matrix.

    Notes
    -----
    -   Input *CIE XYZ* is in domain [0, 1].
    -   Input *illuminant* chromaticity coordinates are in domain [0, 1].
    -   Output *Lightness* :math:`L^*` is in domain [0, 100].

    References
    ----------
    .. [2]  http://www.brucelindbloom.com/Eqn_XYZ_to_Lab.html
            (Last accessed 24 February 2014)

    Examples
    --------
    >>> XYZ_to_Lab(np.array([0.92193107, 1, 1.03744246]))  # doctest: +ELLIPSIS
    array([ 100.        ,   -7.4178784...,  -15.8574210...])
    """

    X, Y, Z = np.ravel(XYZ)
    Xr, Yr, Zr = np.ravel(xy_to_XYZ(illuminant))

    xr = X / Xr
    yr = Y / Yr
    zr = Z / Zr

    fx = xr**(1 / 3) if xr > CIE_E else (CIE_K * xr + 16) / 116
    fy = yr**(1 / 3) if yr > CIE_E else (CIE_K * yr + 16) / 116
    fz = zr**(1 / 3) if zr > CIE_E else (CIE_K * zr + 16) / 116

    L = 116 * fy - 16
    a = 500 * (fx - fy)
    b = 200 * (fy - fz)

    return np.array([L, a, b])
Example #21
0
def XYZ_to_xyY(XYZ,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE XYZ* tristimulus values to *CIE xyY* colourspace and
    reference *illuminant*.

    Parameters
    ----------
    XYZ : array_like
        *CIE XYZ* tristimulus values.
    illuminant : array_like, optional
        Reference *illuminant* chromaticity coordinates.

    Returns
    -------
    ndarray
        *CIE xyY* colourspace array.

    Notes
    -----
    -   Input *CIE XYZ* tristimulus values are in domain [0, 1].
    -   Output *CIE xyY* colourspace array is in range [0, 1].

    References
    ----------
    .. [2]  Lindbloom, B. (2003). XYZ to xyY. Retrieved February 24, 2014,
            from http://www.brucelindbloom.com/Eqn_XYZ_to_xyY.html

    Examples
    --------
    >>> XYZ = np.array([0.07049534, 0.10080000, 0.09558313])
    >>> XYZ_to_xyY(XYZ)  # doctest: +ELLIPSIS
    array([ 0.2641477...,  0.3777000...,  0.1008    ])
    """

    XYZ = np.asarray(XYZ)
    X, Y, Z = tsplit(XYZ)
    xy_w = np.asarray(illuminant)

    XYZ_n = np.zeros(XYZ.shape)
    XYZ_n[..., 0:2] = xy_w

    xyY = np.where(
        np.all(XYZ == 0, axis=-1)[..., np.newaxis],
        XYZ_n,
        tstack((X / (X + Y + Z), Y / (X + Y + Z), Y)))

    return xyY
Example #22
0
def XYZ_to_xyY(XYZ,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE XYZ* tristimulus values to *CIE xyY* colourspace and
    reference *illuminant*.

    Parameters
    ----------
    XYZ : array_like
        *CIE XYZ* tristimulus values.
    illuminant : array_like, optional
        Reference *illuminant* chromaticity coordinates.

    Returns
    -------
    ndarray
        *CIE xyY* colourspace array.

    Notes
    -----
    -   Input *CIE XYZ* tristimulus values are in domain [0, 1].
    -   Output *CIE xyY* colourspace array is in range [0, 1].

    References
    ----------
    .. [2]  Lindbloom, B. (2003). XYZ to xyY. Retrieved February 24, 2014,
            from http://www.brucelindbloom.com/Eqn_XYZ_to_xyY.html

    Examples
    --------
    >>> XYZ = np.array([0.07049534, 0.10080000, 0.09558313])
    >>> XYZ_to_xyY(XYZ)  # doctest: +ELLIPSIS
    array([ 0.2641477...,  0.3777000...,  0.1008    ])
    """

    XYZ = np.asarray(XYZ)
    X, Y, Z = tsplit(XYZ)
    xy_w = np.asarray(illuminant)

    XYZ_n = np.zeros(XYZ.shape)
    XYZ_n[..., 0:2] = xy_w

    xyY = np.where(
        np.all(XYZ == 0, axis=-1)[..., np.newaxis], XYZ_n,
        tstack((X / (X + Y + Z), Y / (X + Y + Z), Y)))

    return xyY
Example #23
0
def XYZ_to_Luv(XYZ,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE XYZ* colourspace to *CIE Luv* colourspace.

    Parameters
    ----------
    XYZ : array_like, (3,)
        *CIE XYZ* colourspace matrix.
    illuminant : array_like, optional
        Reference *illuminant* chromaticity coordinates.

    Returns
    -------
    ndarray, (3,)
        *CIE Luv* colourspace matrix.

    Notes
    -----
    -   Input *CIE XYZ* colourspace matrix is in domain [0, 1].
    -   Input *illuminant* chromaticity coordinates are in domain [0, 1].
    -   Output :math:`L^*` is in domain [0, 100].

    References
    ----------
    .. [2]  Lindbloom, B. (2003). XYZ to Luv. Retrieved February 24, 2014,
            from http://brucelindbloom.com/Eqn_XYZ_to_Luv.html

    Examples
    --------
    >>> XYZ = np.array([0.07049534, 0.1008, 0.09558313])
    >>> XYZ_to_Luv(XYZ)  # doctest: +ELLIPSIS
    array([ 37.9856291..., -28.7922944...,  -1.3558195...])
    """

    X, Y, Z = np.ravel(XYZ)
    Xr, Yr, Zr = np.ravel(xy_to_XYZ(illuminant))

    yr = Y / Yr

    L = 116 * yr ** (1 / 3) - 16 if yr > CIE_E else CIE_K * yr
    u = (13 * L * ((4 * X / (X + 15 * Y + 3 * Z)) -
                   (4 * Xr / (Xr + 15 * Yr + 3 * Zr))))
    v = (13 * L * ((9 * Y / (X + 15 * Y + 3 * Z)) -
                   (9 * Yr / (Xr + 15 * Yr + 3 * Zr))))

    return np.array([L, u, v])
Example #24
0
def XYZ_to_Luv(XYZ,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE XYZ* colourspace to *CIE Luv* colourspace.

    Parameters
    ----------
    XYZ : array_like, (3,)
        *CIE XYZ* colourspace matrix.
    illuminant : array_like, optional
        Reference *illuminant* chromaticity coordinates.

    Returns
    -------
    ndarray, (3,)
        *CIE Luv* colourspace matrix.

    Notes
    -----
    -   Input *CIE XYZ* colourspace matrix is in domain [0, 1].
    -   Input *illuminant* chromaticity coordinates are in domain [0, 1].
    -   Output :math:`L^*` is in domain [0, 100].

    References
    ----------
    .. [2]  http://brucelindbloom.com/Eqn_XYZ_to_Luv.html
            (Last accessed 24 February 2014)

    Examples
    --------
    >>> XYZ_to_Luv(np.array([0.92193107, 1, 1.03744246]))  # doctest: +ELLIPSIS
    array([ 100.        ,  -20.0430424...,  -19.8167603...])
    """

    X, Y, Z = np.ravel(XYZ)
    Xr, Yr, Zr = np.ravel(xy_to_XYZ(illuminant))

    yr = Y / Yr

    L = 116 * yr ** (1 / 3) - 16 if yr > CIE_E else CIE_K * yr
    u = (13 * L * ((4 * X / (X + 15 * Y + 3 * Z)) -
                   (4 * Xr / (Xr + 15 * Yr + 3 * Zr))))
    v = (13 * L * ((9 * Y / (X + 15 * Y + 3 * Z)) -
                   (9 * Yr / (Xr + 15 * Yr + 3 * Zr))))

    return np.array([L, u, v])
Example #25
0
def Luv_to_uv(Luv,
              illuminant=ILLUMINANTS.get(
                  'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Returns the :math:`uv^p` chromaticity coordinates from given *CIE Luv*
    colourspace array.

    Parameters
    ----------
    Luv : array_like
        *CIE Luv* colourspace array.
    illuminant : array_like, optional
        Reference *illuminant* *xy* chromaticity coordinates or *CIE xyY*
        colourspace array.

    Returns
    -------
    ndarray
        :math:`uv^p` chromaticity coordinates.

    Notes
    -----
    -   Input :math:`L^*` is in domain [0, 100].
    -   Input *illuminant* *xy* chromaticity coordinates or *CIE xyY*
        colourspace array are in domain [0, :math:`\infty`].
    -   Output :math:`uv^p` chromaticity coordinates are in range [0, 1].

    References
    ----------
    .. [4]  Wikipedia. (n.d.). The forward transformation. Retrieved February
            24, 2014, from
            http://en.wikipedia.org/wiki/CIELUV#The_forward_transformation

    Examples
    --------
    >>> Luv = np.array([37.9856291 , -28.80219593,  -1.35800706])
    >>> Luv_to_uv(Luv)  # doctest: +ELLIPSIS
    array([ 0.1508531...,  0.4853297...])
    """

    X, Y, Z = tsplit(Luv_to_XYZ(Luv, illuminant))

    uv = tstack((4 * X / (X + 15 * Y + 3 * Z),
                 9 * Y / (X + 15 * Y + 3 * Z)))

    return uv
Example #26
0
def XYZ_to_UVW(XYZ,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE XYZ* colourspace to *CIE 1964 U\*V\*W\** colourspace.

    Parameters
    ----------
    XYZ : array_like, (3,)
        *CIE XYZ* colourspace matrix.
    illuminant : array_like, optional
        Reference *illuminant* chromaticity coordinates.

    Returns
    -------
    ndarray, (3,)
        *CIE 1964 U\*V\*W\** colourspace matrix.

    Notes
    -----
    -   Input *CIE XYZ* colourspace matrix is in domain [0, 100].
    -   Output *CIE UVW* colourspace matrix is in domain [0, 100].

    Warning
    -------
    The input / output domains of that definition are non standard!

    Examples
    --------
    >>> XYZ = np.array([0.07049534, 0.1008, 0.09558313]) * 100
    >>> XYZ_to_UVW(XYZ)  # doctest: +ELLIPSIS
    array([-28.0483277...,  -0.8805242...,  37.0041149...])
    """

    x, y, Y = np.ravel(XYZ_to_xyY(XYZ, illuminant))
    u, v = np.ravel(UCS_to_uv(XYZ_to_UCS(XYZ)))
    u0, v0 = np.ravel(UCS_to_uv(XYZ_to_UCS(xy_to_XYZ(illuminant))))

    W = 25 * Y ** (1 / 3) - 17
    U = 13 * W * (u - u0)
    V = 13 * W * (v - v0)

    return np.array([U, V, W])
Example #27
0
def XYZ_to_UVW(XYZ,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE XYZ* colourspace to *CIE 1964 U\*V*\W\** colourspace.

    Parameters
    ----------
    XYZ : array_like, (3,)
        *CIE XYZ* colourspace matrix.
    illuminant : array_like, optional
        Reference *illuminant* chromaticity coordinates.

    Returns
    -------
    ndarray, (3,)
        *CIE 1964 U\*V*\W\** colourspace matrix.

    Notes
    -----
    -   Input *CIE XYZ* colourspace matrix is in domain [0, 100].
    -   Output *CIE UVW* colourspace matrix is in domain [0, 100].

    Warning
    -------
    The input / output domains of that definition are non standard!

    Examples
    --------
    >>> XYZ = np.array([11.80583421, 10.34, 5.15089229])
    >>> XYZ_to_UVW(XYZ)  # doctest: +ELLIPSIS
    array([ 24.2543371...,   7.2205484...,  37.4645000...])
    """

    x, y, Y = np.ravel(XYZ_to_xyY(XYZ, illuminant))
    u, v = np.ravel(UCS_to_uv(XYZ_to_UCS(XYZ)))
    u0, v0 = np.ravel(UCS_to_uv(XYZ_to_UCS(xy_to_XYZ(illuminant))))

    W = 25 * Y ** (1 / 3) - 17
    U = 13 * W * (u - u0)
    V = 13 * W * (v - v0)

    return np.array([U, V, W])
Example #28
0
def XYZ_to_UVW(XYZ,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE XYZ* colourspace to *CIE 1964 U\*V*\W\** colourspace.

    Parameters
    ----------
    XYZ : array_like, (3,)
        *CIE XYZ* colourspace matrix.
    illuminant : array_like, optional
        Reference *illuminant* chromaticity coordinates.

    Returns
    -------
    ndarray, (3,)
        *CIE 1964 U\*V*\W\** colourspace matrix.

    Notes
    -----
    -   Input *CIE XYZ* colourspace matrix is in domain [0, 100].
    -   Output *CIE UVW* colourspace matrix is in domain [0, 100].

    Warning
    -------
    The input / output domains of that definition are non standard!

    Examples
    --------
    >>> XYZ = np.array([11.80583421, 10.34, 5.15089229])
    >>> XYZ_to_UVW(XYZ)  # doctest: +ELLIPSIS
    array([ 24.2543371...,   7.2205484...,  37.4645000...])
    """

    x, y, Y = np.ravel(XYZ_to_xyY(XYZ, illuminant))
    u, v = np.ravel(UCS_to_uv(XYZ_to_UCS(XYZ)))
    u0, v0 = np.ravel(UCS_to_uv(XYZ_to_UCS(xy_to_XYZ(illuminant))))

    W = 25 * Y**(1 / 3) - 17
    U = 13 * W * (u - u0)
    V = 13 * W * (v - v0)

    return np.array([U, V, W])
Example #29
0
def XYZ_to_xyY(XYZ,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE XYZ* colourspace to *CIE xyY* colourspace and reference
    *illuminant*.

    Parameters
    ----------
    XYZ : array_like, (3,)
        *CIE XYZ* colourspace matrix.
    illuminant : array_like, optional
        Reference *illuminant* chromaticity coordinates.

    Returns
    -------
    ndarray, (3,)
        *CIE xyY* colourspace matrix.

    Notes
    -----
    -   Input *CIE XYZ* colourspace matrix is in domain [0, 1].
    -   Output *CIE xyY* colourspace matrix is in domain [0, 1].

    References
    ----------
    .. [2]  Lindbloom, B. (2003). XYZ to xyY. Retrieved February 24, 2014,
            from http://www.brucelindbloom.com/Eqn_XYZ_to_xyY.html

    Examples
    --------
    >>> XYZ = np.array([0.07049534, 0.1008, 0.09558313])
    >>> XYZ_to_xyY(XYZ)  # doctest: +ELLIPSIS
    array([ 0.2641477...,  0.3777000...,  0.1008    ])
    """

    X, Y, Z = np.ravel(XYZ)

    if X == 0 and Y == 0 and Z == 0:
        return np.array([illuminant[0], illuminant[1], Y])
    else:
        return np.array([X / (X + Y + Z), Y / (X + Y + Z), Y])
Example #30
0
def CCT_factor(reference_data, XYZ_r):

    xy_w = ILLUMINANTS.get('CIE 1931 2 Degree Standard Observer').get('D65')
    XYZ_w = xy_to_XYZ(xy_w)

    Labs = []
    for vs_colorimetry_data_ in reference_data:
        _name, XYZ, _Lab, _C = vs_colorimetry_data_
        XYZ_a = chromatic_adaptation_VonKries(XYZ,
                                              XYZ_r,
                                              XYZ_w,
                                              transform='CMCCAT2000')

        Lab = XYZ_to_Lab(XYZ_a, illuminant=xy_w)
        Labs.append(Lab)

    G_r = gamut_area(Labs) / D65_GAMUT_AREA
    CCT_f = 1 if G_r > 1 else G_r

    return CCT_f
Example #31
0
def RGB_colourspace_limits(colourspace,
                           illuminant=ILLUMINANTS.get(
                               'CIE 1931 2 Degree Standard Observer').get(
                               'D50')):
    """
    Computes given *RGB* colourspace volume limits in *Lab* colourspace.

    Parameters
    ----------
    colourspace : RGB_Colourspace
        *RGB* colourspace to compute the volume of.
    illuminant : array_like, optional
        *Lab* colourspace *illuminant* chromaticity coordinates.

    Returns
    -------
    ndarray
        *RGB* colourspace volume limits.

    Examples
    --------
    >>> from colour import sRGB_COLOURSPACE as sRGB
    >>> RGB_colourspace_limits(sRGB)  # doctest: +ELLIPSIS
    array([[   0...        ,  100.0000848...],
           [ -79.2197012...,   94.6760011...],
           [-114.7814393...,   96.7261797...]])
    """

    Lab = []
    for combination in list(itertools.product([0, 1], repeat=3)):
        Lab.append(XYZ_to_Lab(RGB_to_XYZ(combination,
                                         colourspace.whitepoint,
                                         illuminant,
                                         colourspace.RGB_to_XYZ_matrix)))
    Lab = np.array(Lab)

    limits = []
    for i in np.arange(3):
        limits.append((np.min(Lab[..., i]), np.max(Lab[..., i])))

    return np.array(limits)
Example #32
0
def RGB_colourspace_limits(
    colourspace,
    illuminant=ILLUMINANTS.get('CIE 1931 2 Degree Standard Observer').get(
        'D50')):
    """
    Computes given *RGB* colourspace volume limits in *Lab* colourspace.

    Parameters
    ----------
    colourspace : RGB_Colourspace
        *RGB* colourspace to compute the volume of.
    illuminant : array_like, optional
        *Lab* colourspace *illuminant* chromaticity coordinates.

    Returns
    -------
    ndarray
        *RGB* colourspace volume limits.

    Examples
    --------
    >>> from colour import sRGB_COLOURSPACE as sRGB
    >>> RGB_colourspace_limits(sRGB)  # doctest: +ELLIPSIS
    array([[   0...        ,  100...        ],
           [ -79.2263741...,   94.6657491...],
           [-114.7846271...,   96.7135199...]])
    """

    Lab = []
    for combination in list(itertools.product([0, 1], repeat=3)):
        Lab.append(
            XYZ_to_Lab(
                RGB_to_XYZ(combination, colourspace.whitepoint, illuminant,
                           colourspace.RGB_to_XYZ_matrix)))
    Lab = np.array(Lab)

    limits = []
    for i in np.arange(3):
        limits.append((np.min(Lab[..., i]), np.max(Lab[..., i])))

    return np.array(limits)
Example #33
0
def XYZ_to_xyY(XYZ,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE XYZ* colourspace to *CIE xyY* colourspace and reference
    *illuminant*.

    Parameters
    ----------
    XYZ : array_like, (3,)
        *CIE XYZ* colourspace matrix.
    illuminant : array_like, optional
        Reference *illuminant* chromaticity coordinates.

    Returns
    -------
    ndarray, (3,)
        *CIE xyY* colourspace matrix.

    Notes
    -----
    -   Input *CIE XYZ* colourspace matrix is in domain [0, 1].
    -   Output *CIE xyY* colourspace matrix is in domain [0, 1].

    References
    ----------
    .. [2]  http://www.brucelindbloom.com/Eqn_XYZ_to_xyY.html
            (Last accessed 24 February 2014)

    Examples
    --------
    >>> XYZ_to_xyY(np.array([0.1180583421, 0.1034, 0.0515089229]))
    array([ 0.4325,  0.3788,  0.1034])
    """

    X, Y, Z = np.ravel(XYZ)

    if X == 0 and Y == 0 and Z == 0:
        return np.array([illuminant[0], illuminant[1], Y])
    else:
        return np.array([X / (X + Y + Z), Y / (X + Y + Z), Y])
Example #34
0
def XYZ_to_xyY(XYZ,
               illuminant=ILLUMINANTS.get(
                   'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Converts from *CIE XYZ* colourspace to *CIE xyY* colourspace and reference
    *illuminant*.

    Parameters
    ----------
    XYZ : array_like, (3,)
        *CIE XYZ* colourspace matrix.
    illuminant : array_like, optional
        Reference *illuminant* chromaticity coordinates.

    Returns
    -------
    ndarray, (3,)
        *CIE xyY* colourspace matrix.

    Notes
    -----
    -   Input *CIE XYZ* colourspace matrix is in domain [0, 1].
    -   Output *CIE xyY* colourspace matrix is in domain [0, 1].

    References
    ----------
    .. [2]  http://www.brucelindbloom.com/Eqn_XYZ_to_xyY.html
            (Last accessed 24 February 2014)

    Examples
    --------
    >>> XYZ_to_xyY(np.array([0.1180583421, 0.1034, 0.0515089229]))
    array([ 0.4325,  0.3788,  0.1034])
    """

    X, Y, Z = np.ravel(XYZ)

    if X == 0 and Y == 0 and Z == 0:
        return np.array([illuminant[0], illuminant[1], Y])
    else:
        return np.array([X / (X + Y + Z), Y / (X + Y + Z), Y])
Example #35
0
def Luv_to_uv(Luv,
              illuminant=ILLUMINANTS.get(
                  'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Returns the :math:`uv^p` chromaticity coordinates from given *CIE Luv*
    colourspace matrix.

    Parameters
    ----------
    Luv : array_like, (3,)
        *CIE Luv* colourspace matrix.
    illuminant : array_like, optional
        Reference *illuminant* chromaticity coordinates.

    Returns
    -------
    tuple
        :math:`uv^p` chromaticity coordinates.

    Notes
    -----
    -   Input :math:`L^*` is in domain [0, 100].
    -   Output :math:`uv^p` chromaticity coordinates are in domain [0, 1].

    References
    ----------
    .. [4]  Wikipedia. (n.d.). The forward transformation. Retrieved February
            24, 2014, from
            http://en.wikipedia.org/wiki/CIELUV#The_forward_transformation

    Examples
    --------
    >>> Luv = np.array([37.9856291, -28.79229446, -1.3558195])
    >>> Luv_to_uv(Luv)  # doctest: +ELLIPSIS
    (0.1508530..., 0.4853297...)
    """

    X, Y, Z = np.ravel(Luv_to_XYZ(Luv, illuminant))

    return 4 * X / (X + 15 * Y + 3 * Z), 9 * Y / (X + 15 * Y + 3 * Z)
Example #36
0
def Luv_to_uv(Luv,
              illuminant=ILLUMINANTS.get(
                  'CIE 1931 2 Degree Standard Observer').get('D50')):
    """
    Returns the *u"v"* chromaticity coordinates from given *CIE Luv*
    colourspace matrix.

    Parameters
    ----------
    Luv : array_like, (3,)
        *CIE Luv* colourspace matrix.
    illuminant : array_like, optional
        Reference *illuminant* chromaticity coordinates.

    Returns
    -------
    tuple
        *u"v"* chromaticity coordinates.

    Notes
    -----
    -   Input :math:`L^*` is in domain [0, 100].
    -   Output *u"v"* chromaticity coordinates are in domain [0, 1].

    References
    ----------
    .. [4]  http://en.wikipedia.org/wiki/CIELUV#The_forward_transformation
            (Last accessed 24 February 2014)

    Examples
    --------
    >>> Luv = np.array([100, -20.04304247, -19.81676035])
    >>> Luv_to_uv(Luv)  # doctest: +ELLIPSIS
    (0.1937414..., 0.4728316...)
    """

    X, Y, Z = np.ravel(Luv_to_XYZ(Luv, illuminant))

    return 4 * X / (X + 15 * Y + 3 * Z), 9 * Y / (X + 15 * Y + 3 * Z)
Example #37
0
def RGB_to_Lab(RGB, colourspace):
    """
    Converts given *RGB* value from given colourspace to *CIE Lab* colourspace.

    Parameters
    ----------
    RGB : array_like
        *RGB* value.
    colourspace : RGB_Colourspace
        *RGB* colourspace.

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

    return XYZ_to_Lab(
        RGB_to_XYZ(
            np.array(RGB), colourspace.whitepoint,
            ILLUMINANTS.get('CIE 1931 2 Degree Standard Observer').get('E'),
            colourspace.to_XYZ, 'Bradford', colourspace.cctf_decoding),
        colourspace.whitepoint)
Example #38
0
def CCT_factor(reference_data, XYZ_r):
    """
    Returns the correlated colour temperature factor penalizing lamps with
    extremely low correlated colour temperatures.

    Parameters
    ----------
    reference_data : VS_ColorimetryData
        Reference colorimetry data.
    XYZ_r : array_like
        *CIE XYZ* tristimulus values for reference.

    Returns
    -------
    numeric
        Correlated colour temperature factor.
    """

    xy_w = ILLUMINANTS.get('CIE 1931 2 Degree Standard Observer').get('D65')
    XYZ_w = xy_to_XYZ(xy_w)

    Labs = []
    for vs_colorimetry_data_ in reference_data:
        _name, XYZ, _Lab, _C = vs_colorimetry_data_
        XYZ_a = chromatic_adaptation_VonKries(XYZ,
                                              XYZ_r,
                                              XYZ_w,
                                              transform='CMCCAT2000')

        Lab = XYZ_to_Lab(XYZ_a, illuminant=xy_w)
        Labs.append(Lab)

    G_r = gamut_area(Labs) / D65_GAMUT_AREA
    CCT_f = 1 if G_r > 1 else G_r

    return CCT_f
Example #39
0
def CCT_factor(reference_data, XYZ_r):
    """
    Returns the correlated colour temperature factor penalizing lamps with
    extremely low correlated colour temperatures.

    Parameters
    ----------
    reference_data : VS_ColorimetryData
        Reference colorimetry data.
    XYZ_r : array_like
        *CIE XYZ* tristimulus values for reference.

    Returns
    -------
    numeric
        Correlated colour temperature factor.
    """

    xy_w = ILLUMINANTS.get('CIE 1931 2 Degree Standard Observer').get('D65')
    XYZ_w = xy_to_XYZ(xy_w)

    Labs = []
    for vs_colorimetry_data_ in reference_data:
        _name, XYZ, _Lab, _C = vs_colorimetry_data_
        XYZ_a = chromatic_adaptation_VonKries(XYZ,
                                              XYZ_r,
                                              XYZ_w,
                                              transform='CMCCAT2000')

        Lab = XYZ_to_Lab(XYZ_a, illuminant=xy_w)
        Labs.append(Lab)

    G_r = gamut_area(Labs) / D65_GAMUT_AREA
    CCT_f = 1 if G_r > 1 else G_r

    return CCT_f
Example #40
0
     [0.29, 0.60],
     [0.15, 0.06]])
"""
*Pal/Secam RGB* colourspace primaries.

PAL_SECAM_RGB_PRIMARIES : ndarray, (3, 2)
"""

PAL_SECAM_RGB_ILLUMINANT = 'D65'
"""
*Pal/Secam RGB* colourspace whitepoint name as illuminant.

PAL_SECAM_RGB_ILLUMINANT : unicode
"""

PAL_SECAM_RGB_WHITEPOINT = ILLUMINANTS.get(
    'CIE 1931 2 Degree Standard Observer').get(PAL_SECAM_RGB_ILLUMINANT)
"""
*Pal/Secam RGB* colourspace whitepoint.

PAL_SECAM_RGB_WHITEPOINT : tuple
"""

PAL_SECAM_RGB_TO_XYZ_MATRIX = normalised_primary_matrix(
    PAL_SECAM_RGB_PRIMARIES, PAL_SECAM_RGB_WHITEPOINT)
"""
*Pal/Secam RGB* colourspace to *CIE XYZ* tristimulus values matrix.

PAL_SECAM_RGB_TO_XYZ_MATRIX : array_like, (3, 3)
"""

XYZ_TO_PAL_SECAM_RGB_MATRIX = np.linalg.inv(PAL_SECAM_RGB_TO_XYZ_MATRIX)
Example #41
0
DCI_P3_P_PRIMARIES : ndarray, (3, 2)
"""

DCI_P3_ILLUMINANT = 'D63'
"""
*DCI-P3* colourspace whitepoint name as illuminant.

DCI_P3_ILLUMINANT : unicode

Notes
-----
*CIE Illuminant D Series* *D63* illuminant is used for *DCI-P3* whitepoint at
48 :math:`cd/m^2`.
"""

DCI_P3_WHITEPOINT = ILLUMINANTS.get(
    'CIE 1931 2 Degree Standard Observer').get(DCI_P3_ILLUMINANT)
"""
*DCI-P3* colourspace whitepoint.

DCI_P3_WHITEPOINT : tuple
"""

DCI_P3_TO_XYZ_MATRIX = normalised_primary_matrix(
    DCI_P3_PRIMARIES,
    DCI_P3_WHITEPOINT)
"""
*DCI-P3* colourspace to *CIE XYZ* tristimulus values matrix.

DCI_P3_TO_XYZ_MATRIX : array_like, (3, 3)
"""
Example #42
0
__all__ = [
    'SMPTE_C_RGB_PRIMARIES', 'SMPTE_C_RGB_WHITEPOINT',
    'SMPTE_C_RGB_TO_XYZ_MATRIX', 'XYZ_TO_SMPTE_C_RGB_MATRIX',
    'SMPTE_C_RGB_TRANSFER_FUNCTION', 'SMPTE_C_RGB_INVERSE_TRANSFER_FUNCTION',
    'SMPTE_C_RGB_COLOURSPACE'
]

SMPTE_C_RGB_PRIMARIES = np.array([[0.630, 0.340], [0.310, 0.595],
                                  [0.155, 0.070]])
"""
*SMPTE-C RGB* colourspace primaries.

SMPTE_C_RGB_PRIMARIES : ndarray, (3, 2)
"""

SMPTE_C_RGB_WHITEPOINT = ILLUMINANTS.get(
    'CIE 1931 2 Degree Standard Observer').get('D65')
"""
*SMPTE-C RGB* colourspace whitepoint.

SMPTE_C_RGB_WHITEPOINT : tuple
"""

SMPTE_C_RGB_TO_XYZ_MATRIX = normalised_primary_matrix(SMPTE_C_RGB_PRIMARIES,
                                                      SMPTE_C_RGB_WHITEPOINT)
"""
*SMPTE-C RGB* colourspace to *CIE XYZ* colourspace matrix.

SMPTE_C_RGB_TO_XYZ_MATRIX : array_like, (3, 3)
"""

XYZ_TO_SMPTE_C_RGB_MATRIX = np.linalg.inv(SMPTE_C_RGB_TO_XYZ_MATRIX)
Example #43
0
def planckian_locus_CIE_1931_chromaticity_diagram_plot(
        illuminants=None,
        **kwargs):
    """
    Plots the planckian locus and given illuminants in
    *CIE 1931 Chromaticity Diagram*.

    Parameters
    ----------
    illuminants : array_like, optional
        Factory illuminants to plot.
    \**kwargs : dict, optional
        Keywords arguments.

    Returns
    -------
    Figure
        Current figure or None.

    Raises
    ------
    KeyError
        If one of the given illuminant is not found in the factory illuminants.

    Examples
    --------
    >>> ils = ['A', 'B', 'C']
    >>> planckian_locus_CIE_1931_chromaticity_diagram_plot(
    ...     ils)  # doctest: +SKIP
    """

    if illuminants is None:
        illuminants = ('A', 'B', 'C')

    cmfs = CMFS.get('CIE 1931 2 Degree Standard Observer')

    settings = {
        'title': ('{0} Illuminants - Planckian Locus\n'
                  'CIE 1931 Chromaticity Diagram - '
                  'CIE 1931 2 Degree Standard Observer').format(
            ', '.join(illuminants))
        if illuminants else
        ('Planckian Locus\nCIE 1931 Chromaticity Diagram - '
         'CIE 1931 2 Degree Standard Observer'),
        'standalone': False}
    settings.update(kwargs)

    CIE_1931_chromaticity_diagram_plot(**settings)

    start, end = 1667, 100000
    xy = np.array([UCS_uv_to_xy(CCT_to_uv(x, 0, method='Robertson 1968'))
                   for x in np.arange(start, end + 250, 250)])

    pylab.plot(xy[..., 0], xy[..., 1], color='black', linewidth=2)

    for i in (1667, 2000, 2500, 3000, 4000, 6000, 10000):
        x0, y0 = UCS_uv_to_xy(CCT_to_uv(i, -0.025, method='Robertson 1968'))
        x1, y1 = UCS_uv_to_xy(CCT_to_uv(i, 0.025, method='Robertson 1968'))
        pylab.plot((x0, x1), (y0, y1), color='black', linewidth=2)
        pylab.annotate('{0}K'.format(i),
                       xy=(x0, y0),
                       xytext=(0, -10),
                       color='black',
                       textcoords='offset points',
                       size='x-small')

    for illuminant in illuminants:
        xy = ILLUMINANTS.get(cmfs.name).get(illuminant)
        if xy is None:
            raise KeyError(
                ('Illuminant "{0}" not found in factory illuminants: '
                 '"{1}".').format(illuminant,
                                  sorted(ILLUMINANTS.get(cmfs.name).keys())))

        pylab.plot(xy[0], xy[1], 'o', color='white', linewidth=2)

        pylab.annotate(illuminant,
                       xy=(xy[0], xy[1]),
                       xytext=(-50, 30),
                       color='black',
                       textcoords='offset points',
                       arrowprops=dict(arrowstyle='->',
                                       connectionstyle='arc3, rad=-0.2'))

    settings.update({
        'x_tighten': True,
        'y_tighten': True,
        'limits': (-0.1, 0.9, -0.1, 0.9),
        'standalone': True})
    settings.update(kwargs)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
Example #44
0
def planckian_locus_CIE_1960_UCS_chromaticity_diagram_plot(
        illuminants=None,
        **kwargs):
    """
    Plots the planckian locus and given illuminants in
    *CIE 1960 UCS Chromaticity Diagram*.

    Parameters
    ----------
    illuminants : array_like, optional
        Factory illuminants to plot.
    \*\*kwargs : \*\*
        Keywords arguments.

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

    Raises
    ------
    KeyError
        If one of the given illuminant is not found in the factory illuminants.

    Examples
    --------
    >>> ils = ['A', 'C', 'E']
    >>> planckian_locus_CIE_1960_UCS_chromaticity_diagram_plot(ils)  # noqa  # doctest: +SKIP
    True
    """

    if illuminants is None:
        illuminants = ('A', 'C', 'E')

    cmfs = CMFS.get('CIE 1931 2 Degree Standard Observer')

    settings = {
        'title': ('{0} Illuminants - Planckian Locus\n'
                  'CIE 1960 UCS Chromaticity Diagram - '
                  'CIE 1931 2 Degree Standard Observer').format(
            ', '.join(illuminants))
        if illuminants else
        ('Planckian Locus\nCIE 1960 UCS Chromaticity Diagram - '
         'CIE 1931 2 Degree Standard Observer'),
        'standalone': False}
    settings.update(kwargs)

    if not CIE_1960_UCS_chromaticity_diagram_plot(**settings):
        return

    xy_to_uv = lambda x: UCS_to_uv(XYZ_to_UCS(xy_to_XYZ(x)))

    start, end = 1667, 100000
    uv = np.array([CCT_to_uv(x, 0, cmfs=cmfs)
                   for x in np.arange(start, end + 250, 250)])

    pylab.plot(uv[:, 0], uv[:, 1], color='black', linewidth=2)

    for i in [1667, 2000, 2500, 3000, 4000, 6000, 10000]:
        u0, v0 = CCT_to_uv(i, -0.05)
        u1, v1 = CCT_to_uv(i, 0.05)
        pylab.plot([u0, u1], [v0, v1], color='black', linewidth=2)
        pylab.annotate('{0}K'.format(i),
                       xy=(u0, v0),
                       xytext=(0, -10),
                       textcoords='offset points',
                       size='x-small')

    for illuminant in illuminants:
        uv = xy_to_uv(ILLUMINANTS.get(cmfs.name).get(illuminant))
        if uv is None:
            raise KeyError(
                ('Illuminant "{0}" not found in factory illuminants: '
                 '"{1}".').format(illuminant,
                                  sorted(ILLUMINANTS.get(cmfs.name).keys())))

        pylab.plot(uv[0], uv[1], 'o', color='white', linewidth=2)

        pylab.annotate(illuminant,
                       xy=(uv[0], uv[1]),
                       xytext=(-50, 30),
                       textcoords='offset points',
                       arrowprops=dict(arrowstyle='->',
                                       connectionstyle='arc3, rad=-0.2'))

    settings.update({'standalone': True})
    settings.update(kwargs)

    return display(**settings)
Example #45
0
__status__ = 'Production'

__all__ = [
    'SMITS1999_PRIMARIES', 'SMITS1999_WHITEPOINT',
    'SMITS1999_XYZ_TO_RGB_MATRIX', 'XYZ_to_RGB_Smits1999',
    'RGB_to_spectral_Smits1999'
]

SMITS1999_PRIMARIES = sRGB_COLOURSPACE.primaries
"""
Current Smits (1999) method implementation colourspace primaries.

SMITS1999_PRIMARIES : ndarray, (3, 2)
"""

SMITS1999_WHITEPOINT = ILLUMINANTS.get(
    'CIE 1931 2 Degree Standard Observer').get('E')
"""
Current Smits (1999) method implementation colourspace whitepoint.

SMITS1999_WHITEPOINT : tuple
"""

SMITS1999_XYZ_TO_RGB_MATRIX = np.linalg.inv(
    normalised_primary_matrix(SMITS1999_PRIMARIES, SMITS1999_WHITEPOINT))
"""
Current Smits (1999) method implementation *RGB* colourspace to
*CIE XYZ* tristimulus values matrix.

SMITS1999_XYZ_TO_RGB_MATRIX : array_like, (3, 3)
"""
Example #46
0
                               0.26586621], [0.10039113, 0.89960887],
                              [0.03621495, 0.00000000]])
"""
*Max RGB* colourspace primaries.

MAX_RGB_PRIMARIES : ndarray, (3, 2)
"""

MAX_RGB_ILLUMINANT = 'D50'
"""
*Max RGB* colourspace whitepoint name as illuminant.

MAX_RGB_ILLUMINANT : unicode
"""

MAX_RGB_WHITEPOINT = ILLUMINANTS.get(
    'CIE 1931 2 Degree Standard Observer').get(MAX_RGB_ILLUMINANT)
"""
*Max RGB* colourspace whitepoint.

MAX_RGB_WHITEPOINT : tuple
"""

MAX_RGB_TO_XYZ_MATRIX = normalised_primary_matrix(MAX_RGB_PRIMARIES,
                                                  MAX_RGB_WHITEPOINT)
"""
*Max RGB* colourspace to *CIE XYZ* tristimulus values matrix.

MAX_RGB_TO_XYZ_MATRIX : array_like, (3, 3)
"""

XYZ_TO_MAX_RGB_MATRIX = np.linalg.inv(MAX_RGB_TO_XYZ_MATRIX)
Example #47
0
     [0.209905660377358, 0.709905660377358],
     [0.140061791967044, 0.080329557157570]])
"""
*ECI RGB v2* colourspace primaries.

ECI_RGB_V2_PRIMARIES : ndarray, (3, 2)
"""

ECI_RGB_V_ILLUMINANT = 'D50'
"""
*ECI RGB v2* colourspace whitepoint name as illuminant.

ECI_RGB_V_ILLUMINANT : unicode
"""

ECI_RGB_V2_WHITEPOINT = ILLUMINANTS.get(
    'CIE 1931 2 Degree Standard Observer').get(ECI_RGB_V_ILLUMINANT)
"""
*ECI RGB v2* colourspace whitepoint.

ECI_RGB_V2_WHITEPOINT : tuple
"""

ECI_RGB_V2_TO_XYZ_MATRIX = normalised_primary_matrix(ECI_RGB_V2_PRIMARIES,
                                                     ECI_RGB_V2_WHITEPOINT)
"""
*ECI RGB v2* colourspace to *CIE XYZ* tristimulus values matrix.

ECI_RGB_V2_TO_XYZ_MATRIX : array_like, (3, 3)
"""

XYZ_TO_ECI_RGB_V2_MATRIX = np.linalg.inv(ECI_RGB_V2_TO_XYZ_MATRIX)
                           (15, 'red', 0.5709, 0.3298,
                            0.1268), (16, 'yellow', 0.4694, 0.4732,
                                      0.6081), (17, 'magenta', 0.4177, 0.2704,
                                                0.2007), (18, 'cyan', 0.2151,
                                                          0.3037, 0.1903),
                           (19, 'white 9.5 (.05 D)', 0.3488, 0.3628,
                            0.9129), (20, 'neutral 8 (.23 D)', 0.3451, 0.3596,
                                      0.5885), (21, 'neutral 6.5 (.44 D)',
                                                0.3446, 0.3590, 0.3595),
                           (22, 'neutral 5 (.70 D)', 0.3438, 0.3589,
                            0.1912), (23, 'neutral 3.5 (1.05 D)', 0.3423,
                                      0.3576, 0.0893), (24, 'black 2 (1.5 D)',
                                                        0.3439, 0.3565,
                                                        0.0320))

BABELCOLOR_AVERAGE_ILLUMINANT = ILLUMINANTS.get(
    'CIE 1931 2 Degree Standard Observer').get('D50')
"""
*BabelColor Average* illuminant.

BABELCOLOR_AVERAGE_ILLUMINANT : tuple
"""

BABELCOLOR_AVERAGE = [
    ColourChecker_Specification(*x) for x in BABELCOLOR_AVERAGE_DATA
]
"""
Average data derived from measurements of 30 *ColourChecker* charts.

BABELCOLOR_AVERAGE : list
"""
Example #49
0
     [0.260000000000000010, 0.699999999999999960],
     [0.109728506787330320, 0.004524886877828055]])
"""
*Ekta Space PS 5* colourspace primaries.

EKTA_SPACE_PS_5_PRIMARIES : ndarray, (3, 2)
"""

EKTA_SPACE_PS_5_V_ILLUMINANT = 'D50'
"""
*Ekta Space PS 5* colourspace whitepoint name as illuminant.

EKTA_SPACE_PS_5_V_ILLUMINANT : unicode
"""

EKTA_SPACE_PS_5_WHITEPOINT = ILLUMINANTS.get(
    'CIE 1931 2 Degree Standard Observer').get(EKTA_SPACE_PS_5_V_ILLUMINANT)
"""
*Ekta Space PS 5* colourspace whitepoint.

EKTA_SPACE_PS_5_WHITEPOINT : tuple
"""

EKTA_SPACE_PS_5_TO_XYZ_MATRIX = normalised_primary_matrix(
    EKTA_SPACE_PS_5_PRIMARIES, EKTA_SPACE_PS_5_WHITEPOINT)
"""
*Ekta Space PS 5* colourspace to *CIE XYZ* tristimulus values matrix.

EKTA_SPACE_PS_5_TO_XYZ_MATRIX : array_like, (3, 3)
"""

XYZ_TO_EKTA_SPACE_PS_5_MATRIX = np.linalg.inv(EKTA_SPACE_PS_5_TO_XYZ_MATRIX)
Example #50
0
def planckian_locus_CIE_1960_UCS_chromaticity_diagram_plot(
        illuminants=None, **kwargs):
    """
    Plots the planckian locus and given illuminants in
    *CIE 1960 UCS Chromaticity Diagram*.

    Parameters
    ----------
    illuminants : array_like, optional
        Factory illuminants to plot.

    Other Parameters
    ----------------
    \**kwargs : dict, optional
        {:func:`boundaries`, :func:`canvas`, :func:`decorate`,
        :func:`display`},
        Please refer to the documentation of the previously listed definitions.
    show_diagram_colours : bool, optional
        {:func:`CIE_1960_UCS_chromaticity_diagram_plot`},
        Whether to display the chromaticity diagram background colours.

    Returns
    -------
    Figure
        Current figure or None.

    Raises
    ------
    KeyError
        If one of the given illuminant is not found in the factory illuminants.

    Examples
    --------
    >>> ils = ['A', 'C', 'E']
    >>> planckian_locus_CIE_1960_UCS_chromaticity_diagram_plot(
    ...     ils)  # doctest: +SKIP
    """

    if illuminants is None:
        illuminants = ('A', 'C', 'E')

    cmfs = CMFS['CIE 1931 2 Degree Standard Observer']

    settings = {
        'title': ('{0} Illuminants - Planckian Locus\n'
                  'CIE 1960 UCS Chromaticity Diagram - '
                  'CIE 1931 2 Degree Standard Observer'
                  ).format(', '.join(illuminants)) if illuminants else
                 ('Planckian Locus\nCIE 1960 UCS Chromaticity Diagram - '
                  'CIE 1931 2 Degree Standard Observer'),
        'standalone':
            False
    }
    settings.update(kwargs)

    CIE_1960_UCS_chromaticity_diagram_plot(**settings)

    start, end = 1667, 100000
    uv = np.array(
        [CCT_to_uv(x, 'Robertson 1968', D_uv=0)
         for x in np.arange(start, end + 250, 250)])  # yapf: disable

    pylab.plot(uv[..., 0], uv[..., 1], color='black', linewidth=2)

    for i in (1667, 2000, 2500, 3000, 4000, 6000, 10000):
        u0, v0 = CCT_to_uv(i, 'Robertson 1968', D_uv=-0.05)
        u1, v1 = CCT_to_uv(i, 'Robertson 1968', D_uv=0.05)
        pylab.plot((u0, u1), (v0, v1), color='black', linewidth=2)
        pylab.annotate(
            '{0}K'.format(i),
            xy=(u0, v0),
            xytext=(0, -10),
            color='black',
            textcoords='offset points',
            size='x-small')

    for illuminant in illuminants:
        xy = ILLUMINANTS.get(cmfs.name).get(illuminant)
        if xy is None:
            raise KeyError(
                ('Illuminant "{0}" not found in factory illuminants: '
                 '"{1}".').format(illuminant,
                                  sorted(ILLUMINANTS[cmfs.name].keys())))

        uv = UCS_to_uv(XYZ_to_UCS(xy_to_XYZ(xy)))

        pylab.plot(uv[0], uv[1], 'o', color='white', linewidth=2)

        pylab.annotate(
            illuminant,
            xy=(uv[0], uv[1]),
            xytext=(-50, 30),
            color='black',
            textcoords='offset points',
            arrowprops=dict(arrowstyle='->', connectionstyle='arc3, rad=-0.2'))

    settings.update({
        'x_tighten': True,
        'y_tighten': True,
        'limits': (-0.1, 0.7, -0.2, 0.6),
        'standalone': True
    })
    settings.update(kwargs)

    boundaries(**settings)
    decorate(**settings)

    return display(**settings)
Example #51
0
def plot_planckian_locus_in_chromaticity_diagram(
        illuminants=None,
        annotate_parameters=None,
        chromaticity_diagram_callable=plot_chromaticity_diagram,
        planckian_locus_callable=plot_planckian_locus,
        method='CIE 1931',
        **kwargs):
    """
    Plots the *Planckian Locus* and given illuminants in the
    *Chromaticity Diagram* according to given method.

    Parameters
    ----------
    illuminants : array_like, optional
        Factory illuminants to plot.
    annotate_parameters : dict or array_like, optional
        Parameters for the :func:`plt.annotate` definition, used to annotate
        the resulting chromaticity coordinates with their respective illuminant
        names if ``annotate`` is set to *True*. ``annotate_parameters`` can be
        either a single dictionary applied to all the arrows with same settings
        or a sequence of dictionaries with different settings for each
        illuminant.
    chromaticity_diagram_callable : callable, optional
        Callable responsible for drawing the *Chromaticity Diagram*.
    planckian_locus_callable : callable, optional
        Callable responsible for drawing the *Planckian Locus*.
    method : unicode, optional
        **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**,
        *Chromaticity Diagram* method.

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

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

    Examples
    --------
    >>> plot_planckian_locus_in_chromaticity_diagram(['A', 'B', 'C'])
    ... # doctest: +ELLIPSIS
    (<Figure size ... with 1 Axes>, \
<matplotlib.axes._subplots.AxesSubplot object at 0x...>)

    .. image:: ../_static/Plotting_\
Plot_Planckian_Locus_In_Chromaticity_Diagram.png
        :align: center
        :alt: plot_planckian_locus_in_chromaticity_diagram
    """

    cmfs = CMFS['CIE 1931 2 Degree Standard Observer']

    if illuminants is None:
        illuminants = ('A', 'B', 'C')

    illuminants = filter_passthrough(ILLUMINANTS.get(cmfs.name), illuminants)

    settings = {'uniform': True}
    settings.update(kwargs)

    _figure, axes = artist(**settings)

    method = method.upper()

    settings = {'axes': axes, 'method': method}
    settings.update(kwargs)
    settings['standalone'] = False

    chromaticity_diagram_callable(**settings)

    planckian_locus_callable(**settings)

    if method == 'CIE 1931':

        def xy_to_ij(xy):
            """
            Converts given *CIE xy* chromaticity coordinates to *ij*
            chromaticity coordinates.
            """

            return xy

        bounding_box = (-0.1, 0.9, -0.1, 0.9)
    elif method == 'CIE 1960 UCS':

        def xy_to_ij(xy):
            """
            Converts given *CIE xy* chromaticity coordinates to *ij*
            chromaticity coordinates.
            """

            return UCS_to_uv(XYZ_to_UCS(xy_to_XYZ(xy)))

        bounding_box = (-0.1, 0.7, -0.2, 0.6)
    else:
        raise ValueError('Invalid method: "{0}", must be one of '
                         '{{\'CIE 1931\', \'CIE 1960 UCS\'}}'.format(method))

    annotate_settings_collection = [{
        'annotate': True,
        'xytext': (-50, 30),
        'textcoords': 'offset points',
        'arrowprops': COLOUR_ARROW_STYLE,
    } for _ in range(len(illuminants))]

    if annotate_parameters is not None:
        if not isinstance(annotate_parameters, dict):
            assert len(annotate_parameters) == len(illuminants), (
                'Multiple annotate parameters defined, but they do not match '
                'the illuminants count!')

        for i, annotate_settings in enumerate(annotate_settings_collection):
            if isinstance(annotate_parameters, dict):
                annotate_settings.update(annotate_parameters)
            else:
                annotate_settings.update(annotate_parameters[i])

    for i, (illuminant, xy) in enumerate(illuminants.items()):
        ij = xy_to_ij(xy)

        axes.plot(ij[0],
                  ij[1],
                  'o',
                  color=COLOUR_STYLE_CONSTANTS.colour.brightest,
                  markeredgecolor=COLOUR_STYLE_CONSTANTS.colour.dark,
                  markersize=(COLOUR_STYLE_CONSTANTS.geometry.short * 6 +
                              COLOUR_STYLE_CONSTANTS.geometry.short * 0.75),
                  markeredgewidth=COLOUR_STYLE_CONSTANTS.geometry.short * 0.75,
                  label=illuminant)

        if annotate_settings_collection[i]['annotate']:
            annotate_settings = annotate_settings_collection[i]
            annotate_settings.pop('annotate')

            axes.annotate(illuminant, xy=ij, **annotate_settings)

    title = (('{0} Illuminants - Planckian Locus\n'
              '{1} Chromaticity Diagram - '
              'CIE 1931 2 Degree Standard Observer').format(
                  ', '.join(illuminants), method) if illuminants else
             ('Planckian Locus\n{0} Chromaticity Diagram - '
              'CIE 1931 2 Degree Standard Observer'.format(method)))

    settings.update({
        'axes': axes,
        'standalone': True,
        'bounding_box': bounding_box,
        'title': title,
    })
    settings.update(kwargs)

    return render(**settings)
Example #52
0
REC_709_PRIMARIES = np.array([[0.6400, 0.3300], [0.3000, 0.6000],
                              [0.1500, 0.0600]])
"""
*Rec. 709* colourspace primaries.

REC_709_PRIMARIES : ndarray, (3, 2)
"""

REC_709_ILLUMINANT = 'D65'
"""
*Rec. 709* colourspace whitepoint name as illuminant.

REC_709_ILLUMINANT : unicode
"""

REC_709_WHITEPOINT = ILLUMINANTS.get(
    'CIE 1931 2 Degree Standard Observer').get(REC_709_ILLUMINANT)
"""
*Rec. 709* colourspace whitepoint.

REC_709_WHITEPOINT : tuple
"""

REC_709_TO_XYZ_MATRIX = np.array([[0.41238656, 0.35759149, 0.18045049],
                                  [0.21263682, 0.71518298, 0.0721802],
                                  [0.01933062, 0.11919716, 0.95037259]])
"""
*Rec. 709* colourspace to *CIE XYZ* tristimulus values matrix.

REC_709_TO_XYZ_MATRIX : array_like, (3, 3)
"""
Example #53
0
     [0.2210, 0.8480],
     [0.0861, -0.1020]])
"""
*ALEXA Wide Gamut RGB* colourspace primaries.

ALEXA_WIDE_GAMUT_RGB_PRIMARIES : ndarray, (3, 2)
"""

ALEXA_WIDE_GAMUT_RGB_ILLUMINANT = 'D65'
"""
*ALEXA Wide Gamut RGB* colourspace whitepoint name as illuminant.

ALEXA_WIDE_GAMUT_RGB_WHITEPOINT : unicode
"""

ALEXA_WIDE_GAMUT_RGB_WHITEPOINT = ILLUMINANTS.get(
    'CIE 1931 2 Degree Standard Observer').get(ALEXA_WIDE_GAMUT_RGB_ILLUMINANT)
"""
*ALEXA Wide Gamut RGB* colourspace whitepoint.

ALEXA_WIDE_GAMUT_RGB_WHITEPOINT : tuple
"""

ALEXA_WIDE_GAMUT_RGB_TO_XYZ_MATRIX = np.array(
    [[0.638008, 0.214704, 0.097744],
     [0.291954, 0.823841, -0.115795],
     [0.002798, -0.067034, 1.153294]])
"""
*ALEXA Wide Gamut RGB* colourspace to *CIE XYZ* tristimulus values matrix.

ALEXA_WIDE_GAMUT_RGB_TO_XYZ_MATRIX : array_like, (3, 3)
"""
Example #54
0
__all__ = [
    'ADOBE_RGB_1998_PRIMARIES', 'ADOBE_RGB_1998_WHITEPOINT',
    'ADOBE_RGB_1998_TO_XYZ_MATRIX', 'XYZ_TO_ADOBE_RGB_1998_MATRIX',
    'ADOBE_RGB_1998_TRANSFER_FUNCTION',
    'ADOBE_RGB_1998_INVERSE_TRANSFER_FUNCTION', 'ADOBE_RGB_1998_COLOURSPACE'
]

ADOBE_RGB_1998_PRIMARIES = np.array([[0.6400, 0.3300], [0.2100, 0.7100],
                                     [0.1500, 0.0600]])
"""
*Adobe RGB 1998* colourspace primaries.

ADOBE_RGB_1998_PRIMARIES : ndarray, (3, 2)
"""

ADOBE_RGB_1998_WHITEPOINT = ILLUMINANTS.get(
    'CIE 1931 2 Degree Standard Observer').get('D65')
"""
*Adobe RGB 1998* colourspace whitepoint.

ADOBE_RGB_1998_WHITEPOINT : tuple
"""

ADOBE_RGB_1998_TO_XYZ_MATRIX = np.array([[0.57666809, 0.18556195, 0.1881985],
                                         [0.29734449, 0.62737611, 0.0752794],
                                         [0.02703132, 0.07069027, 0.99117879]])
"""
*Adobe RGB 1998* colourspace to *CIE XYZ* colourspace matrix.

ADOBE_RGB_1998_TO_XYZ_MATRIX : array_like, (3, 3)

References
Example #55
0
__status__ = 'Production'

__all__ = ['SMITS1999_PRIMARIES',
           'SMITS1999_WHITEPOINT',
           'SMITS1999_XYZ_TO_RGB_MATRIX',
           'XYZ_to_RGB_smits1999',
           'RGB_to_spectral_Smits1999']

SMITS1999_PRIMARIES = sRGB_COLOURSPACE.primaries
"""
Current Smits (1999) method implementation colourspace primaries.

SMITS1999_PRIMARIES : ndarray, (3, 2)
"""

SMITS1999_WHITEPOINT = ILLUMINANTS.get(
    'CIE 1931 2 Degree Standard Observer').get('E')
"""
Current Smits (1999) method implementation colourspace whitepoint.

SMITS1999_WHITEPOINT : tuple
"""

SMITS1999_XYZ_TO_RGB_MATRIX = np.linalg.inv(
    normalised_primary_matrix(SMITS1999_PRIMARIES, SMITS1999_WHITEPOINT))
"""
Current Smits (1999) method implementation *RGB* colourspace to
*CIE XYZ* colourspace matrix.

SMITS1999_XYZ_TO_RGB_MATRIX : array_like, (3, 3)
"""
Example #56
0
AP1 = np.array([[0.71300, 0.29300], [0.16500, 0.83000], [0.12800, 0.04400]])
"""
*ACES Primaries 1* or *AP1* primaries (known as *Rec. 2020+* primaries prior
to *ACES* 1.0 release).

AP1 : ndarray, (3, 2)
"""

ACES_ILLUMINANT = 'D60'
"""
*ACES2065-1* colourspace whitepoint name as illuminant.

ACES_ILLUMINANT : unicode
"""

ACES_WHITEPOINT = ILLUMINANTS.get('CIE 1931 2 Degree Standard Observer').get(
    ACES_ILLUMINANT)
"""
*ACES2065-1* colourspace whitepoint.

ACES_WHITEPOINT : tuple
"""

AP0_TO_XYZ_MATRIX = np.array([[0.9525523959, 0.0000000000, 0.0000936786],
                              [0.3439664498, 0.7281660966, -0.0721325464],
                              [0.0000000000, 0.0000000000, 1.0088251844]])
"""
*ACES Primaries 0* to *CIE XYZ* tristimulus values matrix defined as per [2].
AP0_TO_XYZ_MATRIX : array_like, (3, 3)
"""

XYZ_TO_AP0_MATRIX = np.linalg.inv(AP0_TO_XYZ_MATRIX)