Source code for colour_hdri.exposure.dsc

# -*- coding: utf-8 -*-
"""
Digital Still Camera Exposure
=============================

Defines various objects for modeling Digital Still Camera (DSC) exposure:

-   :func:`colour_hdri.focal_plane_exposure`
-   :func:`colour_hdri.arithmetic_mean_focal_plane_exposure`
-   :func:`colour_hdri.saturation_based_speed_focal_plane_exposure`
-   :func:`colour_hdri.exposure_index_values`
-   :func:`colour_hdri.exposure_value_100`
-   :func:`colour_hdri.photometric_exposure_scale_factor_Lagarde2014`

References
----------
-   :cite:`ISO2006` : ISO. (2006). INTERNATIONAL STANDARD ISO12232-2006 -
    Photography - Digital still cameras - Determination of exposure index, ISO
    speed ratings, standard output sensitivity, and recommended exposure index.
-   :cite:`Lagarde2014` : Lagarde, SeĢbastian, & de Rousiers, C. (2014). Moving
    Frostbite to Physically Based Rendering 3.0. Siggraph 2014, 119.
"""

from __future__ import division, unicode_literals

import numpy as np

from colour.utilities import as_float_array
from colour_hdri.exposure import (average_luminance,
                                  luminance_to_exposure_value)

__author__ = 'Colour Developers'
__copyright__ = 'Copyright (C) 2015-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__ = [
    'q_factor', 'focal_plane_exposure', 'arithmetic_mean_focal_plane_exposure',
    'saturation_based_speed_focal_plane_exposure', 'exposure_index_values',
    'exposure_value_100', 'photometric_exposure_scale_factor_Lagarde2014'
]


def q_factor(T=9 / 10, f_v=98 / 100, theta=10):
    """
    Computes the :math:`q` factor modeling the total lens vignetting and
    transmission attenuation.

    Parameters
    ----------
    T : array_like, optional
        Transmission factor of the lens :math:`T`.
    f_v : array_like, optional
        Vignetting factor :math:`f_v`.
    theta : array_like, optional
        Angle of image point off axis :math:`\\theta`.

    Returns
    -------
    ndarray
        :math:`q` factor.

    References
    ----------
    :cite:`ISO2006`

    Examples
    --------
    >>> q_factor()  # doctest: +ELLIPSIS
    0.6515748...
    """

    T = as_float_array(T)
    f_v = as_float_array(f_v)
    theta = as_float_array(theta)

    return np.pi / 4 * T * f_v * np.cos(np.radians(theta)) ** 4


[docs]def focal_plane_exposure(L, A, t, F, i, H_f, T=9 / 10, f_v=98 / 100, theta=10): """ Computes the focal plane exposure :math:`H` in lux-seconds (:math:`lx.s`). Parameters ---------- L : array_like Scene luminance :math:`L`, expressed in :math:`cd/m^2`. A : array_like Lens *F-Number* :math:`A`. t : array_like *Exposure Time* :math:`t`, expressed in seconds. F : array_like Lens focal length :math:`F`, expressed in meters. i : array_like Image distance :math:`i`, expressed in meters. H_f : array_like Focal plane flare exposure :math:`H_f`, expressed in lux-seconds (:math:`lx.s`). T : array_like, optional Transmission factor of the lens :math:`T`. f_v : array_like, optional Vignetting factor :math:`f_v`. theta : array_like, optional Angle of image point off axis :math:`\\theta`. Returns ------- ndarray Focal plane exposure :math:`H` in lux-seconds (:math:`lx.s`). Notes ----- - Focal plane exposure is also named luminous exposure or photometric exposure and is time-integrated illuminance. - Object distance :math:`o`, focal length :math:`F`, and image distance :math:`i` are related by the thin-lens equation: :math:`\\cfrac{1}{f}=\\cfrac{1}{o}+\\cfrac{1}{i}` - This method ignores the *ISO* arithmetic speed :math:`S` and is not concerned with determining an appropriate minimum or maximum exposure level. References ---------- :cite:`ISO2006` Examples -------- >>> focal_plane_exposure(4000, 8, 1 / 250, 50 / 1000, 50 / 1000, 0.0015) ... # doctest: +ELLIPSIS 0.1643937... """ L = as_float_array(L) t = as_float_array(t) A = as_float_array(A) F = as_float_array(F) i = as_float_array(i) H_f = as_float_array(H_f) q = q_factor(T, f_v, theta) H = q * (L * t * F ** 2) / (A ** 2 * i ** 2) + H_f return H
[docs]def arithmetic_mean_focal_plane_exposure(L_a, A, t): """ Computes the arithmetic mean focal plane exposure :math:`H_a` for a camera focused on infinity, :math:`H_f << H`, :math:`T=9/10`, :math:`\\theta =10^{\\circ}` and :math:`f_v=98/100`. Parameters ---------- L_a : array_like Arithmetic scene luminance :math:`L_a`, expressed in :math:`cd/m^2`. A : array_like Lens *F-Number* :math:`A`. t : array_like *Exposure Time* :math:`t`, expressed in seconds. Returns ------- ndarray Focal plane exposure :math:`H_a`. Notes ----- - Focal plane exposure is also named luminous exposure or photometric exposure and is time-integrated illuminance. - Object distance :math:`o`, focal length :math:`F`, and image distance :math:`i` are related by the thin-lens equation: :math:`\\cfrac{1}{f}=\\cfrac{1}{o}+\\cfrac{1}{i}` - This method ignores the *ISO* arithmetic speed :math:`S` and is not concerned with determining an appropriate minimum or maximum exposure level. References ---------- :cite:`ISO2006` Examples -------- >>> arithmetic_mean_focal_plane_exposure(4000, 8, 1 / 250) ... # doctest: +ELLIPSIS 0.1628937... """ H_a = focal_plane_exposure(L_a, A, t, 1, 1, 0, 9 / 10, 98 / 100, 10) return H_a
[docs]def saturation_based_speed_focal_plane_exposure( L, A, t, S, F=50 / 1000, i=1 / (-1 / 5 + 1 / (50 / 1000)), H_f=0, T=9 / 10, f_v=98 / 100, theta=10): """ Computes the Saturation-Based Speed (SBS) focal plane exposure :math:`H_{SBS}` in lux-seconds (:math:`lx.s`). The model implemented by this definition is appropriate to simulate a physical camera in an offline or realtime renderer. Parameters ---------- L : array_like Scene luminance :math:`L`, expressed in :math:`cd/m^2`. A : array_like Lens *F-Number* :math:`A`. t : array_like *Exposure Time* :math:`t`, expressed in seconds. S : array_like *ISO* arithmetic speed :math:`S`. F : array_like Lens focal length :math:`F`, expressed in meters. i : array_like Image distance :math:`i`, expressed in meters. H_f : array_like Focal plane flare exposure :math:`H_f`, expressed in lux-seconds (:math:`lx.s`). T : array_like, optional Transmission factor of the lens :math:`T`. f_v : array_like, optional Vignetting factor :math:`f_v`. theta : array_like, optional Angle of image point off axis :math:`\\theta`. Returns ------- ndarray Saturation-Based Speed focal plane exposure :math:`H_{SBS}` in lux-seconds (:math:`lx.s`). Notes ----- - Focal plane exposure is also named luminous exposure or photometric exposure and is time-integrated illuminance. - Object distance :math:`o`, focal length :math:`F`, and image distance :math:`i` are related by the thin-lens equation: :math:`\\cfrac{1}{f}=\\cfrac{1}{o}+\\cfrac{1}{i}` - The image distance default value is that of an object located at 5m and imaged with a 50mm lens. - The saturation based speed, :math:`S_{sat}`, of an electronic still picture camera is defined as: :math:`S_{sat}=\\cfrac{78}{H_{sat}}` where :math:`H_{sat}` is the minimum focal plane exposure, expressed in lux-seconds (:math:`lx.s`), that produces the maximum valid (not clipped or bloomed) camera output signal. This provides :math:`1/2` "stop" of headroom (41% additional headroom) for specular highlights above the signal level that would be obtained from a theoretical 100% reflectance object in the scene, so that a theoretical 141% reflectance object in the scene would produce a focal plane exposure of :math:`H_{sat}`. - The focal plane exposure :math:`H_{SBS}` computed by this definition is almost equal to that given by scene luminance :math:`L` scaled with the output of :func:`colour_hdri.\ photometric_exposure_scale_factor_Lagarde2014` definition. References ---------- :cite:`ISO2006` Examples -------- >>> saturation_based_speed_focal_plane_exposure( # doctest: +ELLIPSIS ... 4000, 8, 1 / 250, 400, 50 / 1000, 50 / 1000, 0.0015) 0.8430446... """ S = as_float_array(S) H = focal_plane_exposure(L, A, t, F, i, H_f, T, f_v, theta) H_SBS = H * S / 78 return H_SBS
[docs]def exposure_index_values(H_a): """ Computes the exposure index values :math:`I_{EI}` from given focal plane exposure :math:`H_a`. Parameters ---------- H_a : array_like Focal plane exposure :math:`H_a`. Returns ------- ndarray Exposure index values :math:`I_{EI}`. References ---------- :cite:`ISO2006` Examples -------- >>> exposure_index_values(0.1628937086212269) # doctest: +ELLIPSIS 61.3897251... """ return 10 / H_a
[docs]def exposure_value_100(N, t, S): """ Computes the exposure value :math:`EV100` from given relative aperture *F-Number* :math:`N`, *Exposure Time* :math:`t` and *ISO* arithmetic speed :math:`S`. Parameters ---------- N : array_like Relative aperture *F-Number* :math:`N`. t : array_like *Exposure Time* :math:`t`. S : array_like *ISO* arithmetic speed :math:`S`. Returns ------- ndarray Exposure value :math:`EV100`. References ---------- :cite:`ISO2006`, :cite:`Lagarde2014` Notes ----- - The underlying implementation uses the :func:`colour_hdri.luminance_to_exposure_value` and :func:`colour_hdri.average_luminance` definitions with same fixed value for the *reflected light calibration constant* :math:`k` which cancels its scaling effect and produces a value equal to :math:`log_2(\\cfrac{N^2}{t}) - log_2(\\cfrac{S}{100})` as given in :cite:`Lagarde2014`. Examples -------- >>> exposure_value_100(8, 1 / 250, 400) # doctest: +ELLIPSIS 11.9657842... """ return luminance_to_exposure_value(average_luminance(N, t, S), 100)
[docs]def photometric_exposure_scale_factor_Lagarde2014(EV100, T=9 / 10, f_v=98 / 100, theta=10): """ Converts the exposure value :math:`EV100` to photometric exposure scale factor using *Lagarde and de Rousiers (2014)* formulation derived from the *ISO 12232:2006* *Saturation Based Sensitivity* (SBS) recommendation. The model implemented by this definition is appropriate to simulate a physical camera in an offline or realtime renderer. Parameters ---------- T : array_like, optional Exposure value :math:`EV100`. T : array_like, optional Transmission factor of the lens :math:`T`. f_v : array_like, optional Vignetting factor :math:`f_v`. theta : array_like, optional Angle of image point off axis :math:`\\theta`. Returns ------- ndarray Photometric exposure in lux-seconds (:math:`lx.s`). Notes ----- - The saturation based speed, :math:`S_{sat}`, of an electronic still picture camera is defined as: :math:`S_{sat}=\\cfrac{78}{H_{sat}}` where :math:`H_{sat}` is the minimum focal plane exposure, expressed in lux-seconds (:math:`lx.s`), that produces the maximum valid (not clipped or bloomed) camera output signal. This provides :math:`1/2` "stop" of headroom (41% additional headroom) for specular highlights above the signal level that would be obtained from a theoretical 100% reflectance object in the scene, so that a theoretical 141% reflectance object in the scene would produce a focal plane exposure of :math:`H_{sat}`. - Scene luminance :math:`L` scaled with the photometric exposure value computed by this definition is almost equal to that given by the :func:`colour_hdri.saturation_based_speed_focal_plane_exposure` definition. References ---------- :cite:`ISO2006`, :cite:`Lagarde2014` Examples -------- >>> EV100 = exposure_value_100(8, 1 / 250, 400) >>> H = photometric_exposure_scale_factor_Lagarde2014(EV100) >>> print(H) # doctest: +ELLIPSIS 0.0002088... >>> H * 4000 # doctest: +ELLIPSIS 0.8353523... """ q = q_factor(T, f_v, theta) return 1 / (78 / (100 * q) * 2 ** EV100)