Example #1
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
        Wavelength :math:`\lambda` in nm.

    Returns
    -------
    ndarray, (3,)
        *CIE 1964 10 Degree Standard Observer* spectral tristimulus values.

    Raises
    ------
    KeyError
        If wavelength :math:`\lambda` is not available in the colour matching
        functions.

    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 & Stiles**,
            *Color Science - Concepts and Methods Data and Formulae -
            Second Edition*,
            Wiley Classics Library Edition, published 2000,
            ISBN-10: 0-471-39918-3,
            page  141.

    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')
    r_bar, g_bar, b_bar = cmfs.r_bar.get(wavelength), cmfs.g_bar.get(
        wavelength), cmfs.b_bar.get(wavelength)
    if None in (r_bar, g_bar, b_bar):
        raise KeyError(('"{0} nm" wavelength not available in "{1}" colour '
                        'matching functions with "{2}" shape!').format(
                            wavelength, cmfs.name, cmfs.shape))

    x_bar = 0.341080 * r_bar + 0.189145 * g_bar + 0.387529 * b_bar
    y_bar = 0.139058 * r_bar + 0.837460 * g_bar + 0.073316 * b_bar
    z_bar = 0.000000 * r_bar + 0.039553 * g_bar + 2.026200 * b_bar

    return np.array([x_bar, y_bar, z_bar])
Example #2
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
        Wavelength :math:`\lambda` in nm.

    Returns
    -------
    ndarray, (3,)
        *CIE 1964 10 Degree Standard Observer* spectral tristimulus values.

    Raises
    ------
    KeyError
        If wavelength :math:`\lambda` is not available in the colour matching
        functions.

    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 & Stiles**,
            *Color Science - Concepts and Methods Data and Formulae -
            Second Edition*,
            Wiley Classics Library Edition, published 2000,
            ISBN-10: 0-471-39918-3,
            page  141.

    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')
    r_bar, g_bar, b_bar = cmfs.r_bar.get(wavelength), cmfs.g_bar.get(
        wavelength), cmfs.b_bar.get(wavelength)
    if None in (r_bar, g_bar, b_bar):
        raise KeyError(('"{0} nm" wavelength not available in "{1}" colour '
                        'matching functions with "{2}" shape!').format(
            wavelength, cmfs.name, cmfs.shape))

    x_bar = 0.341080 * r_bar + 0.189145 * g_bar + 0.387529 * b_bar
    y_bar = 0.139058 * r_bar + 0.837460 * g_bar + 0.073316 * b_bar
    z_bar = 0.000000 * r_bar + 0.039553 * g_bar + 2.026200 * b_bar

    return np.array([x_bar, y_bar, z_bar])
Example #3
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
        Wavelength :math:`\lambda` in nm.

    Returns
    -------
    ndarray, (3,)
        *Stockman & Sharpe 10 Degree Cone Fundamentals* spectral tristimulus
        values.

    Raises
    ------
    KeyError
        If wavelength :math:`\lambda` is not available in the colour matching
        functions.

    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')
    r_bar, g_bar, z_bar = cmfs.r_bar.get(wavelength), cmfs.g_bar.get(
        wavelength), cmfs.b_bar.get(wavelength)
    if None in (r_bar, g_bar, z_bar):
        raise KeyError(('"{0} nm" wavelength not available in "{1}" colour '
                        'matching functions with "{2}" shape!').format(
            wavelength, cmfs.name, cmfs.shape))

    l_bar = 0.192325269 * r_bar + 0.749548882 * g_bar + 0.0675726702 * z_bar
    g_bar = 0.0192290085 * r_bar + 0.940908496 * g_bar + 0.113830196 * z_bar
    z_bar = (0.0105107859 * g_bar + 0.991427669 * z_bar
             if wavelength <= 505 else 0)

    return np.array([l_bar, g_bar, z_bar])
Example #4
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
        Wavelength :math:`\lambda` in nm.

    Returns
    -------
    ndarray, (3,)
        *Stockman & Sharpe 10 Degree Cone Fundamentals* spectral tristimulus
        values.

    Raises
    ------
    KeyError
        If wavelength :math:`\lambda` is not available in the colour matching
        functions.

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

    References
    ----------
    .. [3]  `CIE 170-1:2006 Fundamental Chromaticity Diagram with Physiological
            Axes - Part 1 <http://div1.cie.co.at/?i_ca_id=551&pubid=48>`_,
            ISBN-13: 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')
    r_bar, g_bar, z_bar = cmfs.r_bar.get(wavelength), cmfs.g_bar.get(
        wavelength), cmfs.b_bar.get(wavelength)
    if None in (r_bar, g_bar, z_bar):
        raise KeyError(('"{0} nm" wavelength not available in "{1}" colour '
                        'matching functions with "{2}" shape!').format(
                            wavelength, cmfs.name, cmfs.shape))

    l_bar = 0.192325269 * r_bar + 0.749548882 * g_bar + 0.0675726702 * z_bar
    g_bar = 0.0192290085 * r_bar + 0.940908496 * g_bar + 0.113830196 * z_bar
    z_bar = (0.0105107859 * g_bar +
             0.991427669 * z_bar if wavelength <= 505 else 0)

    return np.array([l_bar, g_bar, z_bar])
Example #5
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
Example #6
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
Example #7
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
Example #8
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
Example #9
0
def RGB_2_degree_cmfs_to_XYZ_2_degree_cmfs(wavelength):
    """
    Converts *Wright & Guild 1931 2 Degree RGB CMFs* colour matching functions
    into the *CIE 1931 2 Degree Standard Observer* colour matching functions.

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

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

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

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

    References
    ----------
    .. [1]  Wyszecki, G., & Stiles, W. S. (2000). Table 1(3.3.3). In Color
            Science: Concepts and Methods, Quantitative Data and Formulae
            (pp. 138–139). Wiley. ISBN:978-0471399186

    Examples
    --------
    >>> RGB_2_degree_cmfs_to_XYZ_2_degree_cmfs(700)  # doctest: +ELLIPSIS
    array([ 0.0113577...,  0.004102  ,  0.        ])
    """

    cmfs = RGB_CMFS.get('Wright & Guild 1931 2 Degree RGB CMFs')

    rgb_bar = cmfs.get(wavelength)

    rgb = rgb_bar / np.sum(rgb_bar)

    M1 = np.array([[0.49000, 0.31000, 0.20000],
                   [0.17697, 0.81240, 0.01063],
                   [0.00000, 0.01000, 0.99000]])

    M2 = np.array([[0.66697, 1.13240, 1.20063],
                   [0.66697, 1.13240, 1.20063],
                   [0.66697, 1.13240, 1.20063]])

    xyz = dot_vector(M1, rgb)
    xyz /= dot_vector(M2, rgb)

    x, y, z = xyz[..., 0], xyz[..., 1], xyz[..., 2]

    V = PHOTOPIC_LEFS.get('CIE 1924 Photopic Standard Observer').clone()
    V.align(cmfs.shape)
    L = V.get(wavelength)

    x_bar = x / y * L
    y_bar = L
    z_bar = z / y * L

    xyz_bar = tstack((x_bar, y_bar, z_bar))

    return xyz_bar
Example #10
0
def RGB_2_degree_cmfs_to_XYZ_2_degree_cmfs(wavelength):
    """
    Converts *Wright & Guild 1931 2 Degree RGB CMFs* colour matching functions
    into the *CIE 1931 2 Degree Standard Observer* colour matching functions.

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

    Returns
    -------
    ndarray, (3,)
        *CIE 1931 2 Degree Standard Observer* spectral tristimulus values.

    Raises
    ------
    KeyError
        If wavelength :math:`\lambda` is not available in the colour matching
        functions.

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

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

    References
    ----------
    .. [1]  Wyszecki, G., & Stiles, W. S. (2000). Table 1(3.3.3). In Color
            Science: Concepts and Methods, Quantitative Data and Formulae
            (pp. 138–139). Wiley. ISBN:978-0471399186

    Examples
    --------
    >>> RGB_2_degree_cmfs_to_XYZ_2_degree_cmfs(700)  # doctest: +ELLIPSIS
    array([ 0.0113577...,  0.004102  ,  0.        ])
    """

    cmfs = RGB_CMFS.get('Wright & Guild 1931 2 Degree RGB CMFs')
    r_bar, g_bar, b_bar = cmfs.r_bar.get(wavelength), cmfs.g_bar.get(
        wavelength), cmfs.b_bar.get(wavelength)
    if None in (r_bar, g_bar, b_bar):
        raise KeyError(('"{0} nm" wavelength not available in "{1}" colour '
                        'matching functions with "{2}" shape!').format(
            wavelength, cmfs.name, cmfs.shape))

    r = r_bar / (r_bar + g_bar + b_bar)
    g = g_bar / (r_bar + g_bar + b_bar)
    b = b_bar / (r_bar + g_bar + b_bar)

    x = ((0.49000 * r + 0.31000 * g + 0.20000 * b) /
         (0.66697 * r + 1.13240 * g + 1.20063 * b))
    y = ((0.17697 * r + 0.81240 * g + 0.01063 * b) /
         (0.66697 * r + 1.13240 * g + 1.20063 * b))
    z = ((0.00000 * r + 0.01000 * g + 0.99000 * b) /
         (0.66697 * r + 1.13240 * g + 1.20063 * b))

    V = PHOTOPIC_LEFS.get('CIE 1924 Photopic Standard Observer').clone()
    V.align(cmfs.shape)
    L = V.get(wavelength)

    x_bar = x / y * L
    y_bar = L
    z_bar = z / y * L

    return np.array([x_bar, y_bar, z_bar])
Example #11
0
def RGB_2_degree_cmfs_to_XYZ_2_degree_cmfs(wavelength):
    """
    Converts *Wright & Guild 1931 2 Degree RGB CMFs* colour matching functions
    into the *CIE 1931 2 Degree Standard Observer* colour matching functions.

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

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

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

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

    References
    ----------
    .. [1]  Wyszecki, G., & Stiles, W. S. (2000). Table 1(3.3.3). In Color
            Science: Concepts and Methods, Quantitative Data and Formulae
            (pp. 138–139). Wiley. ISBN:978-0471399186

    Examples
    --------
    >>> RGB_2_degree_cmfs_to_XYZ_2_degree_cmfs(700)  # doctest: +ELLIPSIS
    array([ 0.0113577...,  0.004102  ,  0.        ])
    """

    cmfs = RGB_CMFS.get('Wright & Guild 1931 2 Degree RGB CMFs')

    rgb_bar = cmfs.get(wavelength)

    rgb = rgb_bar / np.sum(rgb_bar)

    M1 = np.array([[0.49000, 0.31000, 0.20000], [0.17697, 0.81240, 0.01063],
                   [0.00000, 0.01000, 0.99000]])

    M2 = np.array([[0.66697, 1.13240, 1.20063], [0.66697, 1.13240, 1.20063],
                   [0.66697, 1.13240, 1.20063]])

    xyz = dot_vector(M1, rgb)
    xyz /= dot_vector(M2, rgb)

    x, y, z = xyz[..., 0], xyz[..., 1], xyz[..., 2]

    V = PHOTOPIC_LEFS.get('CIE 1924 Photopic Standard Observer').clone()
    V.align(cmfs.shape)
    L = V.get(wavelength)

    x_bar = x / y * L
    y_bar = L
    z_bar = z / y * L

    xyz_bar = tstack((x_bar, y_bar, z_bar))

    return xyz_bar
Example #12
0
def RGB_2_degree_cmfs_to_XYZ_2_degree_cmfs(wavelength):
    """
    Converts *Wright & Guild 1931 2 Degree RGB CMFs* colour matching functions
    into the *CIE 1931 2 Degree Standard Observer* colour matching functions.

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

    Returns
    -------
    ndarray, (3,)
        *CIE 1931 2 Degree Standard Observer* spectral tristimulus values.

    Raises
    ------
    KeyError
        If wavelength :math:`\lambda` is not available in the colour matching
        functions.

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

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

    References
    ----------
    .. [1]  **Wyszecki & Stiles**,
            *Color Science - Concepts and Methods Data and Formulae -
            Second Edition*,
            Wiley Classics Library Edition, published 2000,
            ISBN-10: 0-471-39918-3,
            pages 138, 139.

    Examples
    --------
    >>> RGB_2_degree_cmfs_to_XYZ_2_degree_cmfs(700)  # doctest: +ELLIPSIS
    array([ 0.0113577...,  0.004102  ,  0.        ])
    """

    cmfs = RGB_CMFS.get('Wright & Guild 1931 2 Degree RGB CMFs')
    r_bar, g_bar, b_bar = cmfs.r_bar.get(wavelength), cmfs.g_bar.get(
        wavelength), cmfs.b_bar.get(wavelength)
    if None in (r_bar, g_bar, b_bar):
        raise KeyError(('"{0} nm" wavelength not available in "{1}" colour '
                        'matching functions with "{2}" shape!').format(
                            wavelength, cmfs.name, cmfs.shape))

    r = r_bar / (r_bar + g_bar + b_bar)
    g = g_bar / (r_bar + g_bar + b_bar)
    b = b_bar / (r_bar + g_bar + b_bar)

    x = ((0.49000 * r + 0.31000 * g + 0.20000 * b) /
         (0.66697 * r + 1.13240 * g + 1.20063 * b))
    y = ((0.17697 * r + 0.81240 * g + 0.01063 * b) /
         (0.66697 * r + 1.13240 * g + 1.20063 * b))
    z = ((0.00000 * r + 0.01000 * g + 0.99000 * b) /
         (0.66697 * r + 1.13240 * g + 1.20063 * b))

    V = PHOTOPIC_LEFS.get('CIE 1924 Photopic Standard Observer').clone()
    V.align(cmfs.shape)
    L = V.get(wavelength)

    x_bar = x / y * L
    y_bar = L
    z_bar = z / y * L

    return np.array([x_bar, y_bar, z_bar])