Skip to content

Commit

Permalink
Merge a027d2e into c67825d
Browse files Browse the repository at this point in the history
  • Loading branch information
KelSolaar committed Sep 18, 2018
2 parents c67825d + a027d2e commit 0ddaaa4
Show file tree
Hide file tree
Showing 5 changed files with 388 additions and 15 deletions.
15 changes: 15 additions & 0 deletions BIBLIOGRAPHY.bib
Expand Up @@ -337,6 +337,13 @@ @misc{Centore2014l
url = {https://github.com/colour-science/MunsellAndKubelkaMunkToolbox},
year = {2014}
}
@misc{Chamberlain2015,
author = {Chamberlain, Peter},
title = {{LUT documentation (to create from another program)}},
url = {https://forum.blackmagicdesign.com/viewtopic.php?f=21&t=40284#p232952},
urldate = {2018-08-23},
year = {2015}
}
@article{Cheung2004,
abstract = {The proliferation of low-cost colour imaging devices in the consumer market has led to a greater need to transfer images from one medium or device to another without loss of colour fidelity. A common solution is to characterise each device in terms of its CIE tristimulus values. In this paper two general techniques, artificial neural networks and polynomial transforms, are compared for their usefulness in characterising colour cameras. The neural and polynomial techniques are shown to give approximately similar performance once the parameters of the models are optimised. Since neural networks can be difficult and time-consuming to train, it is concluded that polynomial transforms offer the better alternative for camera characterisation.},
author = {Cheung, Vien and Westland, Stephen and Connah, David and Ripamonti, Caterina},
Expand Down Expand Up @@ -907,6 +914,14 @@ @article{Fairman1997
volume = {22},
year = {1997}
}
@misc{FiLMiCInc2017,
author = {{FiLMiC Inc}},
file = {:Users/kelsolaar/Google Drive/Documents/Mendeley Desktop/FiLMiC Inc - 2017 - FiLMiC Pro - User Manual v6 - Revision 1.pdf:pdf},
pages = {1--46},
title = {{FiLMiC Pro - User Manual v6 - Revision 1}},
url = {http://www.filmicpro.com/FilmicProUserManualv6.pdf},
year = {2017}
}
@article{Finlayson2015,
abstract = {Cameras record three color responses (RGB) which are device dependent. Camera coordinates are mapped to a standard color space, such as XYZ—useful for color measurement—by amapping function, e.g., the simple 3×3 linear transform (usually derived through regression). This mapping, which we will refer to as linear color correction (LCC), has been demonstrated to work well in the number of studies. However, it can map RGBs to XYZs with high error. The advantage of the LCC is that it is independent of camera exposure. An alternative and potentially more powerful method for color correction is polynomial color correction (PCC). Here, the R, G,and B values at a pixel are extended by the polynomial terms. For a given calibration training set PCC can significantly reduce the colorimetric error. However, the PCC fit depends on exposure, i.e., as exposure changes the vector of polynomial components is altered in a nonlinear way which results in hue and saturation shifts. This paper proposes a new polynomial-type regression loosely related to the idea of fractional polynomials which we call root-PCC (RPCC). Our idea is to take each term in a polynomial expansion and take its kth root of each k-degree term. It is easy to show terms defined in this way scale with exposure. RPCC is a simple (low complexity) extension of LCC. The experiments presented in this paper demonstrate that RPCC enhances color correction performance on real and synthetic data.},
author = {Finlayson, Graham D. and MacKiewicz, Michal and Hurlbert, Anya},
Expand Down
30 changes: 18 additions & 12 deletions colour/models/rgb/transfer_functions/__init__.py
Expand Up @@ -18,6 +18,7 @@
from .cineon import log_encoding_Cineon, log_decoding_Cineon
from .dcdm import oetf_DCDM, eotf_DCDM
from .dicom_gsdf import oetf_DICOMGSDF, eotf_DICOMGSDF
from .filmic_pro import log_encoding_FilmicPro6, log_decoding_FilmicPro6
from .gamma import function_gamma
from .gopro import log_encoding_Protune, log_decoding_Protune
from .itur_bt_601 import oetf_BT601, oetf_reverse_BT601
Expand Down Expand Up @@ -63,6 +64,7 @@
__all__ += ['log_encoding_Cineon', 'log_decoding_Cineon']
__all__ += ['oetf_DCDM', 'eotf_DCDM']
__all__ += ['oetf_DICOMGSDF', 'eotf_DICOMGSDF']
__all__ += ['log_encoding_FilmicPro6', 'log_decoding_FilmicPro6']
__all__ += ['function_gamma']
__all__ += ['log_encoding_Protune', 'log_decoding_Protune']
__all__ += ['oetf_BT601', 'oetf_reverse_BT601']
Expand Down Expand Up @@ -108,6 +110,7 @@
'Canon Log': log_encoding_CanonLog,
'Cineon': log_encoding_Cineon,
'ERIMM RGB': log_encoding_ERIMMRGB,
'Filmic Pro 6': log_encoding_FilmicPro6,
'Log3G10': log_encoding_Log3G10,
'Log3G12': log_encoding_Log3G12,
'Panalog': log_encoding_Panalog,
Expand All @@ -126,9 +129,9 @@
LOG_ENCODING_CURVES : CaseInsensitiveMapping
**{'ACEScc', 'ACEScct', 'ACESproxy', 'ALEXA Log C', 'Canon Log 2',
'Canon Log 3', 'Canon Log', 'Cineon', 'ERIMM RGB', 'Log3G10', 'Log3G12',
'Panalog', 'PLog', 'Protune', 'REDLog', 'REDLogFilm', 'S-Log', 'S-Log2',
'S-Log3', 'V-Log', 'ViperLog'}**
'Canon Log 3', 'Canon Log', 'Cineon', 'ERIMM RGB', 'Filmic Pro 6',
'Log3G10', 'Log3G12', 'Panalog', 'PLog', 'Protune', 'REDLog', 'REDLogFilm',
'S-Log', 'S-Log2', 'S-Log3', 'V-Log', 'ViperLog'}**
"""


Expand All @@ -143,9 +146,10 @@ def log_encoding_curve(value, curve='Cineon', **kwargs):
Value.
curve : unicode, optional
**{'ACEScc', 'ACEScct', 'ACESproxy', 'ALEXA Log C', 'Canon Log 2',
'Canon Log 3', 'Canon Log', 'Cineon', 'ERIMM RGB', 'Log3G10',
'Log3G12', 'Panalog', 'PLog', 'Protune', 'REDLog', 'REDLogFilm',
'S-Log', 'S-Log2', 'S-Log3', 'V-Log', 'ViperLog'}**, Computation curve.
'Canon Log 3', 'Canon Log', 'Cineon', 'ERIMM RGB', 'Filmic Pro 6',
'Log3G10', 'Log3G12', 'Panalog', 'PLog', 'Protune', 'REDLog',
'REDLogFilm', 'S-Log', 'S-Log2', 'S-Log3', 'V-Log', 'ViperLog'}**,
Computation curve.
Other Parameters
----------------
Expand Down Expand Up @@ -238,6 +242,7 @@ def log_encoding_curve(value, curve='Cineon', **kwargs):
'Canon Log': log_decoding_CanonLog,
'Cineon': log_decoding_Cineon,
'ERIMM RGB': log_decoding_ERIMMRGB,
'Filmic Pro 6': log_decoding_FilmicPro6,
'Log3G10': log_decoding_Log3G10,
'Log3G12': log_decoding_Log3G12,
'Panalog': log_decoding_Panalog,
Expand All @@ -256,9 +261,9 @@ def log_encoding_curve(value, curve='Cineon', **kwargs):
LOG_DECODING_CURVES : CaseInsensitiveMapping
**{'ACEScc', 'ACEScct', 'ACESproxy', 'ALEXA Log C', 'Canon Log 2',
'Canon Log 3', 'Canon Log', 'Cineon', 'ERIMM RGB', 'Log3G10', 'Log3G12',
'Panalog', 'PLog', 'Protune', 'REDLog', 'REDLogFilm', 'S-Log', 'S-Log2',
'S-Log3', 'V-Log', 'ViperLog'}**
'Canon Log 3', 'Canon Log', 'Cineon', 'ERIMM RGB', 'Filmic Pro 6',
'Log3G10', 'Log3G12', 'Panalog', 'PLog', 'Protune', 'REDLog', 'REDLogFilm',
'S-Log', 'S-Log2', 'S-Log3', 'V-Log', 'ViperLog'}**
"""


Expand All @@ -273,9 +278,10 @@ def log_decoding_curve(value, curve='Cineon', **kwargs):
Value.
curve : unicode, optional
**{'ACEScc', 'ACEScct', 'ACESproxy', 'ALEXA Log C', 'Canon Log 2',
'Canon Log 3', 'Canon Log', 'Cineon', 'ERIMM RGB', 'Log3G10',
'Log3G12', 'Panalog', 'PLog', 'Protune', 'REDLog', 'REDLogFilm',
'S-Log', 'S-Log2', 'S-Log3', 'V-Log', 'ViperLog'}**, Computation curve.
'Canon Log 3', 'Canon Log', 'Cineon', 'ERIMM RGB', 'Filmic Pro 6',
'Log3G10', 'Log3G12', 'Panalog', 'PLog', 'Protune', 'REDLog',
'REDLogFilm', 'S-Log', 'S-Log2', 'S-Log3', 'V-Log', 'ViperLog'}**,
Computation curve.
Other Parameters
----------------
Expand Down
175 changes: 175 additions & 0 deletions colour/models/rgb/transfer_functions/filmic_pro.py
@@ -0,0 +1,175 @@
# -*- coding: utf-8 -*-
"""
FiLMiC Pro 6 Encoding
=============--======
Defines the *FiLMiC Pro 6* encoding:
- :func:`colour.models.log_encoding_FilmicPro6`
- :func:`colour.models.log_decoding_FilmicPro6`
See Also
--------
`RGB Colourspaces Jupyter Notebook
<http://nbviewer.jupyter.org/github/colour-science/colour-notebooks/\
blob/master/notebooks/models/rgb.ipynb>`_
References
----------
- :cite:`FiLMiCInc2017` : FiLMiC Inc. (2017). FiLMiC Pro - User Manual v6 -
Revision 1. Retrieved from http://www.filmicpro.com/\
FilmicProUserManualv6.pdf
"""

from __future__ import division, unicode_literals

import numpy as np

from colour.algebra import Extrapolator, LinearInterpolator
from colour.utilities import from_range_1, to_domain_1

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

__all__ = ['log_encoding_FilmicPro6', 'log_decoding_FilmicPro6']


def log_encoding_FilmicPro6(t):
"""
Defines the *FiLMiC Pro 6* log encoding curve / opto-electronic transfer
function.
Parameters
----------
t : numeric or array_like
Linear data :math:`t`.
Returns
-------
numeric or ndarray
Non-linear data :math:`y`.
Notes
-----
+------------+-----------------------+---------------+
| **Domain** | **Scale - Reference** | **Scale - 1** |
+============+=======================+===============+
| ``t`` | [0, 1] | [0, 1] |
+------------+-----------------------+---------------+
+------------+-----------------------+---------------+
| **Range** | **Scale - Reference** | **Scale - 1** |
+============+=======================+===============+
| ``y`` | [0, 1] | [0, 1] |
+------------+-----------------------+---------------+
- The *FiLMiC Pro 6* log encoding curve / opto-electronic transfer
function is only defined for domain (0, 1].
References
----------
:cite:`FiLMiCInc2017`
Warnings
--------
The *FiLMiC Pro 6* log encoding curve / opto-electronic transfer function
was fitted with poor precision and has :math:`Y=1.000000819999999` value
for :math:`t=1`. It also has no linear segment near zero and will thus be
undefined for :math:`t=0` when computing its logarithm.
Examples
--------
>>> log_encoding_FilmicPro6(0.18) # doctest: +ELLIPSIS
0.6066345...
"""

t = to_domain_1(t)

y = 0.371 * (np.sqrt(t) + 0.28257 * np.log(t) + 1.69542)

return from_range_1(y)


_LOG_DECODING_FILMICPRO_INTERPOLATOR_CACHE = None


def _log_decoding_FilmicPro6_interpolator():
"""
Returns the *FiLMiC Pro 6* log decoding curve / electro-optical transfer
function interpolator and caches it if not existing.
Returns
-------
Extrapolator
*FiLMiC Pro 6* log decoding curve / electro-optical transfer
function interpolator.
"""

global _LOG_DECODING_FILMICPRO_INTERPOLATOR_CACHE

t = np.arange(0, 1, 0.0001)
if _LOG_DECODING_FILMICPRO_INTERPOLATOR_CACHE is None:
_LOG_DECODING_FILMICPRO_INTERPOLATOR_CACHE = Extrapolator(
LinearInterpolator(log_encoding_FilmicPro6(t), t))

return _LOG_DECODING_FILMICPRO_INTERPOLATOR_CACHE


def log_decoding_FilmicPro6(y):
"""
Defines the *FiLMiC Pro 6* log decoding curve / electro-optical transfer
function.
Parameters
----------
y : numeric or array_like
Non-linear data :math:`y`.
Returns
-------
numeric or ndarray
Linear data :math:`t`.
Notes
-----
+------------+-----------------------+---------------+
| **Domain** | **Scale - Reference** | **Scale - 1** |
+============+=======================+===============+
| ``y`` | [0, 1] | [0, 1] |
+------------+-----------------------+---------------+
+------------+-----------------------+---------------+
| **Range** | **Scale - Reference** | **Scale - 1** |
+============+=======================+===============+
| ``t`` | [0, 1] | [0, 1] |
+------------+-----------------------+---------------+
- The *FiLMiC Pro 6* log decoding curve / electro-optical transfer
function is only defined for domain (0, 1].
References
----------
:cite:`FiLMiCInc2017`
Warnings
--------
The *FiLMiC Pro 6* log encoding curve / opto-electronic transfer function
has no inverse in :math:`R`, we thus use a *LUT* based inversion.
Examples
--------
>>> log_decoding_FilmicPro6(0.6066345199247033) # doctest: +ELLIPSIS
0.1800000...
"""

y = to_domain_1(y)

t = _log_decoding_FilmicPro6_interpolator()(y)

return from_range_1(t)
11 changes: 8 additions & 3 deletions colour/models/rgb/transfer_functions/tests/test_common.py
Expand Up @@ -211,7 +211,11 @@ def test_transfer_functions(self):
Tests transfer functions reciprocity.
"""

ignored_transfer_functions = ('ACESproxy', 'DICOM GSDF')
ignored_transfer_functions = (
'ACESproxy',
'DICOM GSDF',
'Filmic Pro 6',
)

reciprocal_mappings = [
(LOG_ENCODING_CURVES, LOG_DECODING_CURVES),
Expand All @@ -221,8 +225,9 @@ def test_transfer_functions(self):
(OOTFS, OOTFS_REVERSE),
]

samples = np.hstack([np.linspace(0, 1, 1e5),
np.linspace(0, 65504, 65504 * 10)])
samples = np.hstack(
[np.linspace(0, 1, 1e5),
np.linspace(0, 65504, 65504 * 10)])

for encoding_mapping, decoding_mapping in reciprocal_mappings:
for name in encoding_mapping:
Expand Down

0 comments on commit 0ddaaa4

Please sign in to comment.