Skip to content

Commit

Permalink
Merge pull request #600 from njwardhan/feature/LUT-Improvements-GSoC
Browse files Browse the repository at this point in the history
PR: Add "colour.models.rgb.transfer_functions.log" module.
  • Loading branch information
KelSolaar committed Jun 16, 2020
2 parents 14bc07e + 9f5722d commit d79d7cd
Show file tree
Hide file tree
Showing 4 changed files with 360 additions and 12 deletions.
28 changes: 16 additions & 12 deletions colour/models/rgb/transfer_functions/__init__.py
Expand Up @@ -39,6 +39,7 @@
BT2100_HLG_OOTF_METHODS, ootf_HLG_BT2100, BT2100_HLG_OOTF_INVERSE_METHODS,
ootf_inverse_HLG_BT2100)
from .linear import linear_function
from .log import log_encoding_Log2, log_decoding_Log2
from .panalog import log_encoding_Panalog, log_decoding_Panalog
from .panasonic_vlog import log_encoding_VLog, log_decoding_VLog
from .fujifilm_flog import log_encoding_FLog, log_decoding_FLog
Expand Down Expand Up @@ -93,6 +94,7 @@
'BT2100_HLG_OOTF_INVERSE_METHODS', 'ootf_inverse_HLG_BT2100'
]
__all__ += ['linear_function']
__all__ += ['log_encoding_Log2', 'log_decoding_Log2']
__all__ += ['log_encoding_Panalog', 'log_decoding_Panalog']
__all__ += ['log_encoding_VLog', 'log_decoding_VLog']
__all__ += ['log_encoding_FLog', 'log_decoding_FLog']
Expand Down Expand Up @@ -130,6 +132,7 @@
'ERIMM RGB': log_encoding_ERIMMRGB,
'F-Log': log_encoding_FLog,
'Filmic Pro 6': log_encoding_FilmicPro6,
'Log2': log_encoding_Log2,
'Log3G10': log_encoding_Log3G10,
'Log3G12': log_encoding_Log3G12,
'Panalog': log_encoding_Panalog,
Expand All @@ -150,9 +153,9 @@
LOG_ENCODINGS : CaseInsensitiveMapping
**{'ACEScc', 'ACEScct', 'ACESproxy', 'ALEXA Log C', 'Canon Log 2',
'Canon Log 3', 'Canon Log', 'Cineon', 'D-Log', 'ERIMM RGB', 'F-Log',
'Filmic Pro 6', 'Log3G10', 'Log3G12', 'Panalog', 'PLog', 'Protune',
'REDLog', 'REDLogFilm', 'S-Log', 'S-Log2', 'S-Log3', 'T-Log', 'V-Log',
'ViperLog'}**
'Filmic Pro 6', 'Log2', 'Log3G10', 'Log3G12', 'Panalog', 'PLog',
'Protune', 'REDLog', 'REDLogFilm', 'S-Log', 'S-Log2', 'S-Log3',
'T-Log', 'V-Log', 'ViperLog'}**
"""


Expand All @@ -168,9 +171,9 @@ def log_encoding(value, function='Cineon', **kwargs):
function : unicode, optional
**{'ACEScc', 'ACEScct', 'ACESproxy', 'ALEXA Log C', 'Canon Log 2',
'Canon Log 3', 'Canon Log', 'Cineon', 'D-Log', 'ERIMM RGB', 'F-Log',
'Filmic Pro 6', 'Log3G10', 'Log3G12', 'Panalog', 'PLog', 'Protune',
'REDLog', 'REDLogFilm', 'S-Log', 'S-Log2', 'S-Log3', 'T-Log',
'V-Log', 'ViperLog'}**,
'Filmic Pro 6', 'Log2', 'Log3G10', 'Log3G12', 'Panalog', 'PLog',
'Protune', 'REDLog', 'REDLogFilm', 'S-Log', 'S-Log2', 'S-Log3',
'T-Log', 'V-Log', 'ViperLog'}**,
Computation function.
Other Parameters
Expand Down Expand Up @@ -274,6 +277,7 @@ def log_encoding(value, function='Cineon', **kwargs):
'ERIMM RGB': log_decoding_ERIMMRGB,
'F-Log': log_decoding_FLog,
'Filmic Pro 6': log_decoding_FilmicPro6,
'Log2': log_decoding_Log2,
'Log3G10': log_decoding_Log3G10,
'Log3G12': log_decoding_Log3G12,
'Panalog': log_decoding_Panalog,
Expand All @@ -294,9 +298,9 @@ def log_encoding(value, function='Cineon', **kwargs):
LOG_DECODINGS : CaseInsensitiveMapping
**{'ACEScc', 'ACEScct', 'ACESproxy', 'ALEXA Log C', 'Canon Log 2',
'Canon Log 3', 'Canon Log', 'Cineon', 'D-Log', 'ERIMM RGB', 'F-Log',
'Filmic Pro 6', 'Log3G10', 'Log3G12', 'Panalog', 'PLog', 'Protune',
'REDLog', 'REDLogFilm', 'S-Log', 'S-Log2', 'S-Log3', 'T-Log', 'V-Log',
'ViperLog'}**
'Filmic Pro 6', 'Log2', 'Log3G10', 'Log3G12', 'Panalog', 'PLog',
'Protune', 'REDLog', 'REDLogFilm', 'S-Log', 'S-Log2', 'S-Log3',
'T-Log', 'V-Log', 'ViperLog'}**
"""


Expand All @@ -312,9 +316,9 @@ def log_decoding(value, function='Cineon', **kwargs):
function : unicode, optional
**{'ACEScc', 'ACEScct', 'ACESproxy', 'ALEXA Log C', 'Canon Log 2',
'Canon Log 3', 'Canon Log', 'Cineon', 'D-Log', 'ERIMM RGB', 'F-Log',
'Filmic Pro 6', 'Log3G10', 'Log3G12', 'Panalog', 'PLog', 'Protune',
'REDLog', 'REDLogFilm', 'S-Log', 'S-Log2', 'S-Log3', 'T-Log',
'V-Log', 'ViperLog'}**,
'Filmic Pro 6', 'Log2', 'Log3G10', 'Log3G12', 'Panalog', 'PLog',
'Protune', 'REDLog', 'REDLogFilm', 'S-Log', 'S-Log2', 'S-Log3',
'T-Log', 'V-Log', 'ViperLog'}**,
Computation function.
Other Parameters
Expand Down
170 changes: 170 additions & 0 deletions colour/models/rgb/transfer_functions/log.py
@@ -0,0 +1,170 @@
#
"""
Common Log Encodings
====================
Defines the common log encodings:
- :func:`colour.models.log_encoding_Log2`
- :func:`colour.models.log_decoding_Log2`
References
----------
- :cite:`TheAcademyofMotionPictureArtsandSciencesa` :
The Academy of Motion Picture Arts and Sciences,
Science and Technology Council,
& Academy Color Encoding System (ACES) Project Subcommittee.(n.d.-a).
ACESutil.Lin_to_Log2_param.ctl. Retrieved June 14, 2020,
from https://github.com/ampas/aces-dev/blob/\
518c27f577e99cdecfddf2ebcfaa53444b1f9343/transforms/ctl/utilities/ACESutil.Lin_to_Log2_param.ctl
- :cite:`TheAcademyofMotionPictureArtsandSciencesb` :
The Academy of Motion Picture Arts and Sciences,
Science and Technology Council,
& Academy Color Encoding System (ACES) Project Subcommittee.(n.d.-b).
ACESutil.Log2_to_Lin_param.ctl. Retrieved June 14, 2020,
from https://github.com/ampas/aces-dev/blob/\
518c27f577e99cdecfddf2ebcfaa53444b1f9343/transforms/ctl/utilities/ACESutil.Log2_to_Lin_param.ctl
"""

from __future__ import division, unicode_literals

import numpy as np
from colour.utilities import from_range_1, to_domain_1

__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__ = ['log_encoding_Log2', 'log_decoding_Log2']


def log_encoding_Log2(lin,
middle_grey=0.18,
min_exposure=0.18 * 2 ** -6.5,
max_exposure=0.18 * 2 ** 6.5):
"""
Defines the common *Log2* encoding function.
Parameters
----------
lin : numeric or array_like
Linear data to undergo encoding.
middle_grey : numeric, optional
*Middle Grey* exposure value.
min_exposure : numeric, optional
Minimum exposure level.
max_exposure : numeric, optional
Maximum exposure level.
Returns
-------
numeric or ndarray
Non-linear *Log2* encoded data.
Notes
-----
The common *Log2* encoding function can be used
to build linear to logarithmic shapers in the
ACES OCIO configuration.
A (48-nits OCIO) shaper having values in a linear
domain, can be encoded to a logarithmic domain:
+-------------------+-------------------+
| **Shaper Domain** | **Shaper Range** |
+===================+===================+
| [0.002, 16.291] | [0, 1] |
+-------------------+-------------------+
References
----------
:cite:`TheAcademyofMotionPictureArtsandSciencesa`
Examples
--------
Linear numeric input is encoded as follows:
>>> log_encoding_Log2(18)
0.40773288970434662
Linear array-like input is encoded as follows:
>>> log_encoding_Log2(np.linspace(1, 2, 3))
array([ 0.15174832, 0.18765817, 0.21313661])
"""

lin = to_domain_1(lin)

lg2 = np.log2(lin / middle_grey)
log_norm = (lg2 - min_exposure) / (max_exposure - min_exposure)

return from_range_1(log_norm)


def log_decoding_Log2(log_norm,
middle_grey=0.18,
min_exposure=0.18 * 2 ** -6.5,
max_exposure=0.18 * 2 ** 6.5):
"""
Defines the common *Log2* decoding function.
Parameters
----------
log_norm : numeric or array_like
Logarithmic data to undergo decoding.
middle_grey : numeric, optional
*Middle Grey* exposure value.
min_exposure : numeric, optional
Minimum exposure level.
max_exposure : numeric, optional
Maximum exposure level.
Returns
-------
numeric or ndarray
Linear *Log2* decoded data.
Notes
-----
The common *Log2* decoding function can be used
to build logarithmic to linear shapers in the
ACES OCIO configuration.
The shaper with logarithmic encoded values can be
decoded back to linear domain:
+-------------------+-------------------+
| **Shaper Range** | **Shaper Domain** |
+===================+===================+
| [0, 1] | [0.002, 16.291] |
+-------------------+-------------------+
References
----------
:cite:`TheAcademyofMotionPictureArtsandSciencesb`
Examples
--------
Logarithmic input is decoded as follows:
>>> log_decoding_Log2(0.40773288970434662)
17.999999999999993
Linear array-like input is encoded as follows:
>>> log_decoding_Log2(np.linspace(0, 1, 4))
array([ 1.80248299e-01, 7.77032379e+00, 3.34970882e+02,
1.44402595e+04])
"""

log_norm = to_domain_1(log_norm)

lg2 = log_norm * (max_exposure - min_exposure) + min_exposure
lin = (2 ** lg2) * middle_grey

return from_range_1(lin)

0 comments on commit d79d7cd

Please sign in to comment.