def test_nan_full_to_legal(self): """ Tests :func:`colour.models.rgb.transfer_functions.common.full_to_legal` definition nan support. """ full_to_legal(np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]), 10)
def test_n_dimensional_full_to_legal(self): """ Tests :func:`colour.models.rgb.transfer_functions.common.full_to_legal` definition n-dimensional arrays support. """ CF_f = 1.0 CV_l = 0.918866080156403 np.testing.assert_almost_equal(full_to_legal(CF_f, 10), CV_l, decimal=7) CF_f = np.tile(CF_f, 6) CV_l = np.tile(CV_l, 6) np.testing.assert_almost_equal(full_to_legal(CF_f, 10), CV_l, decimal=7) CF_f = np.reshape(CF_f, (2, 3)) CV_l = np.reshape(CV_l, (2, 3)) np.testing.assert_almost_equal(full_to_legal(CF_f, 10), CV_l, decimal=7) CF_f = np.reshape(CF_f, (2, 3, 1)) CV_l = np.reshape(CV_l, (2, 3, 1)) np.testing.assert_almost_equal(full_to_legal(CF_f, 10), CV_l, decimal=7)
def log_decoding_SLog3(y, bit_depth=10, in_legal=True, out_reflection=True): """ Defines the *Sony S-Log3* log decoding curve / electro-optical transfer function. Parameters ---------- y : numeric or array_like Non-linear *Sony S-Log3* data :math:`y`. bit_depth : int, optional Bit depth used for conversion. in_legal : bool, optional Whether the non-linear *Sony S-Log3* data :math:`y` is encoded in legal range. out_reflection : bool, optional Whether the light level :math:`x` to a camera is reflection. Returns ------- numeric or ndarray Reflection or :math:`IRE / 100` input light level :math:`x` to a camera. References ---------- - :cite:`SonyCorporationd` Examples -------- >>> log_decoding_SLog3(0.410557184750733) # doctest: +ELLIPSIS 0.1... >>> log_decoding_SLog3(0.406392694063927, in_legal=False) ... # doctest: +ELLIPSIS 0.1... >>> log_decoding_SLog3(0.399507939606216, out_reflection=False) ... # doctest: +ELLIPSIS 0.1... """ y = np.asarray(y) y = y if in_legal else full_to_legal(y, bit_depth) x = np.where(y >= 171.2102946929 / 1023, ((10**((y * 1023 - 420) / 261.5)) * (0.18 + 0.01) - 0.01), (y * 1023 - 95) * 0.01125000 / (171.2102946929 - 95)) if not out_reflection: x = x / 0.9 return as_numeric(x)
def test_n_dimensional_full_to_legal(self): """ Tests :func:`colour.models.rgb.transfer_functions.common.full_to_legal` definition n-dimensional arrays support. """ CF_f = 1.0 CV_l = full_to_legal(CF_f, 10) CF_f = np.tile(CF_f, 6) CV_l = np.tile(CV_l, 6) np.testing.assert_almost_equal( full_to_legal(CF_f, 10), CV_l, decimal=7) CF_f = np.reshape(CF_f, (2, 3)) CV_l = np.reshape(CV_l, (2, 3)) np.testing.assert_almost_equal( full_to_legal(CF_f, 10), CV_l, decimal=7) CF_f = np.reshape(CF_f, (2, 3, 1)) CV_l = np.reshape(CV_l, (2, 3, 1)) np.testing.assert_almost_equal( full_to_legal(CF_f, 10), CV_l, decimal=7)
def log_encoding_SLog(x, bit_depth=10, out_legal=True, in_reflection=True): """ Defines the *Sony S-Log* log encoding curve / opto-electronic transfer function. Parameters ---------- x : numeric or array_like Reflection or :math:`IRE / 100` input light level :math:`x` to a camera. bit_depth : int, optional Bit depth used for conversion. out_legal : bool, optional Whether the non-linear *Sony S-Log* data :math:`y` is encoded in legal range. in_reflection : bool, optional Whether the light level :math:`x` to a camera is reflection. Returns ------- numeric or ndarray Non-linear *Sony S-Log* data :math:`y`. References ---------- - :cite:`SonyCorporation2012a` Examples -------- >>> log_encoding_SLog(0.18) # doctest: +ELLIPSIS 0.3849708... >>> log_encoding_SLog(0.18, out_legal=False) # doctest: +ELLIPSIS 0.3765127... >>> log_encoding_SLog(0.18, in_reflection=False) # doctest: +ELLIPSIS 0.3708204... """ x = np.asarray(x) if in_reflection: x = x / 0.9 y = np.where(x >= 0, ((0.432699 * np.log10(x + 0.037584) + 0.616596) + 0.03), x * 5 + 0.030001222851889303) y = full_to_legal(y, bit_depth) if out_legal else y return as_numeric(y)
def log_decoding_VLog(V_out, bit_depth=10, in_legal=True, out_reflection=True): """ 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_legal : bool, optional Whether the non-linear *Panasonic V-Log* data :math:`V_{out}` is encoded in legal range. out_reflection : bool, optional Whether the light level :math`L_{in}` to a camera is reflection. Returns ------- numeric or ndarray Linear reflection data :math`L_{in}`. References ---------- - :cite:`Panasonic2014a` Examples -------- >>> log_decoding_VLog(0.423311448760136) # doctest: +ELLIPSIS 0.1799999... """ V_out = np.asarray(V_out) V_out = V_out if in_legal else full_to_legal(V_out, bit_depth) cut2 = VLOG_CONSTANTS.cut2 b = VLOG_CONSTANTS.b c = VLOG_CONSTANTS.c d = VLOG_CONSTANTS.d L_in = np.where(V_out < cut2, (V_out - 0.125) / 5.6, np.power(10, ((V_out - d) / c)) - b) if not out_reflection: L_in = L_in / 0.9 return as_numeric(L_in)
def log_encoding_CanonLog2(x, bit_depth=10, out_legal=True, in_reflection=True): """ Defines the *Canon Log 2* log encoding curve / opto-electronic transfer function. Parameters ---------- x : numeric or array_like Linear data :math:`x`. bit_depth : int, optional Bit depth used for conversion. out_legal : bool, optional Whether the *Canon Log 2* non-linear data is encoded in legal range. in_reflection : bool, optional Whether the light level :math:`x` to a camera is reflection. Returns ------- numeric or ndarray *Canon Log 2* non-linear data. References ---------- - :cite:`Canona` Examples -------- >>> log_encoding_CanonLog2(0.18) * 100 # doctest: +ELLIPSIS 39.8254694... """ x = np.asarray(x) if in_reflection: x = x / 0.9 clog2 = np.where(x < log_decoding_CanonLog2(0.035388128, bit_depth, False), -(0.281863093 * (np.log10(-x * 87.09937546 + 1)) - 0.035388128), 0.281863093 * np.log10(x * 87.09937546 + 1) + 0.035388128) clog2 = full_to_legal(clog2, bit_depth) if out_legal else clog2 return as_numeric(clog2)
def log_encoding_CanonLog(x, bit_depth=10, out_legal=True, in_reflection=True): """ Defines the *Canon Log* log encoding curve / opto-electronic transfer function. Parameters ---------- x : numeric or array_like Linear data :math:`x`. bit_depth : int, optional Bit depth used for conversion. out_legal : bool, optional Whether the *Canon Log* non-linear data is encoded in legal range. in_reflection : bool, optional Whether the light level :math:`x` to a camera is reflection. Returns ------- numeric or ndarray *Canon Log* non-linear data. References ---------- - :cite:`Thorpe2012a` Examples -------- >>> log_encoding_CanonLog(0.18) * 100 # doctest: +ELLIPSIS 34.3389651... """ x = np.asarray(x) if in_reflection: x = x / 0.9 clog = np.where(x < log_decoding_CanonLog(0.0730597, bit_depth, False), -(0.529136 * (np.log10(-x * 10.1596 + 1)) - 0.0730597), 0.529136 * np.log10(10.1596 * x + 1) + 0.0730597) clog = full_to_legal(clog, bit_depth) if out_legal else clog return as_numeric(clog)
def test_full_to_legal(self): """ Tests :func:`colour.models.rgb.transfer_functions.common.full_to_legal` definition. """ self.assertAlmostEqual(full_to_legal(0.0), 0.062561094819159) self.assertAlmostEqual(full_to_legal(1.0), 0.918866080156403) self.assertAlmostEqual(full_to_legal(0.0, out_int=True), 64) self.assertAlmostEqual(full_to_legal(1.0, out_int=True), 940) self.assertAlmostEqual(full_to_legal(0, in_int=True), 0.062561094819159) self.assertAlmostEqual(full_to_legal(1023, in_int=True), 0.918866080156403) self.assertAlmostEqual(full_to_legal(0, in_int=True, out_int=True), 64) self.assertAlmostEqual(full_to_legal(1023, in_int=True, out_int=True), 940)
def test_full_to_legal(self): """ Tests :func:`colour.models.rgb.transfer_functions.common.full_to_legal` definition. """ self.assertAlmostEqual(full_to_legal(0.0), 0.062561094819159) self.assertAlmostEqual(full_to_legal(1.0), 0.918866080156403) self.assertAlmostEqual(full_to_legal(0.0, out_int=True), 64) self.assertAlmostEqual(full_to_legal(1.0, out_int=True), 940) self.assertAlmostEqual( full_to_legal(0, in_int=True), 0.062561094819159) self.assertAlmostEqual( full_to_legal(1023, in_int=True), 0.918866080156403) self.assertAlmostEqual(full_to_legal(0, in_int=True, out_int=True), 64) self.assertAlmostEqual( full_to_legal(1023, in_int=True, out_int=True), 940)
def log_decoding_NLog( out_r: FloatingOrArrayLike, bit_depth: Integer = 10, in_normalised_code_value: Boolean = True, out_reflection: Boolean = True, constants: Structure = NLOG_CONSTANTS, ) -> FloatingOrNDArray: """ Define the *Nikon N-Log* log decoding curve / electro-optical transfer function. Parameters ---------- out_r Non-linear data :math:`out`. bit_depth Bit depth used for conversion. in_normalised_code_value Whether the non-linear *Nikon N-Log* data :math:`out` is encoded as normalised code values. out_reflection Whether the light level :math`in` to a camera is reflection. constants *Nikon N-Log* constants. Returns ------- :class:`numpy.floating` or :class:`numpy.ndarray` Linear reflection data :math`in`. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``out_r`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``in_r`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`Nikon2018` Examples -------- >>> log_decoding_NLog(0.36366777011713869) # doctest: +ELLIPSIS 0.1799999... """ out_r = to_domain_1(out_r) out_r = (out_r if in_normalised_code_value else full_to_legal( out_r, bit_depth)) cut2 = constants.cut2 a = constants.a b = constants.b c = constants.c d = constants.d in_r = np.where( out_r < cut2, spow(out_r / a, 3) - b, np.exp((out_r - d) / c), ) if not out_reflection: in_r = in_r / 0.9 return as_float(from_range_1(in_r))
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))
def log_decoding_VLog(V_out, bit_depth=10, in_legal=True, out_reflection=True, constants=VLOG_CONSTANTS): """ 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_legal : bool, optional Whether the non-linear *Panasonic V-Log* data :math:`V_{out}` is encoded in legal range. out_reflection : bool, optional Whether the light level :math`L_{in}` to a camera is reflection. constants : Structure, optional *Panasonic V-Log* constants. 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... """ V_out = to_domain_1(V_out) V_out = V_out if in_legal 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))
def log_decoding_SLog3(y, bit_depth=10, in_legal=True, out_reflection=True): """ Defines the *Sony S-Log3* log decoding curve / electro-optical transfer function. Parameters ---------- y : numeric or array_like Non-linear *Sony S-Log3* data :math:`y`. bit_depth : int, optional Bit depth used for conversion. in_legal : bool, optional Whether the non-linear *Sony S-Log3* data :math:`y` is encoded in legal range. out_reflection : bool, optional Whether the light level :math:`x` to a camera is reflection. Returns ------- numeric or ndarray Reflection or :math:`IRE / 100` input light level :math:`x` to a camera. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``y`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``x`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`SonyCorporationd` Examples -------- >>> log_decoding_SLog3(0.410557184750733) # doctest: +ELLIPSIS 0.1... >>> log_decoding_SLog3(0.406392694063927, in_legal=False) ... # doctest: +ELLIPSIS 0.1... >>> log_decoding_SLog3(0.399507939606216, out_reflection=False) ... # doctest: +ELLIPSIS 0.1... """ y = to_domain_1(y) y = y if in_legal else full_to_legal(y, bit_depth) x = np.where( y >= 171.2102946929 / 1023, ((10 ** ((y * 1023 - 420) / 261.5)) * (0.18 + 0.01) - 0.01), (y * 1023 - 95) * 0.01125000 / (171.2102946929 - 95), ) if not out_reflection: x = x / 0.9 return as_float(from_range_1(x))
def log_encoding_CanonLog(x, bit_depth=10, out_legal=True, in_reflection=True): """ Defines the *Canon Log* log encoding curve / opto-electronic transfer function. Parameters ---------- x : numeric or array_like Linear data :math:`x`. bit_depth : int, optional Bit depth used for conversion. out_legal : bool, optional Whether the *Canon Log* non-linear data is encoded in legal range. in_reflection : bool, optional Whether the light level :math:`x` to a camera is reflection. Returns ------- numeric or ndarray *Canon Log* non-linear data. References ---------- :cite:`Thorpe2012a` Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``x`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``clog`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ Examples -------- >>> log_encoding_CanonLog(0.18) * 100 # doctest: +ELLIPSIS 34.3389651... """ x = to_domain_1(x) if in_reflection: x = x / 0.9 with domain_range_scale('ignore'): clog = np.where( x < log_decoding_CanonLog(0.0730597, bit_depth, False), -(0.529136 * (np.log10(-x * 10.1596 + 1)) - 0.0730597), 0.529136 * np.log10(10.1596 * x + 1) + 0.0730597, ) clog = full_to_legal(clog, bit_depth) if out_legal else clog return as_float(from_range_1(clog))
def log_encoding_CanonLog2(x, bit_depth=10, out_legal=True, in_reflection=True): """ Defines the *Canon Log 2* log encoding curve / opto-electronic transfer function. Parameters ---------- x : numeric or array_like Linear data :math:`x`. bit_depth : int, optional Bit depth used for conversion. out_legal : bool, optional Whether the *Canon Log 2* non-linear data is encoded in legal range. in_reflection : bool, optional Whether the light level :math:`x` to a camera is reflection. Returns ------- numeric or ndarray *Canon Log 2* non-linear data. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``x`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``clog2`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`Canona` Examples -------- >>> log_encoding_CanonLog2(0.18) * 100 # doctest: +ELLIPSIS 39.8254694... """ x = to_domain_1(x) if in_reflection: x = x / 0.9 with domain_range_scale('ignore'): clog2 = np.where( x < log_decoding_CanonLog2(0.035388128, bit_depth, False), -(0.281863093 * (np.log10(-x * 87.09937546 + 1)) - 0.035388128), 0.281863093 * np.log10(x * 87.09937546 + 1) + 0.035388128, ) clog2 = full_to_legal(clog2, bit_depth) if out_legal else clog2 return as_float(from_range_1(clog2))
def log_decoding_VLog( V_out: FloatingOrArrayLike, bit_depth: Integer = 10, in_normalised_code_value: Boolean = True, out_reflection: Boolean = True, constants: Structure = CONSTANTS_VLOG, ) -> FloatingOrNDArray: """ Define the *Panasonic V-Log* log decoding curve / electro-optical transfer function. Parameters ---------- V_out Non-linear data :math:`V_{out}`. bit_depth Bit depth used for conversion. in_normalised_code_value Whether the non-linear *Panasonic V-Log* data :math:`V_{out}` is encoded as normalised code values. out_reflection Whether the light level :math`L_{in}` to a camera is reflection. constants *Panasonic V-Log* constants. Returns ------- :class:`numpy.floating` or :class:`numpy.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... """ 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))
def log_decoding_SLog3( y: FloatingOrArrayLike, bit_depth: Integer = 10, in_normalised_code_value: Boolean = True, out_reflection: Boolean = True, ) -> FloatingOrNDArray: """ Define the *Sony S-Log3* log decoding curve / electro-optical transfer function. Parameters ---------- y Non-linear *Sony S-Log3* data :math:`y`. bit_depth Bit depth used for conversion. in_normalised_code_value Whether the non-linear *Sony S-Log3* data :math:`y` is encoded as normalised code values. out_reflection Whether the light level :math:`x` to a camera is reflection. Returns ------- :class:`numpy.floating` or :class:`numpy.ndarray` Reflection or :math:`IRE / 100` input light level :math:`x` to a camera. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``y`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``x`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`SonyCorporationd` Examples -------- >>> log_decoding_SLog3(0.410557184750733) # doctest: +ELLIPSIS 0.1... """ y = to_domain_1(y) y = y if in_normalised_code_value else full_to_legal(y, bit_depth) x = np.where( y >= 171.2102946929 / 1023, ((10**((y * 1023 - 420) / 261.5)) * (0.18 + 0.01) - 0.01), (y * 1023 - 95) * 0.01125000 / (171.2102946929 - 95), ) if not out_reflection: x = x / 0.9 return as_float(from_range_1(x))
def log_encoding_SLog(x, bit_depth=10, out_legal=True, in_reflection=True): """ Defines the *Sony S-Log* log encoding curve / opto-electronic transfer function. Parameters ---------- x : numeric or array_like Reflection or :math:`IRE / 100` input light level :math:`x` to a camera. bit_depth : int, optional Bit depth used for conversion. out_legal : bool, optional Whether the non-linear *Sony S-Log* data :math:`y` is encoded in legal range. in_reflection : bool, optional Whether the light level :math:`x` to a camera is reflection. Returns ------- numeric or ndarray Non-linear *Sony S-Log* data :math:`y`. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``x`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``y`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`SonyCorporation2012a` Examples -------- >>> log_encoding_SLog(0.18) # doctest: +ELLIPSIS 0.3849708... >>> log_encoding_SLog(0.18, out_legal=False) # doctest: +ELLIPSIS 0.3765127... >>> log_encoding_SLog(0.18, in_reflection=False) # doctest: +ELLIPSIS 0.3708204... """ x = to_domain_1(x) if in_reflection: x = x / 0.9 y = np.where( x >= 0, ((0.432699 * np.log10(x + 0.037584) + 0.616596) + 0.03), x * 5 + 0.030001222851889303, ) y = full_to_legal(y, bit_depth) if out_legal else y return as_float(from_range_1(y))
def log_encoding_SLog(x, bit_depth=10, out_normalised_code_value=True, in_reflection=True, **kwargs): """ Defines the *Sony S-Log* log encoding curve / opto-electronic transfer function. Parameters ---------- x : numeric or array_like Reflection or :math:`IRE / 100` input light level :math:`x` to a camera. bit_depth : int, optional Bit depth used for conversion. out_normalised_code_value : bool, optional Whether the non-linear *Sony S-Log* data :math:`y` is encoded as normalised code values. in_reflection : bool, optional Whether the light level :math:`x` to a camera is reflection. Other Parameters ---------------- \\**kwargs : dict, optional Keywords arguments for deprecation management. Returns ------- numeric or ndarray Non-linear *Sony S-Log* data :math:`y`. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``x`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``y`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`SonyCorporation2012a` Examples -------- >>> log_encoding_SLog(0.18) # doctest: +ELLIPSIS 0.3849708... The values of *IRE and CV of S-Log2 @ISO800* table in :cite:`SonyCorporation2012a` are obtained as follows: >>> x = np.array([0, 18, 90]) / 100 >>> np.around(log_encoding_SLog(x, 10, False) * 100).astype(np.int) array([ 3, 38, 65]) >>> np.around(log_encoding_SLog(x) * (2 ** 10 - 1)).astype(np.int) array([ 90, 394, 636]) """ out_normalised_code_value = handle_arguments_deprecation( { 'ArgumentRenamed': [['out_legal', 'out_normalised_code_value']], }, **kwargs).get('out_normalised_code_value', out_normalised_code_value) x = to_domain_1(x) if in_reflection: x = x / 0.9 y = np.where( x >= 0, ((0.432699 * np.log10(x + 0.037584) + 0.616596) + 0.03), x * 5 + 0.030001222851889303, ) y = full_to_legal(y, bit_depth) if out_normalised_code_value else y return as_float(from_range_1(y))
def log_decoding_FLog(out_r, bit_depth=10, in_normalised_code_value=True, out_reflection=True, constants=CONSTANTS_FLOG): """ Defines the *Fujifilm F-Log* log decoding curve / electro-optical transfer function. Parameters ---------- out_r : numeric or array_like Non-linear data :math:`out`. bit_depth : int, optional Bit depth used for conversion. in_normalised_code_value : bool, optional Whether the non-linear *Fujifilm F-Log* data :math:`out` is encoded as normalised code values. out_reflection : bool, optional Whether the light level :math`in` to a camera is reflection. constants : Structure, optional *Fujifilm F-Log* constants. Returns ------- numeric or ndarray Linear reflection data :math`in`. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``out_r`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``in_r`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`Fujifilm2016` Examples -------- >>> log_decoding_FLog(0.45931845866162124) # doctest: +ELLIPSIS 0.1800000... """ out_r = to_domain_1(out_r) out_r = (out_r if in_normalised_code_value else full_to_legal( out_r, bit_depth)) cut2 = constants.cut2 a = constants.a b = constants.b c = constants.c d = constants.d e = constants.e f = constants.f in_r = np.where( out_r < cut2, (out_r - f) / e, (10**((out_r - d) / c)) / a - b / a, ) if not out_reflection: in_r = in_r / 0.9 return as_float(from_range_1(in_r))
def log_encoding_CanonLog3( x: FloatingOrArrayLike, bit_depth: Integer = 10, out_normalised_code_value: Boolean = True, in_reflection: Boolean = True, ) -> FloatingOrNDArray: """ Define the *Canon Log 3* log encoding curve / opto-electronic transfer function. Parameters ---------- x Linear data :math:`x`. bit_depth Bit depth used for conversion. out_normalised_code_value Whether the *Canon Log 3* non-linear data is encoded as normalised code values. in_reflection Whether the light level :math:`x` to a camera is reflection. Returns ------- :class:`numpy.floating` or :class:`numpy.ndarray` *Canon Log 3* non-linear data. Notes ----- - Introspection of the grafting points by Shaw, N. (2018) shows that the *Canon Log 3* IDT was likely derived from its encoding curve as the later is grafted at *+/-0.014*:: >>> clog3 = 0.04076162 >>> (clog3 - 0.073059361) / 2.3069815 -0.014000000000000002 >>> clog3 = 0.105357102 >>> (clog3 - 0.073059361) / 2.3069815 0.013999999999999997 +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``x`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``clog3`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`Canona` Examples -------- >>> log_encoding_CanonLog3(0.18) * 100 # doctest: +ELLIPSIS 34.3389369... """ x = to_domain_1(x) if in_reflection: x = x / 0.9 with domain_range_scale("ignore"): clog3 = np.select( ( x < log_decoding_CanonLog3(0.04076162, bit_depth, False, False), x <= log_decoding_CanonLog3(0.105357102, bit_depth, False, False), x > log_decoding_CanonLog3(0.105357102, bit_depth, False, False), ), ( -0.42889912 * np.log10(-x * 14.98325 + 1) + 0.07623209, 2.3069815 * x + 0.073059361, 0.42889912 * np.log10(x * 14.98325 + 1) + 0.069886632, ), ) clog3_cv = (full_to_legal(clog3, bit_depth) if out_normalised_code_value else clog3) return as_float(from_range_1(clog3_cv))
def log_encoding_CanonLog3(x, bit_depth=10, out_legal=True, in_reflection=True): """ Defines the *Canon Log 3* log encoding curve / opto-electronic transfer function. Parameters ---------- x : numeric or array_like Linear data :math:`x`. bit_depth : int, optional Bit depth used for conversion. out_legal : bool, optional Whether the *Canon Log 3* non-linear data is encoded in legal range. in_reflection : bool, optional Whether the light level :math:`x` to a camera is reflection. Returns ------- numeric or ndarray *Canon Log 3* non-linear data. Notes ----- - Introspection of the grafting points by Shaw, N. (2018) shows that the *Canon Log 3* IDT was likely derived from its encoding curve as the later is grafted at *+/-0.014*:: >>> clog3 = 0.04076162 >>> (clog3 - 0.073059361) / 2.3069815 -0.014000000000000002 >>> clog3 = 0.105357102 >>> (clog3 - 0.073059361) / 2.3069815 0.013999999999999997 Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``x`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``clog3`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`Canona` Examples -------- >>> log_encoding_CanonLog3(0.18) * 100 # doctest: +ELLIPSIS 34.3389369... """ x = to_domain_1(x) if in_reflection: x = x / 0.9 with domain_range_scale('ignore'): clog3 = np.select( (x < log_decoding_CanonLog3(0.04076162, bit_depth, False, False), x <= log_decoding_CanonLog3(0.105357102, bit_depth, False, False), x > log_decoding_CanonLog3(0.105357102, bit_depth, False, False)), (-0.42889912 * np.log10(-x * 14.98325 + 1) + 0.07623209, 2.3069815 * x + 0.073059361, 0.42889912 * np.log10(x * 14.98325 + 1) + 0.069886632)) clog3 = full_to_legal(clog3, bit_depth) if out_legal else clog3 return as_float(from_range_1(clog3))
def log_encoding_CanonLog2(x, bit_depth=10, out_normalised_code_value=True, in_reflection=True, **kwargs): """ Defines the *Canon Log 2* log encoding curve / opto-electronic transfer function. Parameters ---------- x : numeric or array_like Linear data :math:`x`. bit_depth : int, optional Bit depth used for conversion. out_normalised_code_value : bool, optional Whether the *Canon Log 2* non-linear data is encoded as normalised code values. in_reflection : bool, optional Whether the light level :math:`x` to a camera is reflection. Other Parameters ---------------- \\**kwargs : dict, optional Keywords arguments for deprecation management. Returns ------- numeric or ndarray *Canon Log 2* non-linear data. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``x`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``clog2`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`Canona` Examples -------- >>> log_encoding_CanonLog2(0.18) * 100 # doctest: +ELLIPSIS 39.8254694... """ out_normalised_code_value = handle_arguments_deprecation( { 'ArgumentRenamed': [['out_legal', 'out_normalised_code_value']], }, **kwargs).get('out_normalised_code_value', out_normalised_code_value) x = to_domain_1(x) if in_reflection: x = x / 0.9 with domain_range_scale('ignore'): clog2 = np.where( x < log_decoding_CanonLog2(0.035388128, bit_depth, False), -(0.281863093 * (np.log10(-x * 87.09937546 + 1)) - 0.035388128), 0.281863093 * np.log10(x * 87.09937546 + 1) + 0.035388128, ) clog2 = (full_to_legal(clog2, bit_depth) if out_normalised_code_value else clog2) return as_float(from_range_1(clog2))
def log_encoding_SLog( x: FloatingOrArrayLike, bit_depth: Integer = 10, out_normalised_code_value: Boolean = True, in_reflection: Boolean = True, ) -> FloatingOrNDArray: """ Define the *Sony S-Log* log encoding curve / opto-electronic transfer function. Parameters ---------- x Reflection or :math:`IRE / 100` input light level :math:`x` to a camera. bit_depth Bit depth used for conversion. out_normalised_code_value Whether the non-linear *Sony S-Log* data :math:`y` is encoded as normalised code values. in_reflection Whether the light level :math:`x` to a camera is reflection. Returns ------- :class:`numpy.floating` or :class:`numpy.ndarray` Non-linear *Sony S-Log* data :math:`y`. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``x`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``y`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`SonyCorporation2012a` Examples -------- >>> log_encoding_SLog(0.18) # doctest: +ELLIPSIS 0.3849708... The values of *IRE and CV of S-Log2 @ISO800* table in :cite:`SonyCorporation2012a` are obtained as follows: >>> x = np.array([0, 18, 90]) / 100 >>> np.around(log_encoding_SLog(x, 10, False) * 100).astype(np.int) array([ 3, 38, 65]) >>> np.around(log_encoding_SLog(x) * (2 ** 10 - 1)).astype(np.int) array([ 90, 394, 636]) """ x = to_domain_1(x) if in_reflection: x = x / 0.9 y = np.where( x >= 0, ((0.432699 * np.log10(x + 0.037584) + 0.616596) + 0.03), x * 5 + 0.030001222851889303, ) y_cv = full_to_legal(y, bit_depth) if out_normalised_code_value else y return as_float(from_range_1(y_cv))
def log_decoding_SLog3(y, bit_depth=10, in_normalised_code_value=True, out_reflection=True, **kwargs): """ Defines the *Sony S-Log3* log decoding curve / electro-optical transfer function. Parameters ---------- y : numeric or array_like Non-linear *Sony S-Log3* data :math:`y`. bit_depth : int, optional Bit depth used for conversion. in_normalised_code_value : bool, optional Whether the non-linear *Sony S-Log3* data :math:`y` is encoded as normalised code values. out_reflection : bool, optional Whether the light level :math:`x` to a camera is reflection. Other Parameters ---------------- \\**kwargs : dict, optional Keywords arguments for deprecation management. Returns ------- numeric or ndarray Reflection or :math:`IRE / 100` input light level :math:`x` to a camera. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``y`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``x`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`SonyCorporationd` Examples -------- >>> log_decoding_SLog3(0.410557184750733) # doctest: +ELLIPSIS 0.1... """ in_normalised_code_value = handle_arguments_deprecation( { 'ArgumentRenamed': [['in_legal', 'in_normalised_code_value']], }, **kwargs).get('in_normalised_code_value', in_normalised_code_value) y = to_domain_1(y) y = y if in_normalised_code_value else full_to_legal(y, bit_depth) x = np.where( y >= 171.2102946929 / 1023, ((10**((y * 1023 - 420) / 261.5)) * (0.18 + 0.01) - 0.01), (y * 1023 - 95) * 0.01125000 / (171.2102946929 - 95), ) if not out_reflection: x = x / 0.9 return as_float(from_range_1(x))
def log_encoding_CanonLog(x, bit_depth=10, out_normalised_code_value=True, in_reflection=True, **kwargs): """ Defines the *Canon Log* log encoding curve / opto-electronic transfer function. Parameters ---------- x : numeric or array_like Linear data :math:`x`. bit_depth : int, optional Bit depth used for conversion. out_normalised_code_value : bool, optional Whether the *Canon Log* non-linear data is encoded as normalised code values. in_reflection : bool, optional Whether the light level :math:`x` to a camera is reflection. Other Parameters ---------------- \\**kwargs : dict, optional Keywords arguments for deprecation management. Returns ------- numeric or ndarray *Canon Log* non-linear data. References ---------- :cite:`Thorpe2012a` Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``x`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``clog`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ Examples -------- >>> log_encoding_CanonLog(0.18) * 100 # doctest: +ELLIPSIS 34.3389651... The values of *Table 2 Canon-Log Code Values* table in :cite:`Thorpe2012a` are obtained as follows: >>> x = np.array([0, 2, 18, 90, 720]) / 100 >>> np.around(log_encoding_CanonLog(x) * (2 ** 10 - 1)).astype(np.int) array([ 128, 169, 351, 614, 1016]) >>> np.around(log_encoding_CanonLog(x, 10, False) * 100, 1) array([ 7.3, 12. , 32.8, 62.7, 108.7]) """ out_normalised_code_value = handle_arguments_deprecation( { 'ArgumentRenamed': [['out_legal', 'out_normalised_code_value']], }, **kwargs).get('out_normalised_code_value', out_normalised_code_value) x = to_domain_1(x) if in_reflection: x = x / 0.9 with domain_range_scale('ignore'): clog = np.where( x < log_decoding_CanonLog(0.0730597, bit_depth, False), -(0.529136 * (np.log10(-x * 10.1596 + 1)) - 0.0730597), 0.529136 * np.log10(10.1596 * x + 1) + 0.0730597, ) clog = (full_to_legal(clog, bit_depth) if out_normalised_code_value else clog) return as_float(from_range_1(clog))
def log_encoding_CanonLog2( x: FloatingOrArrayLike, bit_depth: Integer = 10, out_normalised_code_value: Boolean = True, in_reflection: Boolean = True, ) -> FloatingOrNDArray: """ Define the *Canon Log 2* log encoding curve / opto-electronic transfer function. Parameters ---------- x Linear data :math:`x`. bit_depth Bit depth used for conversion. out_normalised_code_value Whether the *Canon Log 2* non-linear data is encoded as normalised code values. in_reflection Whether the light level :math:`x` to a camera is reflection. Returns ------- :class:`numpy.floating` or :class:`numpy.ndarray` *Canon Log 2* non-linear data. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``x`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``clog2`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`Canona` Examples -------- >>> log_encoding_CanonLog2(0.18) * 100 # doctest: +ELLIPSIS 39.8254694... """ x = to_domain_1(x) if in_reflection: x = x / 0.9 with domain_range_scale("ignore"): clog2 = np.where( x < log_decoding_CanonLog2(0.035388128, bit_depth, False), -(0.281863093 * (np.log10(-x * 87.09937546 + 1)) - 0.035388128), 0.281863093 * np.log10(x * 87.09937546 + 1) + 0.035388128, ) clog2_cv = (full_to_legal(clog2, bit_depth) if out_normalised_code_value else clog2) return as_float(from_range_1(clog2_cv))
def log_decoding_VLog(V_out, bit_depth=10, in_legal=True, out_reflection=True, constants=VLOG_CONSTANTS): """ 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_legal : bool, optional Whether the non-linear *Panasonic V-Log* data :math:`V_{out}` is encoded in legal range. out_reflection : bool, optional Whether the light level :math`L_{in}` to a camera is reflection. constants : Structure, optional *Panasonic V-Log* constants. 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... """ V_out = to_domain_1(V_out) V_out = V_out if in_legal 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))
def log_encoding_CanonLog( x: FloatingOrArrayLike, bit_depth: Integer = 10, out_normalised_code_value: Boolean = True, in_reflection: Boolean = True, ) -> FloatingOrNDArray: """ Define the *Canon Log* log encoding curve / opto-electronic transfer function. Parameters ---------- x Linear data :math:`x`. bit_depth Bit depth used for conversion. out_normalised_code_value Whether the *Canon Log* non-linear data is encoded as normalised code values. in_reflection Whether the light level :math:`x` to a camera is reflection. Returns ------- :class:`numpy.floating` or :class:`numpy.ndarray` *Canon Log* non-linear data. References ---------- :cite:`Thorpe2012a` Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``x`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``clog`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ Examples -------- >>> log_encoding_CanonLog(0.18) * 100 # doctest: +ELLIPSIS 34.3389651... The values of *Table 2 Canon-Log Code Values* table in :cite:`Thorpe2012a` are obtained as follows: >>> x = np.array([0, 2, 18, 90, 720]) / 100 >>> np.around(log_encoding_CanonLog(x) * (2 ** 10 - 1)).astype(np.int) array([ 128, 169, 351, 614, 1016]) >>> np.around(log_encoding_CanonLog(x, 10, False) * 100, 1) array([ 7.3, 12. , 32.8, 62.7, 108.7]) """ x = to_domain_1(x) if in_reflection: x = x / 0.9 with domain_range_scale("ignore"): clog = np.where( x < log_decoding_CanonLog(0.0730597, bit_depth, False), -(0.529136 * (np.log10(-x * 10.1596 + 1)) - 0.0730597), 0.529136 * np.log10(10.1596 * x + 1) + 0.0730597, ) clog_cv = (full_to_legal(clog, bit_depth) if out_normalised_code_value else clog) return as_float(from_range_1(clog_cv))