Source code for colour.models.rgb.transfer_functions.panasonic_vlog

# -*- coding: utf-8 -*-
"""
Panasonic V-Log Log Encoding
============================

Defines the *Panasonic V-Log* log encoding:

-   :func:`colour.models.log_encoding_VLog`
-   :func:`colour.models.log_decoding_VLog`

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

References
----------
-   :cite:`Panasonic2014a` : Panasonic. (2014). VARICAM V-Log/V-Gamut.
    Retrieved from http://pro-av.panasonic.net/en/varicam/common/pdf/\
VARICAM_V-Log_V-Gamut.pdf
"""

from __future__ import division, unicode_literals

import numpy as np

from colour.models.rgb.transfer_functions import full_to_legal, legal_to_full
from colour.utilities import Structure, as_float, from_range_1, to_domain_1
from colour.utilities.deprecation import handle_arguments_deprecation

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

__all__ = ['VLOG_CONSTANTS', 'log_encoding_VLog', 'log_decoding_VLog']

VLOG_CONSTANTS = Structure(
    cut1=0.01, cut2=0.181, b=0.00873, c=0.241514, d=0.598206)
"""
*Panasonic V-Log* colourspace constants.

VLOG_CONSTANTS : Structure
"""


[docs]def log_encoding_VLog(L_in, bit_depth=10, out_normalised_code_value=True, in_reflection=True, constants=VLOG_CONSTANTS, **kwargs): """ Defines the *Panasonic V-Log* log encoding curve / opto-electronic transfer function. Parameters ---------- L_in : numeric or array_like Linear reflection data :math`L_{in}`. bit_depth : int, optional Bit depth used for conversion. out_normalised_code_value : bool, optional Whether the non-linear *Panasonic V-Log* data :math:`V_{out}` is encoded as normalised code values. in_reflection : bool, optional Whether the light level :math`L_{in}` to a camera is reflection. constants : Structure, optional *Panasonic V-Log* constants. Other Parameters ---------------- \\**kwargs : dict, optional Keywords arguments for deprecation management. Returns ------- numeric or ndarray Non-linear data :math:`V_{out}`. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``L_in`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``V_out`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`Panasonic2014a` Examples -------- >>> log_encoding_VLog(0.18) # doctest: +ELLIPSIS 0.4233114... The values of *Fig.2.2 V-Log Code Value* table in :cite:`Panasonic2014a` are obtained as follows: >>> L_in = np.array([0, 18, 90]) / 100 >>> np.around(log_encoding_VLog(L_in, 10, False) * 100).astype(np.int) array([ 7, 42, 61]) >>> np.around(log_encoding_VLog(L_in) * (2 ** 10 - 1)).astype(np.int) array([128, 433, 602]) >>> np.around(log_encoding_VLog(L_in) * (2 ** 12 - 1)).astype(np.int) array([ 512, 1733, 2409]) Note that some values in the last column values of *Fig.2.2 V-Log Code Value* table in :cite:`Panasonic2014a` are different by a code: [512, 1732, 2408]. """ out_normalised_code_value = handle_arguments_deprecation({ 'ArgumentRenamed': [['out_legal', 'out_normalised_code_value']], }, **kwargs).get('out_normalised_code_value', out_normalised_code_value) L_in = to_domain_1(L_in) if not in_reflection: L_in = L_in * 0.9 cut1 = constants.cut1 b = constants.b c = constants.c d = constants.d V_out = np.where( L_in < cut1, 5.6 * L_in + 0.125, c * np.log10(L_in + b) + d, ) V_out = (V_out if out_normalised_code_value else legal_to_full(V_out, bit_depth)) return as_float(from_range_1(V_out))
[docs]def log_decoding_VLog(V_out, bit_depth=10, in_normalised_code_value=True, out_reflection=True, constants=VLOG_CONSTANTS, **kwargs): """ Defines the *Panasonic V-Log* log decoding curve / electro-optical transfer function. Parameters ---------- V_out : numeric or array_like Non-linear data :math:`V_{out}`. bit_depth : int, optional Bit depth used for conversion. in_normalised_code_value : bool, optional Whether the non-linear *Panasonic V-Log* data :math:`V_{out}` is encoded as normalised code values. out_reflection : bool, optional Whether the light level :math`L_{in}` to a camera is reflection. constants : Structure, optional *Panasonic V-Log* constants. Other Parameters ---------------- \\**kwargs : dict, optional Keywords arguments for deprecation management. Returns ------- numeric or ndarray Linear reflection data :math`L_{in}`. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``V_out`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``L_in`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`Panasonic2014a` Examples -------- >>> log_decoding_VLog(0.423311448760136) # doctest: +ELLIPSIS 0.1799999... """ in_normalised_code_value = handle_arguments_deprecation({ 'ArgumentRenamed': [['in_legal', 'in_normalised_code_value']], }, **kwargs).get('in_normalised_code_value', in_normalised_code_value) V_out = to_domain_1(V_out) V_out = (V_out if in_normalised_code_value else full_to_legal(V_out, bit_depth)) cut2 = constants.cut2 b = constants.b c = constants.c d = constants.d L_in = np.where( V_out < cut2, (V_out - 0.125) / 5.6, 10 ** ((V_out - d) / c) - b, ) if not out_reflection: L_in = L_in / 0.9 return as_float(from_range_1(L_in))