Source code for colour.models.rgb.aces_it

# -*- coding: utf-8 -*-
"""
Academy Color Encoding System - Input Transform
===============================================

Defines the *Academy Color Encoding System* (ACES) *Input Transform* utilities:

-   :func:`colour.sd_to_aces_relative_exposure_values`

See Also
--------
`RGB Colourspaces Jupyter Notebook
<http://nbviewer.jupyter.org/github/colour-science/colour-notebooks/\
blob/master/notebooks/models/rgb.ipynb>`_

References
----------
-   :cite:`Forsythe2018` : Forsythe, A. (2018). Private Discussion with
    Mansencal, T.
-   :cite:`TheAcademyofMotionPictureArtsandSciences2014q` : The Academy of
    Motion Picture Arts and Sciences, Science and Technology Council, & Academy
    Color Encoding System (ACES) Project Subcommittee. (2014). Technical
    Bulletin TB-2014-004 - Informative Notes on SMPTE ST 2065-1 - Academy Color
    Encoding Specification (ACES). Retrieved from
    https://github.com/ampas/aces-dev/tree/master/documents
-   :cite:`TheAcademyofMotionPictureArtsandSciences2014r` : The Academy of
    Motion Picture Arts and Sciences, Science and Technology Council, & Academy
    Color Encoding System (ACES) Project Subcommittee. (2014). Technical
    Bulletin TB-2014-012 - Academy Color Encoding System Version 1.0 Component
    Names. Retrieved from
    https://github.com/ampas/aces-dev/tree/master/documents
-   :cite:`TheAcademyofMotionPictureArtsandSciencese` : The Academy of Motion
    Picture Arts and Sciences, Science and Technology Council, & Academy Color
    Encoding System (ACES) Project Subcommittee. (n.d.). Academy Color Encoding
    System. Retrieved February 24, 2014, from
    http://www.oscars.org/science-technology/council/projects/aces.html
"""

from __future__ import division, unicode_literals

import numpy as np

from colour.colorimetry import ILLUMINANTS_SDS, sd_to_XYZ
from colour.models import XYZ_to_xy
from colour.models.rgb import (ACES_2065_1_COLOURSPACE, ACES_RICD, RGB_to_XYZ,
                               XYZ_to_RGB, normalised_primary_matrix)
from colour.utilities import from_range_1, tsplit

__author__ = 'Colour Developers'
__copyright__ = 'Copyright (C) 2013-2020 - Colour Developers'
__license__ = 'New BSD License - https://opensource.org/licenses/BSD-3-Clause'
__maintainer__ = 'Colour Developers'
__email__ = 'colour-developers@colour-science.org'
__status__ = 'Production'

__all__ = [
    'FLARE_PERCENTAGE', 'S_FLARE_FACTOR', 'sd_to_aces_relative_exposure_values'
]

FLARE_PERCENTAGE = 0.00500
S_FLARE_FACTOR = 0.18000 / (0.18000 + FLARE_PERCENTAGE)


[docs]def sd_to_aces_relative_exposure_values( sd, illuminant=ILLUMINANTS_SDS['D65'], apply_chromatic_adaptation=False, chromatic_adaptation_transform='CAT02'): """ Converts given spectral distribution to *ACES2065-1* colourspace relative exposure values. Parameters ---------- sd : SpectralDistribution Spectral distribution. illuminant : SpectralDistribution, optional *Illuminant* spectral distribution. apply_chromatic_adaptation : bool, optional Whether to apply chromatic adaptation using given transform. chromatic_adaptation_transform : unicode, optional **{'CAT02', 'XYZ Scaling', 'Von Kries', 'Bradford', 'Sharp', 'Fairchild', 'CMCCAT97', 'CMCCAT2000', 'CAT02_BRILL_CAT', 'Bianco', 'Bianco PC'}**, *Chromatic adaptation* transform. Returns ------- ndarray, (3,) *ACES2065-1* colourspace relative exposure values array. Notes ----- +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``XYZ`` | [0, 100] | [0, 1] | +------------+-----------------------+---------------+ - The chromatic adaptation method implemented here is a bit unusual as it involves building a new colourspace based on *ACES2065-1* colourspace primaries but using the whitepoint of the illuminant that the spectral distribution was measured under. References ---------- :cite:`Forsythe2018`, :cite:`TheAcademyofMotionPictureArtsandSciences2014q`, :cite:`TheAcademyofMotionPictureArtsandSciences2014r`, :cite:`TheAcademyofMotionPictureArtsandSciencese` Examples -------- >>> from colour import COLOURCHECKERS_SDS >>> sd = COLOURCHECKERS_SDS['ColorChecker N Ohta']['dark skin'] >>> sd_to_aces_relative_exposure_values(sd) # doctest: +ELLIPSIS array([ 0.1171785..., 0.0866347..., 0.0589707...]) >>> sd_to_aces_relative_exposure_values(sd, ... apply_chromatic_adaptation=True) # doctest: +ELLIPSIS array([ 0.1180766..., 0.0869023..., 0.0589104...]) """ shape = ACES_RICD.shape if sd.shape != ACES_RICD.shape: sd = sd.copy().align(shape) if illuminant.shape != ACES_RICD.shape: illuminant = illuminant.copy().align(shape) s_v = sd.values i_v = illuminant.values r_bar, g_bar, b_bar = tsplit(ACES_RICD.values) def k(x, y): """ Computes the :math:`K_r`, :math:`K_g` or :math:`K_b` scale factors. """ return 1 / np.sum(x * y) k_r = k(i_v, r_bar) k_g = k(i_v, g_bar) k_b = k(i_v, b_bar) E_r = k_r * np.sum(i_v * s_v * r_bar) E_g = k_g * np.sum(i_v * s_v * g_bar) E_b = k_b * np.sum(i_v * s_v * b_bar) E_rgb = np.array([E_r, E_g, E_b]) # Accounting for flare. E_rgb += FLARE_PERCENTAGE E_rgb *= S_FLARE_FACTOR if apply_chromatic_adaptation: xy = XYZ_to_xy(sd_to_XYZ(illuminant) / 100) NPM = normalised_primary_matrix(ACES_2065_1_COLOURSPACE.primaries, xy) XYZ = RGB_to_XYZ(E_rgb, xy, ACES_2065_1_COLOURSPACE.whitepoint, NPM, chromatic_adaptation_transform) E_rgb = XYZ_to_RGB(XYZ, ACES_2065_1_COLOURSPACE.whitepoint, ACES_2065_1_COLOURSPACE.whitepoint, ACES_2065_1_COLOURSPACE.XYZ_to_RGB_matrix) return from_range_1(E_rgb)