Source code for colour_hdri.exposure.common

"""
Exposure Value Computation
==========================

Defines the exposure value computation objects:

-   :func:`colour_hdri.average_luminance`
-   :func:`colour_hdri.average_illuminance`
-   :func:`colour_hdri.luminance_to_exposure_value`
-   :func:`colour_hdri.illuminance_to_exposure_value`
-   :func:`colour_hdri.adjust_exposure`

References
----------
-   :cite:`Wikipediabj` : Wikipedia. (n.d.). EV as a measure of luminance and
    illuminance. Retrieved November 14, 2015, from
    https://en.wikipedia.org/wiki/Exposure_value#\
EV_as_a_measure_of_luminance_and_illuminance
"""

from __future__ import annotations

import numpy as np
from colour.hints import ArrayLike, NDArrayFloat
from colour.utilities import as_float, as_float_array

__author__ = "Colour Developers"
__copyright__ = "Copyright 2015 Colour Developers"
__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause"
__maintainer__ = "Colour Developers"
__email__ = "colour-developers@colour-science.org"
__status__ = "Production"

__all__ = [
    "average_luminance",
    "average_illuminance",
    "luminance_to_exposure_value",
    "illuminance_to_exposure_value",
    "adjust_exposure",
]


[docs] def average_luminance( N: ArrayLike, t: ArrayLike, S: ArrayLike, k: ArrayLike = 12.5, ) -> NDArrayFloat: """ Compute the average luminance :math:`L` in :math:`cd\\cdot m^{-2}` from given relative aperture *F-Number* :math:`N`, *Exposure Time* :math:`t`, *ISO* arithmetic speed :math:`S` and *reflected light calibration constant* :math:`k`. Parameters ---------- N Relative aperture *F-Number* :math:`N`. t *Exposure Time* :math:`t`. S *ISO* arithmetic speed :math:`S`. k *Reflected light calibration constant* :math:`k`. *ISO 2720:1974* recommends a range for :math:`k` of 10.6 to 13.4 with luminance in :math:`cd\\cdot m^{-2}`. Two values for :math:`k` are in common use: 12.5 (Canon, Nikon, and Sekonic) and 14 (Minolta, Kenko, and Pentax). Returns ------- :class:`numpy.ndarray` Average luminance :math:`L` in :math:`cd\\cdot m^{-2}`. References ---------- :cite:`Wikipediabj` Examples -------- >>> average_luminance(8, 1, 100) 8.0 """ N = as_float_array(N) t = as_float_array(t) S = as_float_array(S) k = as_float_array(k) L = N**2 / t / S * k return as_float(L)
[docs] def average_illuminance( N: ArrayLike, t: ArrayLike, S: ArrayLike, c: ArrayLike = 250, ) -> NDArrayFloat: """ Compute the average illuminance :math:`E` in :math:`Lux` from given relative aperture *F-Number* :math:`N`, *Exposure Time* :math:`t`, *ISO* arithmetic speed :math:`S` and *incident light calibration constant* :math:`c`. Parameters ---------- N Relative aperture *F-Number* :math:`N`. t *Exposure Time* :math:`t`. S *ISO* arithmetic speed :math:`S`. c *Incident light calibration constant* :math:`c`. With a flat receptor, *ISO 2720:1974* recommends a range for :math:`c`. of 240 to 400 with illuminance in :math:`Lux`; a value of 250 is commonly used. With a hemispherical receptor, *ISO 2720:1974* recommends a range for :math:`c` of 320 to 540 with illuminance in :math:`Lux`; in practice, values typically are between 320 (Minolta) and 340 (Sekonic). Returns ------- :class:`numpy.ndarray` Average illuminance :math:`E` in :math:`Lux`. References ---------- :cite:`Wikipediabj` Examples -------- >>> average_illuminance(8, 1, 100) 160.0 """ N = as_float_array(N) t = as_float_array(t) S = as_float_array(S) c = as_float_array(c) E = N**2 / t / S * c return as_float(E)
[docs] def luminance_to_exposure_value( L: ArrayLike, S: ArrayLike, k: ArrayLike = 12.5, ) -> NDArrayFloat: """ Compute the exposure value :math:`EV` from given scene luminance :math:`L` in :math:`cd\\cdot m^{-2}`, *ISO* arithmetic speed :math:`S` and *reflected light calibration constant* :math:`k`. Parameters ---------- L Scene luminance :math:`L` in :math:`cd\\cdot m^{-2}`. S *ISO* arithmetic speed :math:`S`. k *Reflected light calibration constant* :math:`k`. *ISO 2720:1974* recommends a range for :math:`k` of 10.6 to 13.4 with luminance in :math:`cd\\cdot m^{-2}`. Two values for :math:`k` are in common use: 12.5 (Canon, Nikon, and Sekonic) and 14 (Minolta, Kenko, and Pentax). Returns ------- :class:`numpy.ndarray` Exposure value :math:`EV`. Notes ----- - The exposure value :math:`EV` indicates a combination of camera settings rather than the focal plane exposure, i.e. luminous exposure, photometric exposure, :math:`H`. The focal plane exposure is time-integrated illuminance. References ---------- :cite:`Wikipediabj` Examples -------- >>> luminance_to_exposure_value(0.125, 100) 0.0 """ L = as_float_array(L) S = as_float_array(S) k = as_float_array(k) EV = np.log2(L * S / k) return as_float(EV)
[docs] def illuminance_to_exposure_value( E: ArrayLike, S: ArrayLike, c: ArrayLike = 250, ) -> NDArrayFloat: """ Compute the exposure value :math:`EV` from given scene illuminance :math:`E` in :math:`Lux`, *ISO* arithmetic speed :math:`S` and *incident light calibration constant* :math:`c`. Parameters ---------- E Scene illuminance :math:`E` in :math:`Lux`. S *ISO* arithmetic speed :math:`S`. c *Incident light calibration constant* :math:`c`. With a flat receptor, *ISO 2720:1974* recommends a range for :math:`c`. of 240 to 400 with illuminance in :math:`Lux`; a value of 250 is commonly used. With a hemispherical receptor, *ISO 2720:1974* recommends a range for :math:`c` of 320 to 540 with illuminance in :math:`Lux`; in practice, values typically are between 320 (Minolta) and 340 (Sekonic). Returns ------- :class:`numpy.ndarray` Exposure value :math:`EV`. Notes ----- - The exposure value :math:`EV` indicates a combination of camera settings rather than the focal plane exposure, i.e. luminous exposure, photometric exposure, :math:`H`. The focal plane exposure is time-integrated illuminance. References ---------- :cite:`Wikipediabj` Examples -------- >>> illuminance_to_exposure_value(2.5, 100) 0.0 """ E = as_float_array(E) S = as_float_array(S) c = as_float_array(c) EV = np.log2(E * S / c) return as_float(EV)
[docs] def adjust_exposure(a: ArrayLike, EV: ArrayLike) -> NDArrayFloat: """ Adjust given array exposure using given :math:`EV` exposure value. Parameters ---------- a Array to adjust the exposure. EV Exposure adjustment value. Returns ------- :class:`numpy.ndarray` Exposure adjusted array. Examples -------- >>> adjust_exposure(np.array([0.25, 0.5, 0.75, 1]), 1) array([ 0.5, 1. , 1.5, 2. ]) """ a = as_float_array(a) EV = as_float_array(EV) return as_float(a * pow(2, EV))