def test_nan_legal_to_full(self): """ Tests :func:`colour.models.rgb.transfer_functions.common.legal_to_full` definition nan support. """ legal_to_full(np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]), 10)
def test_nan_legal_to_full(self): """ Tests :func:`colour.models.rgb.transfer_functions.common.legal_to_full` definition nan support. """ legal_to_full(np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]), 10)
def test_n_dimensional_legal_to_full(self): """ Tests :func:`colour.models.rgb.transfer_functions.common.legal_to_full` definition n-dimensional arrays support. """ CV_l = 0.918866080156403 CV_f = 1.0 np.testing.assert_almost_equal(legal_to_full(CV_l, 10), CV_f, decimal=7) CV_l = np.tile(CV_l, 6) CV_f = np.tile(CV_f, 6) np.testing.assert_almost_equal(legal_to_full(CV_l, 10), CV_f, decimal=7) CV_l = np.reshape(CV_l, (2, 3)) CV_f = np.reshape(CV_f, (2, 3)) np.testing.assert_almost_equal(legal_to_full(CV_l, 10), CV_f, decimal=7) CV_l = np.reshape(CV_l, (2, 3, 1)) CV_f = np.reshape(CV_f, (2, 3, 1)) np.testing.assert_almost_equal(legal_to_full(CV_l, 10), CV_f, decimal=7)
def log_decoding_SLog(y, bit_depth=10, in_legal=True, out_reflection=True): """ Defines the *Sony S-Log* log decoding curve / electro-optical transfer function. Parameters ---------- y : numeric or array_like Non-linear *Sony S-Log* data :math:`y`. bit_depth : int, optional Bit depth used for conversion. in_legal : bool, optional Whether the non-linear *Sony S-Log* 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:`SonyCorporation2012a` Examples -------- >>> log_decoding_SLog(0.384970815928670) # doctest: +ELLIPSIS 0.1... >>> log_decoding_SLog(0.376512722254600, in_legal=False) ... # doctest: +ELLIPSIS 0.1... >>> log_decoding_SLog(0.370820482371268, out_reflection=False) ... # doctest: +ELLIPSIS 0.1... """ y = np.asarray(y) x = legal_to_full(y, bit_depth) if in_legal else y x = np.where(y >= log_encoding_SLog(0.0, bit_depth, in_legal), 10**((x - 0.616596 - 0.03) / 0.432699) - 0.037584, (x - 0.030001222851889303) / 5.0) if out_reflection: x = x * 0.9 return as_numeric(x)
def test_n_dimensional_legal_to_full(self): """ Tests :func:`colour.models.rgb.transfer_functions.common.legal_to_full` definition n-dimensional arrays support. """ CV_l = 0.918866080156403 CV_f = legal_to_full(CV_l, 10) CV_l = np.tile(CV_l, 6) CV_f = np.tile(CV_f, 6) np.testing.assert_almost_equal( legal_to_full(CV_l, 10), CV_f, decimal=7) CV_l = np.reshape(CV_l, (2, 3)) CV_f = np.reshape(CV_f, (2, 3)) np.testing.assert_almost_equal( legal_to_full(CV_l, 10), CV_f, decimal=7) CV_l = np.reshape(CV_l, (2, 3, 1)) CV_f = np.reshape(CV_f, (2, 3, 1)) np.testing.assert_almost_equal( legal_to_full(CV_l, 10), CV_f, decimal=7)
def log_encoding_SLog3(x, bit_depth=10, out_legal=True, in_reflection=True): """ Defines the *Sony S-Log3* 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-Log3* 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-Log3* data :math:`y`. References ---------- - :cite:`SonyCorporationd` Examples -------- >>> log_encoding_SLog3(0.18) # doctest: +ELLIPSIS 0.4105571... >>> log_encoding_SLog3(0.18, out_legal=False) # doctest: +ELLIPSIS 0.4063926... >>> log_encoding_SLog3(0.18, in_reflection=False) # doctest: +ELLIPSIS 0.3995079... """ x = np.asarray(x) if not in_reflection: x = x * 0.9 y = np.where(x >= 0.01125000, (420 + np.log10( (x + 0.01) / (0.18 + 0.01)) * 261.5) / 1023, (x * (171.2102946929 - 95) / 0.01125000 + 95) / 1023) y = y if out_legal else legal_to_full(y, bit_depth) return as_numeric(y)
def log_decoding_CanonLog3(clog3, bit_depth=10, in_legal=True, out_reflection=True): """ Defines the *Canon Log 3* log decoding curve / electro-optical transfer function. Parameters ---------- clog3 : numeric or array_like *Canon Log 3* non-linear data. bit_depth : int, optional Bit depth used for conversion. in_legal : bool, optional Whether the *Canon Log 3* non-linear data is encoded in legal range. out_reflection : bool, optional Whether the light level :math:`x` to a camera is reflection. Returns ------- numeric or ndarray Linear data :math:`x`. References ---------- - :cite:`Canona` Examples -------- >>> log_decoding_CanonLog3(34.338936938868677 / 100) # doctest: +ELLIPSIS 0.1800000... """ clog3 = np.asarray(clog3) clog3 = legal_to_full(clog3, bit_depth) if in_legal else clog3 x = np.select( (clog3 < 0.04076162, clog3 <= 0.105357102, clog3 > 0.105357102), (-(10 ** ((0.07623209 - clog3) / 0.42889912) - 1) / 14.98325, (clog3 - 0.073059361) / 2.3069815, (10 ** ((clog3 - 0.069886632) / 0.42889912) - 1) / 14.98325)) if out_reflection: x = x * 0.9 return as_numeric(x)
def log_decoding_CanonLog2(clog2, bit_depth=10, in_legal=True, out_reflection=True): """ Defines the *Canon Log 2* log decoding curve / electro-optical transfer function. Parameters ---------- clog2 : numeric or array_like *Canon Log 2* non-linear data. bit_depth : int, optional Bit depth used for conversion. in_legal : bool, optional Whether the *Canon Log 2* non-linear data is encoded in legal range. out_reflection : bool, optional Whether the light level :math:`x` to a camera is reflection. Returns ------- numeric or ndarray Linear data :math:`x`. References ---------- - :cite:`Canona` Examples -------- >>> log_decoding_CanonLog2(39.825469498316735 / 100) # doctest: +ELLIPSIS 0.1799999... """ clog2 = np.asarray(clog2) clog2 = legal_to_full(clog2, bit_depth) if in_legal else clog2 x = np.where(clog2 < 0.035388128, -(10 ** ((0.035388128 - clog2) / 0.281863093) - 1) / 87.09937546, (10 ** ((clog2 - 0.035388128) / 0.281863093) - 1) / 87.09937546) if out_reflection: x = x * 0.9 return as_numeric(x)
def log_encoding_VLog(L_in, bit_depth=10, out_legal=True, in_reflection=True): """ 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_legal : bool, optional Whether the non-linear *Panasonic V-Log* data :math:`V_{out}` is encoded in legal range. in_reflection : bool, optional Whether the light level :math`L_{in}` to a camera is reflection. Returns ------- numeric or ndarray Non-linear data :math:`V_{out}`. References ---------- - :cite:`Panasonic2014a` Examples -------- >>> log_encoding_VLog(0.18) # doctest: +ELLIPSIS 0.4233114... """ L_in = np.asarray(L_in) if not in_reflection: L_in = L_in * 0.9 cut1 = VLOG_CONSTANTS.cut1 b = VLOG_CONSTANTS.b c = VLOG_CONSTANTS.c d = VLOG_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_legal else legal_to_full(V_out, bit_depth) return as_numeric(V_out)
def log_decoding_CanonLog(clog, bit_depth=10, in_legal=True, out_reflection=True): """ Defines the *Canon Log* log decoding curve / electro-optical transfer function. Parameters ---------- clog : numeric or array_like *Canon Log* non-linear data. bit_depth : int, optional Bit depth used for conversion. in_legal : bool, optional Whether the *Canon Log* non-linear data is encoded in legal range. out_reflection : bool, optional Whether the light level :math:`x` to a camera is reflection. Returns ------- numeric or ndarray Linear data :math:`x`. References ---------- - :cite:`Thorpe2012a` Examples -------- >>> log_decoding_CanonLog(34.338965172606912 / 100) # doctest: +ELLIPSIS 0.17999999... """ clog = np.asarray(clog) clog = legal_to_full(clog, bit_depth) if in_legal else clog x = np.where(clog < 0.0730597, -(10 ** ((0.0730597 - clog) / 0.529136) - 1) / 10.1596, (10 ** ((clog - 0.0730597) / 0.529136) - 1) / 10.1596) if out_reflection: x = x * 0.9 return as_numeric(x)
def test_legal_to_full(self): """ Tests :func:`colour.models.rgb.transfer_functions.common.legal_to_full` definition. """ self.assertAlmostEqual(legal_to_full(64 / 1023), 0.0) self.assertAlmostEqual(legal_to_full(940 / 1023), 1.0) self.assertAlmostEqual(legal_to_full(64 / 1023, out_int=True), 0) self.assertAlmostEqual(legal_to_full(940 / 1023, out_int=True), 1023) self.assertAlmostEqual(legal_to_full(64, in_int=True), 0.0) self.assertAlmostEqual(legal_to_full(940, in_int=True), 1.0) self.assertAlmostEqual(legal_to_full(64, in_int=True, out_int=True), 0) self.assertAlmostEqual( legal_to_full(940, in_int=True, out_int=True), 1023)
def test_legal_to_full(self): """ Tests :func:`colour.models.rgb.transfer_functions.common.legal_to_full` definition. """ self.assertAlmostEqual(legal_to_full(64 / 1023), 0.0) self.assertAlmostEqual(legal_to_full(940 / 1023), 1.0) self.assertAlmostEqual(legal_to_full(64 / 1023, out_int=True), 0) self.assertAlmostEqual(legal_to_full(940 / 1023, out_int=True), 1023) self.assertAlmostEqual(legal_to_full(64, in_int=True), 0.0) self.assertAlmostEqual(legal_to_full(940, in_int=True), 1.0) self.assertAlmostEqual(legal_to_full(64, in_int=True, out_int=True), 0) self.assertAlmostEqual(legal_to_full(940, in_int=True, out_int=True), 1023)
def log_encoding_VLog( L_in: FloatingOrArrayLike, bit_depth: Integer = 10, out_normalised_code_value: Boolean = True, in_reflection: Boolean = True, constants: Structure = CONSTANTS_VLOG, ) -> FloatingOrNDArray: """ Define the *Panasonic V-Log* log encoding curve / opto-electronic transfer function. Parameters ---------- L_in Linear reflection data :math`L_{in}`. bit_depth Bit depth used for conversion. out_normalised_code_value Whether the non-linear *Panasonic V-Log* data :math:`V_{out}` is encoded as normalised code values. in_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` 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]. """ 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_cv = (V_out if out_normalised_code_value else legal_to_full( V_out, bit_depth)) return as_float(from_range_1(V_out_cv))
def log_encoding_FLog(in_r, bit_depth=10, out_normalised_code_value=True, in_reflection=True, constants=CONSTANTS_FLOG): """ Defines the *Fujifilm F-Log* log encoding curve / opto-electronic transfer function. Parameters ---------- in_r : numeric or array_like Linear reflection data :math`in`. bit_depth : int, optional Bit depth used for conversion. out_normalised_code_value : bool, optional Whether the non-linear *Fujifilm F-Log* data :math:`out` is encoded as normalised code values. in_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 Non-linear data :math:`out`. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``in_r`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``out_r`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`Fujifilm2016` Examples -------- >>> log_encoding_FLog(0.18) # doctest: +ELLIPSIS 0.4593184... The values of *2-2. F-Log Code Value* table in :cite:`Fujifilm2016` are obtained as follows: >>> x = np.array([0, 18, 90]) / 100 >>> np.around(log_encoding_FLog(x, 10, False) * 100, 1) array([ 3.5, 46.3, 73.2]) >>> np.around(log_encoding_FLog(x) * (2 ** 10 - 1)).astype(np.int) array([ 95, 470, 705]) """ in_r = to_domain_1(in_r) if not in_reflection: in_r = in_r * 0.9 cut1 = constants.cut1 a = constants.a b = constants.b c = constants.c d = constants.d e = constants.e f = constants.f out_r = np.where( in_r < cut1, e * in_r + f, c * np.log10(a * in_r + b) + d, ) out_r = (out_r if out_normalised_code_value else legal_to_full( out_r, bit_depth)) return as_float(from_range_1(out_r))
def log_decoding_CanonLog3(clog3, bit_depth=10, in_legal=True, out_reflection=True): """ Defines the *Canon Log 3* log decoding curve / electro-optical transfer function. Parameters ---------- clog3 : numeric or array_like *Canon Log 3* non-linear data. bit_depth : int, optional Bit depth used for conversion. in_legal : bool, optional Whether the *Canon Log 3* non-linear data is encoded in legal range. out_reflection : bool, optional Whether the light level :math:`x` to a camera is reflection. Returns ------- numeric or ndarray Linear data :math:`x`. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``clog3`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``x`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`Canona` Examples -------- >>> log_decoding_CanonLog3(34.338936938868677 / 100) # doctest: +ELLIPSIS 0.1800000... """ clog3 = to_domain_1(clog3) clog3 = legal_to_full(clog3, bit_depth) if in_legal else clog3 x = np.select( (clog3 < 0.04076162, clog3 <= 0.105357102, clog3 > 0.105357102), (-(10 ** ((0.07623209 - clog3) / 0.42889912) - 1) / 14.98325, (clog3 - 0.073059361) / 2.3069815, (10 ** ((clog3 - 0.069886632) / 0.42889912) - 1) / 14.98325)) if out_reflection: x = x * 0.9 return as_float(from_range_1(x))
def log_encoding_NLog( in_r: FloatingOrArrayLike, bit_depth: Integer = 10, out_normalised_code_value: Boolean = True, in_reflection: Boolean = True, constants: Structure = NLOG_CONSTANTS, ) -> FloatingOrNDArray: """ Define the *Nikon N-Log* log encoding curve / opto-electronic transfer function. Parameters ---------- in_r Linear reflection data :math`in`. bit_depth Bit depth used for conversion. out_normalised_code_value Whether the non-linear *Nikon N-Log* data :math:`out` is encoded as normalised code values. in_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` Non-linear data :math:`out`. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``in_r`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``out_r`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`Nikon2018` Examples -------- >>> log_encoding_NLog(0.18) # doctest: +ELLIPSIS 0.3636677... """ in_r = to_domain_1(in_r) if not in_reflection: in_r = in_r * 0.9 cut1 = constants.cut1 a = constants.a b = constants.b c = constants.c d = constants.d out_r = np.where( in_r < cut1, a * spow(in_r + b, 1 / 3), c * np.log(in_r) + d, ) out_r_cv = (out_r if out_normalised_code_value else legal_to_full( out_r, bit_depth)) return as_float(from_range_1(out_r_cv))
def log_encoding_VLog(L_in, bit_depth=10, out_legal=True, in_reflection=True, constants=VLOG_CONSTANTS): """ 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_legal : bool, optional Whether the non-linear *Panasonic V-Log* data :math:`V_{out}` is encoded in legal range. in_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 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... """ 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_legal else legal_to_full(V_out, bit_depth) return as_float(from_range_1(V_out))
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))
def log_decoding_SLog( y: FloatingOrArrayLike, bit_depth: Integer = 10, in_normalised_code_value: Boolean = True, out_reflection: Boolean = True, ) -> FloatingOrNDArray: """ Define the *Sony S-Log* log decoding curve / electro-optical transfer function. Parameters ---------- y Non-linear *Sony S-Log* data :math:`y`. bit_depth Bit depth used for conversion. in_normalised_code_value Whether the non-linear *Sony S-Log* 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:`SonyCorporation2012a` Examples -------- >>> log_decoding_SLog(0.384970815928670) # doctest: +ELLIPSIS 0.1... """ y = to_domain_1(y) x = legal_to_full(y, bit_depth) if in_normalised_code_value else y with domain_range_scale("ignore"): x = np.where( y >= log_encoding_SLog(0.0, bit_depth, in_normalised_code_value), 10**((x - 0.616596 - 0.03) / 0.432699) - 0.037584, (x - 0.030001222851889303) / 5.0, ) if out_reflection: x = x * 0.9 return as_float(from_range_1(x))
def log_encoding_VLog(L_in, bit_depth=10, out_legal=True, in_reflection=True, constants=VLOG_CONSTANTS): """ 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_legal : bool, optional Whether the non-linear *Panasonic V-Log* data :math:`V_{out}` is encoded in legal range. in_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 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... """ 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_legal else legal_to_full(V_out, bit_depth) return as_float(from_range_1(V_out))
def log_decoding_CanonLog2(clog2, bit_depth=10, in_legal=True, out_reflection=True): """ Defines the *Canon Log 2* log decoding curve / electro-optical transfer function. Parameters ---------- clog2 : numeric or array_like *Canon Log 2* non-linear data. bit_depth : int, optional Bit depth used for conversion. in_legal : bool, optional Whether the *Canon Log 2* non-linear data is encoded in legal range. out_reflection : bool, optional Whether the light level :math:`x` to a camera is reflection. Returns ------- numeric or ndarray Linear data :math:`x`. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``clog2`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``x`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`Canona` Examples -------- >>> log_decoding_CanonLog2(39.825469498316735 / 100) # doctest: +ELLIPSIS 0.1799999... """ clog2 = to_domain_1(clog2) clog2 = legal_to_full(clog2, bit_depth) if in_legal else clog2 x = np.where( clog2 < 0.035388128, -(10 ** ((0.035388128 - clog2) / 0.281863093) - 1) / 87.09937546, (10 ** ((clog2 - 0.035388128) / 0.281863093) - 1) / 87.09937546, ) if out_reflection: x = x * 0.9 return as_float(from_range_1(x))
def log_decoding_CanonLog3(clog3, bit_depth=10, in_normalised_code_value=True, out_reflection=True, **kwargs): """ Defines the *Canon Log 3* log decoding curve / electro-optical transfer function. Parameters ---------- clog3 : numeric or array_like *Canon Log 3* non-linear data. bit_depth : int, optional Bit depth used for conversion. in_normalised_code_value : bool, optional Whether the *Canon Log 3* non-linear data is encoded with 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 Linear data :math:`x`. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``clog3`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``x`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`Canona` Examples -------- >>> log_decoding_CanonLog3(34.338936938868677 / 100) # doctest: +ELLIPSIS 0.1800000... """ in_normalised_code_value = handle_arguments_deprecation( { 'ArgumentRenamed': [['in_legal', 'in_normalised_code_value']], }, **kwargs).get('in_normalised_code_value', in_normalised_code_value) clog3 = to_domain_1(clog3) clog3 = (legal_to_full(clog3, bit_depth) if in_normalised_code_value else clog3) x = np.select( (clog3 < 0.04076162, clog3 <= 0.105357102, clog3 > 0.105357102), (-(10**((0.07623209 - clog3) / 0.42889912) - 1) / 14.98325, (clog3 - 0.073059361) / 2.3069815, (10**((clog3 - 0.069886632) / 0.42889912) - 1) / 14.98325)) if out_reflection: x = x * 0.9 return as_float(from_range_1(x))
def log_decoding_CanonLog2( clog2: FloatingOrArrayLike, bit_depth: Integer = 10, in_normalised_code_value: Boolean = True, out_reflection: Boolean = True, ) -> FloatingOrNDArray: """ Define the *Canon Log 2* log decoding curve / electro-optical transfer function. Parameters ---------- clog2 *Canon Log 2* non-linear data. bit_depth Bit depth used for conversion. in_normalised_code_value Whether the *Canon Log 2* non-linear data is encoded with normalised code values. out_reflection Whether the light level :math:`x` to a camera is reflection. Returns ------- :class:`numpy.floating` or :class:`numpy.ndarray` Linear data :math:`x`. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``clog2`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``x`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`Canona` Examples -------- >>> log_decoding_CanonLog2(39.825469498316735 / 100) # doctest: +ELLIPSIS 0.1799999... """ clog2 = to_domain_1(clog2) clog2 = (legal_to_full(clog2, bit_depth) if in_normalised_code_value else clog2) x = np.where( clog2 < 0.035388128, -(10**((0.035388128 - clog2) / 0.281863093) - 1) / 87.09937546, (10**((clog2 - 0.035388128) / 0.281863093) - 1) / 87.09937546, ) if out_reflection: x = x * 0.9 return as_float(from_range_1(x))
def log_encoding_SLog3(x, bit_depth=10, out_normalised_code_value=True, in_reflection=True, **kwargs): """ Defines the *Sony S-Log3* 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-Log3* 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-Log3* 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:`SonyCorporationd` Examples -------- >>> log_encoding_SLog3(0.18) # doctest: +ELLIPSIS 0.4105571... The values of *S-Log3 10bit code values (18%, 90%)* table in :cite:`SonyCorporationd` are obtained as follows: >>> x = np.array([0, 18, 90]) / 100 >>> np.around(log_encoding_SLog3(x, 10, False) * 100).astype(np.int) array([ 4, 41, 61]) >>> np.around(log_encoding_SLog3(x) * (2 ** 10 - 1)).astype(np.int) array([ 95, 420, 598]) """ 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 not in_reflection: x = x * 0.9 y = np.where( x >= 0.01125000, (420 + np.log10((x + 0.01) / (0.18 + 0.01)) * 261.5) / 1023, (x * (171.2102946929 - 95) / 0.01125000 + 95) / 1023, ) y = y if out_normalised_code_value else legal_to_full(y, bit_depth) return as_float(from_range_1(y))
def log_encoding_SLog3( x: FloatingOrArrayLike, bit_depth: Integer = 10, out_normalised_code_value: Boolean = True, in_reflection: Boolean = True, ) -> FloatingOrNDArray: """ Define the *Sony S-Log3* 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-Log3* 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-Log3* 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:`SonyCorporationd` Examples -------- >>> log_encoding_SLog3(0.18) # doctest: +ELLIPSIS 0.4105571... The values of *S-Log3 10bit code values (18%, 90%)* table in :cite:`SonyCorporationd` are obtained as follows: >>> x = np.array([0, 18, 90]) / 100 >>> np.around(log_encoding_SLog3(x, 10, False) * 100).astype(np.int) array([ 4, 41, 61]) >>> np.around(log_encoding_SLog3(x) * (2 ** 10 - 1)).astype(np.int) array([ 95, 420, 598]) """ x = to_domain_1(x) if not in_reflection: x = x * 0.9 y = np.where( x >= 0.01125000, (420 + np.log10((x + 0.01) / (0.18 + 0.01)) * 261.5) / 1023, (x * (171.2102946929 - 95) / 0.01125000 + 95) / 1023, ) y_cv = y if out_normalised_code_value else legal_to_full(y, bit_depth) return as_float(from_range_1(y_cv))
def log_decoding_SLog(y, bit_depth=10, in_legal=True, out_reflection=True): """ Defines the *Sony S-Log* log decoding curve / electro-optical transfer function. Parameters ---------- y : numeric or array_like Non-linear *Sony S-Log* data :math:`y`. bit_depth : int, optional Bit depth used for conversion. in_legal : bool, optional Whether the non-linear *Sony S-Log* 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:`SonyCorporation2012a` Examples -------- >>> log_decoding_SLog(0.384970815928670) # doctest: +ELLIPSIS 0.1... >>> log_decoding_SLog(0.376512722254600, in_legal=False) ... # doctest: +ELLIPSIS 0.1... >>> log_decoding_SLog(0.370820482371268, out_reflection=False) ... # doctest: +ELLIPSIS 0.1... """ y = to_domain_1(y) x = legal_to_full(y, bit_depth) if in_legal else y with domain_range_scale('ignore'): x = np.where( y >= log_encoding_SLog(0.0, bit_depth, in_legal), 10 ** ((x - 0.616596 - 0.03) / 0.432699) - 0.037584, (x - 0.030001222851889303) / 5.0, ) if out_reflection: x = x * 0.9 return as_float(from_range_1(x))
def log_encoding_SLog3(x, bit_depth=10, out_legal=True, in_reflection=True): """ Defines the *Sony S-Log3* 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-Log3* 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-Log3* 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:`SonyCorporationd` Examples -------- >>> log_encoding_SLog3(0.18) # doctest: +ELLIPSIS 0.4105571... >>> log_encoding_SLog3(0.18, out_legal=False) # doctest: +ELLIPSIS 0.4063926... >>> log_encoding_SLog3(0.18, in_reflection=False) # doctest: +ELLIPSIS 0.3995079... """ x = to_domain_1(x) if not in_reflection: x = x * 0.9 y = np.where( x >= 0.01125000, (420 + np.log10((x + 0.01) / (0.18 + 0.01)) * 261.5) / 1023, (x * (171.2102946929 - 95) / 0.01125000 + 95) / 1023, ) y = y if out_legal else legal_to_full(y, bit_depth) return as_float(from_range_1(y))
def log_decoding_SLog(y, bit_depth=10, in_normalised_code_value=True, out_reflection=True, **kwargs): """ Defines the *Sony S-Log* log decoding curve / electro-optical transfer function. Parameters ---------- y : numeric or array_like Non-linear *Sony S-Log* data :math:`y`. bit_depth : int, optional Bit depth used for conversion. in_normalised_code_value : bool, optional Whether the non-linear *Sony S-Log* 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:`SonyCorporation2012a` Examples -------- >>> log_decoding_SLog(0.384970815928670) # 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) x = legal_to_full(y, bit_depth) if in_normalised_code_value else y with domain_range_scale('ignore'): x = np.where( y >= log_encoding_SLog(0.0, bit_depth, in_normalised_code_value), 10**((x - 0.616596 - 0.03) / 0.432699) - 0.037584, (x - 0.030001222851889303) / 5.0, ) if out_reflection: x = x * 0.9 return as_float(from_range_1(x))
def log_decoding_CanonLog(clog, bit_depth=10, in_normalised_code_value=True, out_reflection=True, **kwargs): """ Defines the *Canon Log* log decoding curve / electro-optical transfer function. Parameters ---------- clog : numeric or array_like *Canon Log* non-linear data. bit_depth : int, optional Bit depth used for conversion. in_normalised_code_value : bool, optional Whether the *Canon Log* non-linear data is encoded with 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 Linear data :math:`x`. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``clog`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``x`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`Thorpe2012a` Examples -------- >>> log_decoding_CanonLog(34.338965172606912 / 100) # doctest: +ELLIPSIS 0.17999999... """ in_normalised_code_value = handle_arguments_deprecation( { 'ArgumentRenamed': [['in_legal', 'in_normalised_code_value']], }, **kwargs).get('in_normalised_code_value', in_normalised_code_value) clog = to_domain_1(clog) clog = (legal_to_full(clog, bit_depth) if in_normalised_code_value else clog) x = np.where( clog < 0.0730597, -(10**((0.0730597 - clog) / 0.529136) - 1) / 10.1596, (10**((clog - 0.0730597) / 0.529136) - 1) / 10.1596, ) if out_reflection: x = x * 0.9 return as_float(from_range_1(x))
def log_decoding_CanonLog( clog: FloatingOrArrayLike, bit_depth: Integer = 10, in_normalised_code_value: Boolean = True, out_reflection: Boolean = True, ) -> FloatingOrNDArray: """ Define the *Canon Log* log decoding curve / electro-optical transfer function. Parameters ---------- clog *Canon Log* non-linear data. bit_depth Bit depth used for conversion. in_normalised_code_value Whether the *Canon Log* non-linear data is encoded with normalised code values. out_reflection Whether the light level :math:`x` to a camera is reflection. Returns ------- :class:`numpy.floating` or :class:`numpy.ndarray` Linear data :math:`x`. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``clog`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``x`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`Thorpe2012a` Examples -------- >>> log_decoding_CanonLog(34.338965172606912 / 100) # doctest: +ELLIPSIS 0.17999999... """ clog = to_domain_1(clog) clog = legal_to_full(clog, bit_depth) if in_normalised_code_value else clog x = np.where( clog < 0.0730597, -(10**((0.0730597 - clog) / 0.529136) - 1) / 10.1596, (10**((clog - 0.0730597) / 0.529136) - 1) / 10.1596, ) if out_reflection: x = x * 0.9 return as_float(from_range_1(x))
def log_decoding_CanonLog2(clog2, bit_depth=10, in_normalised_code_value=True, out_reflection=True, **kwargs): """ Defines the *Canon Log 2* log decoding curve / electro-optical transfer function. Parameters ---------- clog2 : numeric or array_like *Canon Log 2* non-linear data. bit_depth : int, optional Bit depth used for conversion. in_normalised_code_value : bool, optional Whether the *Canon Log 2* non-linear data is encoded with 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 Linear data :math:`x`. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``clog2`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``x`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`Canona` Examples -------- >>> log_decoding_CanonLog2(39.825469498316735 / 100) # 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) clog2 = to_domain_1(clog2) clog2 = (legal_to_full(clog2, bit_depth) if in_normalised_code_value else clog2) x = np.where( clog2 < 0.035388128, -(10**((0.035388128 - clog2) / 0.281863093) - 1) / 87.09937546, (10**((clog2 - 0.035388128) / 0.281863093) - 1) / 87.09937546, ) if out_reflection: x = x * 0.9 return as_float(from_range_1(x))
def log_decoding_CanonLog3( clog3: FloatingOrArrayLike, bit_depth: Integer = 10, in_normalised_code_value: Boolean = True, out_reflection: Boolean = True, ) -> FloatingOrNDArray: """ Define the *Canon Log 3* log decoding curve / electro-optical transfer function. Parameters ---------- clog3 *Canon Log 3* non-linear data. bit_depth Bit depth used for conversion. in_normalised_code_value Whether the *Canon Log 3* non-linear data is encoded with normalised code values. out_reflection Whether the light level :math:`x` to a camera is reflection. Returns ------- :class:`numpy.floating` or :class:`numpy.ndarray` Linear data :math:`x`. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``clog3`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``x`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`Canona` Examples -------- >>> log_decoding_CanonLog3(34.338936938868677 / 100) # doctest: +ELLIPSIS 0.1800000... """ clog3 = to_domain_1(clog3) clog3 = (legal_to_full(clog3, bit_depth) if in_normalised_code_value else clog3) x = np.select( (clog3 < 0.04076162, clog3 <= 0.105357102, clog3 > 0.105357102), ( -(10**((0.07623209 - clog3) / 0.42889912) - 1) / 14.98325, (clog3 - 0.073059361) / 2.3069815, (10**((clog3 - 0.069886632) / 0.42889912) - 1) / 14.98325, ), ) if out_reflection: x = x * 0.9 return as_float(from_range_1(x))
def log_decoding_CanonLog(clog, bit_depth=10, in_legal=True, out_reflection=True): """ Defines the *Canon Log* log decoding curve / electro-optical transfer function. Parameters ---------- clog : numeric or array_like *Canon Log* non-linear data. bit_depth : int, optional Bit depth used for conversion. in_legal : bool, optional Whether the *Canon Log* non-linear data is encoded in legal range. out_reflection : bool, optional Whether the light level :math:`x` to a camera is reflection. Returns ------- numeric or ndarray Linear data :math:`x`. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``clog`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``x`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`Thorpe2012a` Examples -------- >>> log_decoding_CanonLog(34.338965172606912 / 100) # doctest: +ELLIPSIS 0.17999999... """ clog = to_domain_1(clog) clog = legal_to_full(clog, bit_depth) if in_legal else clog x = np.where( clog < 0.0730597, -(10 ** ((0.0730597 - clog) / 0.529136) - 1) / 10.1596, (10 ** ((clog - 0.0730597) / 0.529136) - 1) / 10.1596, ) if out_reflection: x = x * 0.9 return as_float(from_range_1(x))