def test_filter_kwargs(self): """ Tests :func:`colour.utilities.common.filter_kwargs` definition. """ def fn_a(a): """ :func:`filter_kwargs` unit tests :func:`fn_a` definition. """ return a def fn_b(a, b=0): """ :func:`filter_kwargs` unit tests :func:`fn_b` definition. """ return a, b def fn_c(a, b=0, c=0): """ :func:`filter_kwargs` unit tests :func:`fn_c` definition. """ return a, b, c self.assertEqual(1, fn_a(1, **filter_kwargs(fn_a, b=2, c=3))) self.assertTupleEqual((1, 2), fn_b(1, **filter_kwargs(fn_b, b=2, c=3))) self.assertTupleEqual((1, 2, 3), fn_c(1, **filter_kwargs(fn_c, b=2, c=3)))
def test_filter_kwargs(self): """ Tests :func:`colour.utilities.common.filter_kwargs` definition. """ def fn_a(a): """ :func:`filter_kwargs` unit tests :func:`fn_a`. """ return a def fn_b(a, b=0): """ :func:`filter_kwargs` unit tests :func:`fn_b`. """ return a, b def fn_c(a, b=0, c=0): """ :func:`filter_kwargs` unit tests :func:`fn_c`. """ return a, b, c self.assertEqual(1, fn_a(1, **filter_kwargs(fn_a, b=2, c=3))) self.assertTupleEqual((1, 2), fn_b(1, **filter_kwargs(fn_b, b=2, c=3))) self.assertTupleEqual((1, 2, 3), fn_c(1, **filter_kwargs(fn_c, b=2, c=3)))
def eotf(value, function='sRGB', **kwargs): """ Decodes :math:`R'G'B'` video component signal value to tristimulus values at the display using given electro-optical transfer function (EOTF / EOCF). Parameters ---------- value : numeric or array_like Value. function : unicode, optional **{'sRGB', 'BT.1886', 'BT.2020', 'BT.709', 'DCI-P3', 'ROMM RGB', 'ProPhoto RGB', 'RIMM RGB', 'ST 2084'}**, Computation function. Other Parameters ---------------- L_B : numeric, optional {:func:`eotf_BT1886`}, Screen luminance for black. L_W : numeric, optional {:func:`eotf_BT1886`}, Screen luminance for white. is_12_bits_system : bool {:func:`eotf_BT2020`}, *BT.709* *alpha* and *beta* constants are used if system is not 12-bit. I_max : numeric, optional {:func:`eotf_ROMMRGB`, :func:`eotf_RIMMRGB`}, Maximum code value: 255, 4095 and 650535 for respectively 8-bit, 12-bit and 16-bit per channel. E_clip : numeric, optional {:func:`eotf_RIMMRGB`}, Maximum exposure level. L_p : numeric, optional {:func:`eotf_ST2084`}, Display peak luminance :math:`cd/m^2`. Returns ------- numeric or ndarray Tristimulus values at the display. Examples -------- >>> eotf(0.461356129500442) # doctest: +ELLIPSIS 0.1... >>> eotf(0.409007728864150, ... function='BT.2020') # doctest: +ELLIPSIS 0.1... >>> eotf( # doctest: +ELLIPSIS ... 0.182011532850008, function='ST 2084', L_p=1000) 0.1... """ function = EOTFS[function] filter_kwargs(function, **kwargs) return function(value, **kwargs)
def luminance(LV, method='CIE 1976', **kwargs): """ Returns the *luminance* :math:`Y` of given *Lightness* :math:`L^*` or given *Munsell* value :math:`V`. Parameters ---------- LV : numeric or array_like *Lightness* :math:`L^*` or *Munsell* value :math:`V`. method : unicode, optional **{'CIE 1976', 'Newhall 1943', 'ASTM D1535-08', 'Fairchild 2010'}**, Computation method. Other Parameters ---------------- Y_n : numeric or array_like, optional {:func:`luminance_CIE1976`}, White reference *luminance* :math:`Y_n`. epsilon : numeric or array_like, optional {:func:`lightness_Fairchild2010`}, :math:`\epsilon` exponent. Returns ------- numeric or array_like *luminance* :math:`Y`. Notes ----- - Input *LV* is in domain [0, 100], [0, 10] or [0, 1] and optional *luminance* :math:`Y_n` is in domain [0, 100]. - Output *luminance* :math:`Y` is in range [0, 100] or [0, math:`\infty`]. Examples -------- >>> luminance(37.98562910) # doctest: +ELLIPSIS array(10.0800000...) >>> luminance(37.98562910, Y_n=100) # doctest: +ELLIPSIS array(10.0800000...) >>> luminance(37.98562910, Y_n=95) # doctest: +ELLIPSIS array(9.5760000...) >>> luminance(3.74629715, method='Newhall 1943') # doctest: +ELLIPSIS 10.4089874... >>> luminance(3.74629715, method='ASTM D1535-08') # doctest: +ELLIPSIS 10.1488096... >>> luminance( ... 24.902290269546651, ... epsilon=1.836, ... method='Fairchild 2010') # doctest: +ELLIPSIS 0.1007999... """ function = LUMINANCE_METHODS[method] filter_kwargs(function, **kwargs) return function(LV, **kwargs)
def delta_E(Lab_1, Lab_2, method='CMC', **kwargs): """ Returns the difference :math:`\Delta E_{ab}` between two given *CIE Lab* colourspace arrays using given method. Parameters ---------- Lab_1 : array_like *CIE Lab* colourspace array 1. Lab_2 : array_like *CIE Lab* colourspace array 2. method : unicode, optional **{'CMC', 'CIE 1976', 'CIE 1994', 'CIE 2000'}**, Computation method. Other Parameters ---------------- textiles : bool, optional {:func:`delta_E_CIE1994`, :func:`delta_E_CIE2000`}, Textiles application specific parametric factors :math:`k_L=2,\ k_C=k_H=1,\ k_1=0.048,\ k_2=0.014` weights are used instead of :math:`k_L=k_C=k_H=1,\ k_1=0.045,\ k_2=0.015`. l : numeric, optional {:func:`delta_E_CIE2000`}, Lightness weighting factor. c : numeric, optional {:func:`delta_E_CIE2000`}, Chroma weighting factor. Returns ------- numeric or ndarray Colour difference :math:`\Delta E_{ab}`. Examples -------- >>> Lab_1 = np.array([100.00000000, 21.57210357, 272.22819350]) >>> Lab_2 = np.array([100.00000000, 426.67945353, 72.39590835]) >>> delta_E(Lab_1, Lab_2) # doctest: +ELLIPSIS 172.7047712... >>> delta_E(Lab_1, Lab_2, method='CIE 1976') # doctest: +ELLIPSIS 451.7133019... >>> delta_E(Lab_1, Lab_2, method='CIE 1994') # doctest: +ELLIPSIS 83.7792255... >>> delta_E( # doctest: +ELLIPSIS ... Lab_1, Lab_2, method='CIE 1994', textiles=False) 83.7792255... >>> delta_E(Lab_1, Lab_2, method='CIE 2000') # doctest: +ELLIPSIS 94.0356490... """ function = DELTA_E_METHODS[method] filter_kwargs(function, **kwargs) return function(Lab_1, Lab_2, **kwargs)
def lightness(Y, method='CIE 1976', **kwargs): """ Returns the *Lightness* :math:`L` using given method. Parameters ---------- Y : numeric or array_like *luminance* :math:`Y`. method : unicode, optional **{'CIE 1976', 'Glasser 1958', 'Wyszecki 1963', 'Fairchild 2010'}**, Computation method. Other Parameters ---------------- Y_n : numeric or array_like, optional {:func:`lightness_CIE1976`}, White reference *luminance* :math:`Y_n`. epsilon : numeric or array_like, optional {:func:`lightness_Fairchild2010`}, :math:`\epsilon` exponent. Returns ------- numeric or array_like *Lightness* :math:`L`. Notes ----- - Input *luminance* :math:`Y` and optional :math:`Y_n` are in domain [0, 100] or [0, :math:`\infty`]. - Output *Lightness* :math:`L` is in range [0, 100]. Examples -------- >>> lightness(10.08) # doctest: +ELLIPSIS array(37.9856290...) >>> lightness(10.08, Y_n=100) # doctest: +ELLIPSIS array(37.9856290...) >>> lightness(10.08, Y_n=95) # doctest: +ELLIPSIS array(38.9165987...) >>> lightness(10.08, method='Glasser 1958') # doctest: +ELLIPSIS 36.2505626... >>> lightness(10.08, method='Wyszecki 1963') # doctest: +ELLIPSIS 37.0041149... >>> lightness( ... 10.08 / 100, ... epsilon=1.836, ... method='Fairchild 2010') # doctest: +ELLIPSIS 24.9022902... """ function = LIGHTNESS_METHODS[method] filter_kwargs(function, **kwargs) return function(Y, **kwargs)
def corresponding_chromaticities_prediction(experiment=1, model='Von Kries', **kwargs): """ Returns the corresponding chromaticities prediction for given chromatic adaptation model. Parameters ---------- experiment : integer, optional {1, 2, 3, 4, 6, 8, 9, 11, 12} *Breneman (1987)* experiment number. model : unicode, optional **{'Von Kries', 'CIE 1994', 'CMCCAT2000', 'Fairchild 1990'}**, Chromatic adaptation model. Other Parameters ---------------- transform : unicode, optional {:func:`corresponding_chromaticities_prediction_VonKries`}, **{'CAT02', 'XYZ Scaling', 'Von Kries', 'Bradford', 'Sharp', 'Fairchild', 'CMCCAT97', 'CMCCAT2000', 'CAT02_BRILL_CAT', 'Bianco', 'Bianco PC'}**, Chromatic adaptation transform. Returns ------- tuple Corresponding chromaticities prediction. Examples -------- >>> from pprint import pprint >>> pr = corresponding_chromaticities_prediction(2, 'CMCCAT2000') >>> pr = [(p.uvp_m, p.uvp_p) for p in pr] >>> pprint(pr) # doctest: +SKIP [((0.207, 0.486), (0.2083210..., 0.4727168...)), ((0.449, 0.511), (0.4459270..., 0.5077735...)), ((0.263, 0.505), (0.2640262..., 0.4955361...)), ((0.322, 0.545), (0.3316884..., 0.5431580...)), ((0.316, 0.537), (0.3222624..., 0.5357624...)), ((0.265, 0.553), (0.2710705..., 0.5501997...)), ((0.221, 0.538), (0.2261826..., 0.5294740...)), ((0.135, 0.532), (0.1439693..., 0.5190984...)), ((0.145, 0.472), (0.1494835..., 0.4556760...)), ((0.163, 0.331), (0.1563172..., 0.3164151...)), ((0.176, 0.431), (0.1763199..., 0.4127589...)), ((0.244, 0.349), (0.2287638..., 0.3499324...))] """ function = CORRESPONDING_CHROMATICITIES_PREDICTION_MODELS[model] filter_kwargs(function, **kwargs) return function(experiment, **kwargs)
def uv_to_CCT(uv, method='Ohno 2013', **kwargs): """ Returns the correlated colour temperature :math:`T_{cp}` and :math:`\Delta_{uv}` from given *CIE UCS* colourspace *uv* chromaticity coordinates using given method. Parameters ---------- uv : array_like *CIE UCS* colourspace *uv* chromaticity coordinates. method : unicode, optional **{'Ohno 2013', 'Robertson 1968'}**, Computation method. Other Parameters ---------------- cmfs : XYZ_ColourMatchingFunctions, optional {:func:`uv_to_CCT_Ohno2013`}, Standard observer colour matching functions. start : numeric, optional {:func:`uv_to_CCT_Ohno2013`}, Temperature range start in kelvins. end : numeric, optional {:func:`uv_to_CCT_Ohno2013`}, Temperature range end in kelvins. count : int, optional {:func:`uv_to_CCT_Ohno2013`}, Temperatures count in the planckian tables. iterations : int, optional {:func:`uv_to_CCT_Ohno2013`}, Number of planckian tables to generate. Returns ------- ndarray Correlated colour temperature :math:`T_{cp}`, :math:`\Delta_{uv}`. Examples -------- >>> from colour import STANDARD_OBSERVERS_CMFS >>> cmfs = STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer'] >>> uv = np.array([0.1978, 0.3122]) >>> uv_to_CCT(uv, cmfs=cmfs) # doctest: +ELLIPSIS array([ 6.5075128...e+03, 3.2233587...e-03]) """ function = UV_TO_CCT_METHODS[method] filter_kwargs(function, **kwargs) return function(uv, **kwargs)
def corresponding_chromaticities_prediction(experiment=1, model='Von Kries', **kwargs): """ Returns the corresponding chromaticities prediction for given chromatic adaptation model. Parameters ---------- experiment : integer, optional {1, 2, 3, 4, 6, 8, 9, 11, 12} Breneman (1987) experiment number. model : unicode, optional **{'Von Kries', 'CIE 1994', 'CMCCAT2000', 'Fairchild 1990'}**, Chromatic adaptation model. \**kwargs : dict, optional Keywords arguments. Returns ------- tuple Corresponding chromaticities prediction. Examples -------- >>> from pprint import pprint >>> pr = corresponding_chromaticities_prediction(2, 'CMCCAT2000') >>> pr = [(p.uvp_m, p.uvp_p) for p in pr] >>> pprint(pr) # doctest: +SKIP [((0.207, 0.486), (0.2083210..., 0.4727168...)), ((0.449, 0.511), (0.4459270..., 0.5077735...)), ((0.263, 0.505), (0.2640262..., 0.4955361...)), ((0.322, 0.545), (0.3316884..., 0.5431580...)), ((0.316, 0.537), (0.3222624..., 0.5357624...)), ((0.265, 0.553), (0.2710705..., 0.5501997...)), ((0.221, 0.538), (0.2261826..., 0.5294740...)), ((0.135, 0.532), (0.1439693..., 0.5190984...)), ((0.145, 0.472), (0.1494835..., 0.4556760...)), ((0.163, 0.331), (0.1563172..., 0.3164151...)), ((0.176, 0.431), (0.1763199..., 0.4127589...)), ((0.244, 0.349), (0.2287638..., 0.3499324...))] """ function = CORRESPONDING_CHROMATICITIES_PREDICTION_MODELS[model] filter_kwargs(function, **kwargs) return function(experiment, **kwargs)
def ootf(value, function='ITU-R BT.2100 PQ', **kwargs): """ Maps relative scene linear light to display linear light using given opto-optical transfer function (OOTF / OOCF). Parameters ---------- value : numeric or array_like Value. function : unicode, optional **{'ITU-R BT.2100 HLG', 'ITU-R BT.2100 PQ'}** Opto-optical transfer function (OOTF / OOCF). Returns ------- numeric or ndarray Luminance of a displayed linear component. Examples -------- >>> ootf(0.1) # doctest: +ELLIPSIS 779.9883608... >>> ootf(0.1, function='ITU-R BT.2100 HLG') # doctest: +ELLIPSIS 63.0957344... """ function = OOTFS[function] return function(value, **filter_kwargs(function, **kwargs))
def substrate_concentration_MichaelisMenten( v: FloatingOrArrayLike, V_max: FloatingOrArrayLike, K_m: FloatingOrArrayLike, method: Union[Literal["Michaelis 1913", "Abebe 2017"], str] = "Michaelis 1913", **kwargs: Any, ) -> FloatingOrNDArray: """ Describe the rate of enzymatic reactions, by relating concentration of a substrate :math:`S` to reaction rate :math:`v` according to given method. Parameters ---------- v Reaction rate :math:`v`. V_max Maximum rate :math:`V_{max}` achieved by the system, at saturating substrate concentration. K_m Substrate concentration :math:`K_m` at which the reaction rate is half of :math:`V_{max}`. method Computation method. Other Parameters ---------------- b_m {:func:`colour.biochemistry.\ substrate_concentration_MichaelisMenten_Abebe2017`}, Bias factor :math:`b_m`. Returns ------- :class:`numpy.floating` or :class:`numpy.ndarray` Concentration of a substrate :math:`S`. References ---------- :cite:`Wikipedia2003d`, :cite:`Abebe2017a` Examples -------- >>> substrate_concentration_MichaelisMenten(0.961538461538461, 2.5, 0.8) ... # doctest: +ELLIPSIS 0.4999999... >>> substrate_concentration_MichaelisMenten( ... 1.036054703688355, 2.5, 0.8, method='Abebe 2017', b_m=0.813) ... # doctest: +ELLIPSIS 0.5000000... """ method = validate_method(method, SUBSTRATE_CONCENTRATION_MICHAELISMENTEN_METHODS) function = SUBSTRATE_CONCENTRATION_MICHAELISMENTEN_METHODS[method] return function(v, V_max, K_m, **filter_kwargs(function, **kwargs))
def oetf(value, function='sRGB', **kwargs): """ Encodes estimated tristimulus values in a scene to :math:`R'G'B'` video component signal value using given opto-electronic transfer function (OETF / OECF). Parameters ---------- value : numeric or array_like Value. function : unicode, optional **{'sRGB', 'ARIB STD-B67', 'DICOM GSDF', 'ITU-R BT.2020', 'ITU-R BT.2100 HLG', 'ITU-R BT.2100 PQ', 'ITU-R BT.601', 'ITU-R BT.709', 'ProPhoto RGB', 'RIMM RGB', 'ROMM RGB', 'SMPTE 240M', 'ST 2084'}**, Opto-electronic transfer function (OETF / OECF). Other Parameters ---------------- E_clip : numeric, optional {:func:`colour.models.oetf_RIMMRGB`}, Maximum exposure level. I_max : numeric, optional {:func:`colour.models.oetf_ROMMRGB`, :func:`colour.models.oetf_RIMMRGB`}, Maximum code value: 255, 4095 and 650535 for respectively 8-bit, 12-bit and 16-bit per channel. L_p : numeric, optional {:func:`colour.models.oetf_ST2084`}, Display peak luminance :math:`cd/m^2`. is_12_bits_system : bool {:func:`colour.models.oetf_BT2020`}, *ITU-R BT.2020* *alpha* and *beta* constants are used if system is not 12-bit. r : numeric, optional {:func:`colour.models.oetf_ARIBSTDB67`}, Video level corresponding to reference white level. Returns ------- numeric or ndarray :math:`R'G'B'` video component signal value. Examples -------- >>> oetf(0.18) # doctest: +ELLIPSIS 0.4613561... >>> oetf(0.18, function='ITU-R BT.2020') # doctest: +ELLIPSIS 0.4090077... >>> oetf(0.18, function='ST 2084', L_p=1000) ... # doctest: +ELLIPSIS 0.1820115... """ function = OETFS[function] return function(value, **filter_kwargs(function, **kwargs))
def eotf_inverse(value, function='ITU-R BT.1886', **kwargs): """ Encodes estimated tristimulus values in a scene to :math:`R'G'B'` video component signal value using given inverse electro-optical transfer function (EOTF / EOCF). Parameters ---------- value : numeric or array_like Value. function : unicode, optional **{'ITU-R BT.1886', 'DCDM', 'DICOM GSDF', 'ITU-R BT.2100 HLG', 'ITU-R BT.2100 PQ', 'ST 2084', 'sRGB'}**, Inverse electro-optical transfer function (EOTF / EOCF). Other Parameters ---------------- L_B : numeric, optional {:func:`colour.models.eotf_inverse_BT1886`, :func:`colour.models.eotf_inverse_HLG_BT2100`}, Screen luminance for black. L_W : numeric, optional {:func:`colour.models.eotf_inverse_BT1886`, :func:`colour.models.eotf_inverse_HLG_BT2100`}, Screen luminance for white. gamma : numeric, optional {:func:`colour.models.eotf_HLG_BT2100`}, System gamma value, 1.2 at the nominal display peak luminance of :math:`1000 cd/m^2`. L_p : numeric, optional {:func:`colour.models.eotf_inverse_ST2084`}, Display peak luminance :math:`cd/m^2`. method : unicode, optional {:func:`colour.models.eotf_inverse_HLG_BT2100`}, **{'ITU-R BT.2100-1', 'ITU-R BT.2100-2'}** out_int : bool, optional {:func:`colour.models.eotf_inverse_DCDM`, :func:`colour.models.eotf_inverse_DICOMGSDF`}, Whether to return value as integer code value or float equivalent of a code value at a given bit depth. Returns ------- numeric or ndarray :math:`R'G'B'` video component signal value. Examples -------- >>> eotf_inverse(0.11699185725296059) # doctest: +ELLIPSIS 0.4090077... >>> eotf_inverse( # doctest: +ELLIPSIS ... 0.11699185725296059, function='ITU-R BT.1886') 0.4090077... """ function = EOTF_INVERSES[function] return function(value, **filter_kwargs(function, **kwargs))
def oetf(value, function='sRGB', **kwargs): """ Encodes estimated tristimulus values in a scene to :math:`R'G'B'` video component signal value using given opto-electronic transfer function (OETF / OECF). Parameters ---------- value : numeric or array_like Value. function : unicode, optional **{'sRGB', 'ARIB STD-B67', 'DCDM', 'DICOM GSDF', 'ITU-R BT.2020', 'ITU-R BT.2100 HLG', 'ITU-R BT.2100 PQ', 'ITU-R BT.601', 'ITU-R BT.709', 'ProPhoto RGB', 'RIMM RGB', 'ROMM RGB', 'SMPTE 240M', 'ST 2084'}**, Opto-electronic transfer function (OETF / OECF). Other Parameters ---------------- E_clip : numeric, optional {:func:`colour.models.oetf_RIMMRGB`}, Maximum exposure level. I_max : numeric, optional {:func:`colour.models.oetf_ROMMRGB`, :func:`colour.models.oetf_RIMMRGB`}, Maximum code value: 255, 4095 and 650535 for respectively 8-bit, 12-bit and 16-bit per channel. L_p : numeric, optional {:func:`colour.models.oetf_ST2084`}, Display peak luminance :math:`cd/m^2`. is_12_bits_system : bool {:func:`colour.models.oetf_BT2020`}, *ITU-R BT.2020* *alpha* and *beta* constants are used if system is not 12-bit. r : numeric, optional {:func:`colour.models.oetf_ARIBSTDB67`}, Video level corresponding to reference white level. Returns ------- numeric or ndarray :math:`R'G'B'` video component signal value. Examples -------- >>> oetf(0.18) # doctest: +ELLIPSIS 0.4613561... >>> oetf(0.18, function='ITU-R BT.2020') # doctest: +ELLIPSIS 0.4090077... >>> oetf(0.18, function='ST 2084', L_p=1000) ... # doctest: +ELLIPSIS 0.1820115... """ function = OETFS[function] return function(value, **filter_kwargs(function, **kwargs))
def luminance(LV, method='CIE 1976', **kwargs): """ Returns the *luminance* :math:`Y` of given *Lightness* :math:`L^*` or given *Munsell* value :math:`V`. Parameters ---------- LV : numeric or array_like *Lightness* :math:`L^*` or *Munsell* value :math:`V`. method : unicode, optional **{'CIE 1976', 'Newhall 1943', 'ASTM D1535-08'}**, Computation method. \**kwargs : dict, optional Keywords arguments. Returns ------- numeric or array_like *luminance* :math:`Y`. Notes ----- - Input *LV* is in domain [0, 100] or [0, 10] and optional *luminance* :math:`Y_n` is in domain [0, 100]. - Output *luminance* :math:`Y` is in range [0, 100]. Examples -------- >>> luminance(37.98562910) # doctest: +ELLIPSIS array(10.0800000...) >>> luminance(37.98562910, Y_n=100) # doctest: +ELLIPSIS array(10.0800000...) >>> luminance(37.98562910, Y_n=95) # doctest: +ELLIPSIS array(9.5760000...) >>> luminance(3.74629715, method='Newhall 1943') # doctest: +ELLIPSIS 10.4089874... >>> luminance(3.74629715, method='ASTM D1535-08') # doctest: +ELLIPSIS 10.1488096... """ function = LUMINANCE_METHODS[method] filter_kwargs(function, **kwargs) return function(LV, **kwargs)
def oetf_inverse(value: FloatingOrArrayLike, function: Union[Literal["ARIB STD-B67", "Blackmagic Film Generation 5", "DaVinci Intermediate", "ITU-R BT.2100 HLG", "ITU-R BT.2100 PQ", "ITU-R BT.601", "ITU-R BT.709", ], str, ] = "ITU-R BT.709", **kwargs: Any) -> FloatingOrNDArray: """ Decode :math:`R'G'B'` video component signal value to tristimulus values at the display using given inverse opto-electronic transfer function (OETF). Parameters ---------- value Value. function Inverse opto-electronic transfer function (OETF). Other Parameters ---------------- kwargs {:func:`colour.models.oetf_inverse_ARIBSTDB67`, :func:`colour.models.oetf_inverse_BlackmagicFilmGeneration5`, :func:`colour.models.oetf_inverse_DaVinciIntermediate`, :func:`colour.models.oetf_inverse_HLG_BT2100`, :func:`colour.models.oetf_inverse_PQ_BT2100`, :func:`colour.models.oetf_inverse_BT601`, :func:`colour.models.oetf_inverse_BT709`}, See the documentation of the previously listed definitions. Returns ------- :class:`numpy.floating` or :class:`numpy.ndarray` Tristimulus values at the display. Examples -------- >>> oetf_inverse(0.409007728864150) # doctest: +ELLIPSIS 0.1... >>> oetf_inverse( # doctest: +ELLIPSIS ... 0.409007728864150, function='ITU-R BT.601') 0.1... """ function = validate_method( function, OETF_INVERSES, '"{0}" inverse "OETF" is invalid, it must be one of {1}!', ) callable_ = OETF_INVERSES[function] return callable_(value, **filter_kwargs(callable_, **kwargs))
def uv_to_CCT(uv, method='Ohno 2013', **kwargs): """ Returns the correlated colour temperature :math:`T_{cp}` and :math:`\\Delta_{uv}` from given *CIE UCS* colourspace *uv* chromaticity coordinates using given method. Parameters ---------- uv : array_like *CIE UCS* colourspace *uv* chromaticity coordinates. method : unicode, optional **{'Ohno 2013', 'Krystek 1985, 'Robertson 1968'}**, Computation method. Other Parameters ---------------- cmfs : XYZ_ColourMatchingFunctions, optional {:func:`colour.temperature.uv_to_CCT_Ohno2013`}, Standard observer colour matching functions. start : numeric, optional {:func:`colour.temperature.uv_to_CCT_Ohno2013`}, Temperature range start in kelvins. end : numeric, optional {:func:`colour.temperature.uv_to_CCT_Ohno2013`}, Temperature range end in kelvins. count : int, optional {:func:`colour.temperature.uv_to_CCT_Ohno2013`}, Temperatures count in the planckian tables. iterations : int, optional {:func:`colour.temperature.uv_to_CCT_Ohno2013`}, Number of planckian tables to generate. optimisation_kwargs : dict_like, optional {:func:`colour.temperature.uv_to_CCT_Krystek1985`}, Parameters for :func:`scipy.optimize.minimize` definition. Returns ------- ndarray Correlated colour temperature :math:`T_{cp}`, :math:`\\Delta_{uv}`. References ---------- :cite:`AdobeSystems2013`, :cite:`AdobeSystems2013a`, :cite:`Krystek1985b`, :cite:`Ohno2014a`, :cite:`Wyszecki2000y` Examples -------- >>> import numpy as np >>> uv = np.array([0.1978, 0.3122]) >>> # Doctests skipping for Python 2.x compatibility. >>> uv_to_CCT(uv) # doctest: +SKIP array([ 6.5074738...e+03, 3.2233460...e-03]) """ function = UV_TO_CCT_METHODS[method] return function(uv, **filter_kwargs(function, **kwargs))
def lightness(Y, method='CIE 1976', **kwargs): """ Returns the *Lightness* :math:`L^*` using given method. Parameters ---------- Y : numeric or array_like *luminance* :math:`Y`. method : unicode, optional **{'CIE 1976', 'Glasser 1958', 'Wyszecki 1963'}**, Computation method. \**kwargs : dict, optional Keywords arguments. Returns ------- numeric or array_like *Lightness* :math:`L^*`. Notes ----- - Input *luminance* :math:`Y` and optional :math:`Y_n` are in domain [0, 100]. - Output *Lightness* :math:`L^*` is in range [0, 100]. Examples -------- >>> lightness(10.08) # doctest: +ELLIPSIS array(37.9856290...) >>> lightness(10.08, Y_n=100) # doctest: +ELLIPSIS array(37.9856290...) >>> lightness(10.08, Y_n=95) # doctest: +ELLIPSIS array(38.9165987...) >>> lightness(10.08, method='Glasser 1958') # doctest: +ELLIPSIS 36.2505626... >>> lightness(10.08, method='Wyszecki 1963') # doctest: +ELLIPSIS 37.0041149... """ function = LIGHTNESS_METHODS[method] filter_kwargs(function, **kwargs) return function(Y, **kwargs)
def delta_E(Lab_1, Lab_2, method='CMC', **kwargs): """ Returns the difference :math:`\Delta E_{ab}` between two given *CIE Lab* colourspace arrays using given method. Parameters ---------- Lab_1 : array_like *CIE Lab* colourspace array 1. Lab_2 : array_like *CIE Lab* colourspace array 2. method : unicode, optional **{'CMC', 'CIE 1976', 'CIE 1994', 'CIE 2000'}**, Computation method. \**kwargs : dict, optional Keywords arguments. Returns ------- numeric or ndarray Colour difference :math:`\Delta E_{ab}`. Examples -------- >>> Lab_1 = np.array([100.00000000, 21.57210357, 272.22819350]) >>> Lab_2 = np.array([100.00000000, 426.67945353, 72.39590835]) >>> delta_E(Lab_1, Lab_2) # doctest: +ELLIPSIS 172.7047712... >>> delta_E(Lab_1, Lab_2, method='CIE 1976') # doctest: +ELLIPSIS 451.7133019... >>> delta_E(Lab_1, Lab_2, method='CIE 1994') # doctest: +ELLIPSIS 83.7792255... >>> delta_E( # doctest: +ELLIPSIS ... Lab_1, Lab_2, method='CIE 1994', textiles=False) 83.7792255... >>> delta_E(Lab_1, Lab_2, method='CIE 2000') # doctest: +ELLIPSIS 94.0356490... """ function = DELTA_E_METHODS[method] filter_kwargs(function, **kwargs) return function(Lab_1, Lab_2, **kwargs)
def cctf_decoding(value, function='sRGB', **kwargs): """ Decodes non-linear :math:`R'G'B'` values to linear :math:`RGB` values using given decoding colour component transfer function (Decoding CCTF). Parameters ---------- value : numeric or array_like Non-linear :math:`R'G'B'` values. function : unicode, optional {:attr:`colour.CCTF_DECODINGS`}, Computation function. Other Parameters ---------------- \\**kwargs : dict, optional Keywords arguments for the relevant decoding CCTF of the :attr:`colour.CCTF_DECODINGS` attribute collection. Warnings -------- For *ITU-R BT.2100*, only the electro-optical transfer functions (EOTFs / EOCFs) are exposed by this definition, please refer to the :func:`colour.oetf_inverse` definition for the inverse opto-electronic transfer functions (OETF / OECF). Returns ------- numeric or ndarray Linear :math:`RGB` values. Examples -------- >>> cctf_decoding(0.391006842619746, function='PLog', log_reference=400) ... # doctest: +ELLIPSIS 0.1... >>> cctf_decoding(0.182011532850008, function='ST 2084', L_p=1000) ... # doctest: +ELLIPSIS 0.1... >>> cctf_decoding( # doctest: +ELLIPSIS ... 0.461356129500442, function='ITU-R BT.1886') 0.1... """ if 'itu-r bt.2100' in function.lower(): usage_warning( 'With the "ITU-R BT.2100" method, only the electro-optical ' 'transfer functions (EOTFs / EOCFs) are exposed by this ' 'definition, please refer to the "colour.oetf_inverse" definition ' 'for the inverse opto-electronic transfer functions (OETF / OECF).' ) function = CCTF_DECODINGS[function] return function(value, **filter_kwargs(function, **kwargs))
def polynomial_expansion( a: ArrayLike, method: Union[Literal["Cheung 2004", "Finlayson 2015", "Vandermonde"], str] = "Cheung 2004", **kwargs: Any, ) -> NDArray: """ Perform polynomial expansion of given :math:`a` array. Parameters ---------- a :math:`a` array to expand. method Computation method. Other Parameters ---------------- degree {:func:`colour.characterisation.polynomial_expansion_Finlayson2015`, :func:`colour.characterisation.polynomial_expansion_Vandermonde`}, Expanded polynomial degree, must be one of *[1, 2, 3, 4]* for :func:`colour.characterisation.polynomial_expansion_Finlayson2015` definition. root_polynomial_expansion {:func:`colour.characterisation.polynomial_expansion_Finlayson2015`}, Whether to use the root-polynomials set for the expansion. terms {:func:`colour.characterisation.matrix_augmented_Cheung2004`}, Number of terms of the expanded polynomial. Returns ------- :class:`numpy.ndarray` Expanded :math:`a` array. References ---------- :cite:`Cheung2004`, :cite:`Finlayson2015`, :cite:`Westland2004`, :cite:`Wikipedia2003e` Examples -------- >>> RGB = np.array([0.17224810, 0.09170660, 0.06416938]) >>> polynomial_expansion(RGB) # doctest: +ELLIPSIS array([ 0.1722481..., 0.0917066..., 0.0641693...]) >>> polynomial_expansion(RGB, 'Cheung 2004', terms=5) # doctest: +ELLIPSIS array([ 0.1722481..., 0.0917066..., 0.0641693..., 0.0010136..., 1...]) """ method = validate_method(method, POLYNOMIAL_EXPANSION_METHODS) function = POLYNOMIAL_EXPANSION_METHODS[method] return function(a, **filter_kwargs(function, **kwargs))
def CCT_to_uv(CCT, method='Ohno 2013', **kwargs): """ Returns the *CIE UCS* colourspace *uv* chromaticity coordinates from given correlated colour temperature :math:`T_{cp}` using given method. Parameters ---------- CCT : numeric Correlated colour temperature :math:`T_{cp}`. method : unicode, optional **{'Ohno 2013', 'Robertson 1968', 'Krystek 1985}**, Computation method. Other Parameters ---------------- D_uv : numeric {:func:`CCT_to_uv_Ohno2013, CCT_to_uv_Robertson1968`}, :math:`\Delta_{uv}`. cmfs : XYZ_ColourMatchingFunctions, optional {:func:`CCT_to_uv_Ohno2013`}, Standard observer colour matching functions. Returns ------- ndarray *CIE UCS* colourspace *uv* chromaticity coordinates. Examples -------- >>> from colour import STANDARD_OBSERVERS_CMFS >>> cmfs = STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer'] >>> CCT = 6507.4342201047066 >>> D_uv = 0.003223690901513 >>> CCT_to_uv(CCT, D_uv=D_uv, cmfs=cmfs) # doctest: +ELLIPSIS array([ 0.1977999..., 0.3122004...]) """ function = CCT_TO_UV_METHODS[method] filter_kwargs(function, **kwargs) return function(CCT, **kwargs)
def log_decoding_curve(value, curve='Cineon', **kwargs): """ Decodes :math:`R'G'B'` video component signal value to linear-light values using given *log* curve. Parameters ---------- value : numeric or array_like Value. curve : unicode, optional **{'Cineon', 'Panalog', 'ViperLog', 'PLog', 'Canon Log', 'ACEScc', 'ACESproxy', 'ALEXA Log C', 'REDLog', 'REDLogFilm', 'S-Log', 'S-Log2', 'S-Log3', 'V-Log'}**, Computation curve. \**kwargs : dict, optional Keywords arguments. Returns ------- numeric or ndarray *Log* value. Examples -------- >>> log_decoding_curve(0.457319613085418) # doctest: +ELLIPSIS 0.1... >>> log_decoding_curve( # doctest: +ELLIPSIS ... 0.413588402492442, curve='ACEScc') 0.1... >>> log_decoding_curve( # doctest: +ELLIPSIS ... 0.391006842619746, curve='PLog', log_reference=400) 0.1... >>> log_decoding_curve( # doctest: +ELLIPSIS ... 0.359987846422154, curve='S-Log') 0.1... """ function = LOG_DECODING_CURVES[curve] filter_kwargs(function, **kwargs) return function(value, **kwargs)
def decoding_cctf(value, function='Cineon', **kwargs): """ Decodes non-linear :math:`R'G'B'` values to linear :math:`RGB` values using given decoding colour component transfer function (Decoding CCTF). Parameters ---------- value : numeric or array_like Non-linear :math:`R'G'B'` values. function : unicode, optional {:attr:`colour.DECODING_CCTFS`}, Computation function. Other Parameters ---------------- \\**kwargs : dict, optional Keywords arguments for the relevant decoding CCTF of the :attr:`colour.DECODING_CCTFS` attribute collection. Warning ------- For *ITU-R BT.2100*, only the electro-optical transfer functions (EOTFs / EOCFs) are exposed by this definition, please refer to the :func:`colour.oetf_reverse` definition for the reverse opto-electronic transfer functions (OETF / OECF). Returns ------- numeric or ndarray Linear :math:`RGB` values. Examples -------- >>> decoding_cctf(0.391006842619746, function='PLog', log_reference=400) ... # doctest: +ELLIPSIS 0.1... >>> decoding_cctf(0.182011532850008, function='ST 2084', L_p=1000) ... # doctest: +ELLIPSIS 0.1... >>> decoding_cctf( # doctest: +ELLIPSIS ... 0.461356129500442, function='ITU-R BT.1886') 0.1... """ if 'itu-r bt.2100' in function.lower(): usage_warning( 'For "ITU-R BT.2100", only the electro-optical transfer functions ' '(EOTFs / EOCFs) are exposed by this definition, please refer to ' 'the "colour.oetf_reverse" definition for the reverse ' 'opto-electronic transfer functions (OETF / OECF).') function = DECODING_CCTFS[function] return function(value, **filter_kwargs(function, **kwargs))
def encoding_cctf(value, function='sRGB', **kwargs): """ Encodes linear :math:`RGB` values to non linear :math:`R'G'B'` values using given encoding colour component transfer function (Encoding CCTF). Parameters ---------- value : numeric or array_like Linear :math:`RGB` values. function : unicode, optional {:attr:`colour.ENCODING_CCTFS`}, Computation function. Other Parameters ---------------- \\**kwargs : dict, optional Keywords arguments for the relevant encoding CCTF of the :attr:`colour.ENCODING_CCTFS` attribute collection. Warning ------- For *ITU-R BT.2100*, only the reverse electro-optical transfer functions (EOTFs / EOCFs) are exposed by this definition, please refer to the :func:`colour.oetf` definition for the opto-electronic transfer functions (OETF / OECF). Returns ------- numeric or ndarray Non linear :math:`R'G'B'` values. Examples -------- >>> encoding_cctf(0.18, function='PLog', log_reference=400) ... # doctest: +ELLIPSIS 0.3910068... >>> encoding_cctf(0.18, function='ST 2084', L_p=1000) ... # doctest: +ELLIPSIS 0.1820115... >>> encoding_cctf( # doctest: +ELLIPSIS ... 0.11699185725296059, function='ITU-R BT.1886') 0.4090077... """ if 'itu-r bt.2100' in function.lower(): usage_warning( 'For "ITU-R BT.2100", only the reverse electro-optical transfer ' 'functions (EOTFs / EOCFs) are exposed by this definition, please ' 'refer to the "colour.oetf" definition for the opto-electronic ' 'transfer functions (OETF / OECF).') function = ENCODING_CCTFS[function] return function(value, **filter_kwargs(function, **kwargs))
def uv_to_CCT(uv, method='Ohno 2013', **kwargs): """ Returns the correlated colour temperature :math:`T_{cp}` and :math:`\\Delta_{uv}` from given *CIE UCS* colourspace *uv* chromaticity coordinates using given method. Parameters ---------- uv : array_like *CIE UCS* colourspace *uv* chromaticity coordinates. method : unicode, optional **{'Ohno 2013', 'Robertson 1968'}**, Computation method. Other Parameters ---------------- cmfs : XYZ_ColourMatchingFunctions, optional {:func:`colour.temperature.uv_to_CCT_Ohno2013`}, Standard observer colour matching functions. start : numeric, optional {:func:`colour.temperature.uv_to_CCT_Ohno2013`}, Temperature range start in kelvins. end : numeric, optional {:func:`colour.temperature.uv_to_CCT_Ohno2013`}, Temperature range end in kelvins. count : int, optional {:func:`colour.temperature.uv_to_CCT_Ohno2013`}, Temperatures count in the planckian tables. iterations : int, optional {:func:`colour.temperature.uv_to_CCT_Ohno2013`}, Number of planckian tables to generate. Returns ------- ndarray Correlated colour temperature :math:`T_{cp}`, :math:`\\Delta_{uv}`. References ---------- :cite:`AdobeSystems2013`, :cite:`AdobeSystems2013a`, :cite:`Ohno2014a`, :cite:`Wyszecki2000y` Examples -------- >>> from colour import STANDARD_OBSERVERS_CMFS >>> cmfs = STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer'] >>> uv = np.array([0.1978, 0.3122]) >>> uv_to_CCT(uv, cmfs=cmfs) # doctest: +ELLIPSIS array([ 6.5074738...e+03, 3.2233461...e-03]) """ function = UV_TO_CCT_METHODS[method] return function(uv, **filter_kwargs(function, **kwargs))
def eotf(value: Union[FloatingOrArrayLike, IntegerOrArrayLike], function: Union[Literal["DCDM", "DICOM GSDF", "ITU-R BT.1886", "ITU-R BT.2020", "ITU-R BT.2100 HLG", "ITU-R BT.2100 PQ", "SMPTE 240M", "ST 2084", "sRGB", ], str, ] = "ITU-R BT.1886", **kwargs: Any) -> FloatingOrNDArray: """ Decode :math:`R'G'B'` video component signal value to tristimulus values at the display using given electro-optical transfer function (EOTF). Parameters ---------- value Value. function Electro-optical transfer function (EOTF). Other Parameters ---------------- kwargs {:func:`colour.models.eotf_DCDM`, :func:`colour.models.eotf_DICOMGSDF`, :func:`colour.models.eotf_BT1886`, :func:`colour.models.eotf_BT2020`, :func:`colour.models.eotf_HLG_BT2100`, :func:`colour.models.eotf_PQ_BT2100`, :func:`colour.models.eotf_SMPTE240M`, :func:`colour.models.eotf_ST2084`, :func:`colour.models.eotf_sRGB`}, See the documentation of the previously listed definitions. Returns ------- :class:`numpy.floating` or :class:`numpy.ndarray` Tristimulus values at the display. Examples -------- >>> eotf(0.461356129500442) # doctest: +ELLIPSIS 0.1... >>> eotf(0.409007728864150, function='ITU-R BT.2020') ... # doctest: +ELLIPSIS 0.1... >>> eotf(0.182011532850008, function='ST 2084', L_p=1000) ... # doctest: +ELLIPSIS 0.1... """ function = validate_method( function, EOTFS, '"{0}" "EOTF" is invalid, it must be one of {1}!') callable_ = EOTFS[function] return callable_(value, **filter_kwargs(callable_, **kwargs))
def eotf_inverse(value: FloatingOrArrayLike, function: Union[Literal["DCDM", "DICOM GSDF", "ITU-R BT.1886", "ITU-R BT.2020", "ITU-R BT.2100 HLG", "ITU-R BT.2100 PQ", "ST 2084", "sRGB", ], str, ] = "ITU-R BT.1886", **kwargs) -> Union[FloatingOrNDArray, IntegerOrNDArray]: """ Encode estimated tristimulus values in a scene to :math:`R'G'B'` video component signal value using given inverse electro-optical transfer function (EOTF). Parameters ---------- value Value. function Inverse electro-optical transfer function (EOTF). Other Parameters ---------------- kwargs {:func:`colour.models.eotf_inverse_DCDM`, :func:`colour.models.eotf_inverse_DICOMGSDF`, :func:`colour.models.eotf_inverse_BT1886`, :func:`colour.models.eotf_inverse_BT2020`, :func:`colour.models.eotf_inverse_HLG_BT2100`, :func:`colour.models.eotf_inverse_PQ_BT2100`, :func:`colour.models.eotf_inverse_ST2084`, :func:`colour.models.eotf_inverse_sRGB`}, See the documentation of the previously listed definitions. Returns ------- :class:`numpy.floating` or :class:`numpy.integer` or :class:`numpy.ndarray` :math:`R'G'B'` video component signal value. Examples -------- >>> eotf_inverse(0.11699185725296059) # doctest: +ELLIPSIS 0.4090077... >>> eotf_inverse( # doctest: +ELLIPSIS ... 0.11699185725296059, function='ITU-R BT.1886') 0.4090077... """ function = validate_method( function, EOTF_INVERSES, '"{0}" inverse "EOTF" is invalid, it must be one of {1}!', ) callable_ = EOTF_INVERSES[function] return callable_(value, **filter_kwargs(callable_, **kwargs))
def oetf(value: FloatingOrArrayLike, function: Union[Literal["ARIB STD-B67", "Blackmagic Film Generation 5", "DaVinci Intermediate", "ITU-R BT.2100 HLG", "ITU-R BT.2100 PQ", "ITU-R BT.601", "ITU-R BT.709", "SMPTE 240M", ], str, ] = "ITU-R BT.709", **kwargs: Any) -> FloatingOrNDArray: """ Encode estimated tristimulus values in a scene to :math:`R'G'B'` video component signal value using given opto-electronic transfer function (OETF). Parameters ---------- value Value. function Opto-electronic transfer function (OETF). Other Parameters ---------------- kwargs {:func:`colour.models.oetf_ARIBSTDB67`, :func:`colour.models.oetf_BlackmagicFilmGeneration5`, :func:`colour.models.oetf_DaVinciIntermediate`, :func:`colour.models.oetf_HLG_BT2100`, :func:`colour.models.oetf_PQ_BT2100`, :func:`colour.models.oetf_BT601`, :func:`colour.models.oetf_BT709`, :func:`colour.models.oetf_SMPTE240M`}, See the documentation of the previously listed definitions. Returns ------- :class:`numpy.floating` or :class:`numpy.ndarray` :math:`R'G'B'` video component signal value. Examples -------- >>> oetf(0.18) # doctest: +ELLIPSIS 0.4090077... >>> oetf(0.18, function='ITU-R BT.601') # doctest: +ELLIPSIS 0.4090077... """ function = validate_method( function, OETFS, '"{0}" "OETF" is invalid, it must be one of {1}!') callable_ = OETFS[function] return callable_(value, **filter_kwargs(callable_, **kwargs))
def oetf(value, function='sRGB', **kwargs): """ Encodes estimated tristimulus values in a scene to :math:`R'G'B'` video component signal value using given opto-electronic transfer function (OETF / OECF). Parameters ---------- value : numeric or array_like Value. function : unicode, optional **{'sRGB', 'BT.1886', 'BT.2020', 'BT.709', 'DCI-P3', 'ProPhoto RGB', 'ST 2084'}**, Computation function. \**kwargs : dict, optional Keywords arguments. Returns ------- numeric or ndarray :math:`R'G'B'` video component signal value. Examples -------- >>> oetf(0.18) # doctest: +ELLIPSIS 0.4613561... >>> oetf(0.18, function='BT.2020') # doctest: +ELLIPSIS 0.4090077... >>> oetf( # doctest: +ELLIPSIS ... 0.18, function='ST 2084', L_p=1000) 0.1820115... """ function = OETFS[function] filter_kwargs(function, **kwargs) return function(value, **kwargs)
def eotf(value, function='sRGB', **kwargs): """ Decodes :math:`R'G'B'` video component signal value to tristimulus values at the display using given electro-optical transfer function (EOTF / EOCF). Parameters ---------- value : numeric or array_like Value. function : unicode, optional **{'sRGB', 'BT.1886', 'BT.2020', 'BT.709', 'DCI-P3', 'ProPhoto RGB', 'ST 2084'}**, Computation function. \**kwargs : dict, optional Keywords arguments. Returns ------- numeric or ndarray Tristimulus values at the display. Examples -------- >>> eotf(0.461356129500442) # doctest: +ELLIPSIS 0.1... >>> eotf(0.409007728864150, ... function='BT.2020') # doctest: +ELLIPSIS 0.1... >>> eotf( # doctest: +ELLIPSIS ... 0.182011532850008, function='ST 2084', L_p=1000) 0.1... """ function = EOTFS[function] filter_kwargs(function, **kwargs) return function(value, **kwargs)
def eotf_reverse(value, function='ITU-R BT.1886', **kwargs): """ Encodes estimated tristimulus values in a scene to :math:`R'G'B'` video component signal value using given reverse electro-optical transfer function (EOTF / EOCF). Parameters ---------- value : numeric or array_like Value. function : unicode, optional **{'ITU-R BT.1886', 'DCDM', 'ITU-R BT.2100 HLG', 'ITU-R BT.2100 PQ'}**, Reverse electro-optical transfer function (EOTF / EOCF). Other Parameters ---------------- L_B : numeric, optional {:func:`colour.models.eotf_reverse_BT1886`, :func:`colour.models.eotf_reverse_BT2100_HLG`}, Screen luminance for black. L_W : numeric, optional {:func:`colour.models.eotf_reverse_BT1886`, :func:`colour.models.eotf_reverse_BT2100_HLG`}, Screen luminance for white. gamma : numeric, optional {:func:`colour.models.eotf_BT2100_HLG`}, System gamma value, 1.2 at the nominal display peak luminance of :math:`1000 cd/m^2`. out_int : bool, optional {:func:`colour.models.eotf_reverse_DCDM`}, Whether to return value as integer code value or float equivalent of a code value at a given bit depth. Returns ------- numeric or ndarray :math:`R'G'B'` video component signal value. Examples -------- >>> eotf_reverse(0.11699185725296059) # doctest: +ELLIPSIS 0.4090077... >>> eotf_reverse( # doctest: +ELLIPSIS ... 0.11699185725296059, function='ITU-R BT.1886') 0.4090077... """ function = EOTFS_REVERSE[function] return function(value, **filter_kwargs(function, **kwargs))
def polynomial_expansion(a, method='Cheung 2004', **kwargs): """ Performs polynomial expansion of given :math:`a` array. Parameters ---------- a : array_like, (3, n) :math:`a` array to expand. method : unicode, optional **{'Cheung 2004', 'Finlayson 2015', 'Vandermonde'}**, Computation method. Other Parameters ---------------- degree : int {:func:`colour.characterisation.polynomial_expansion_Finlayson2015`, :func:`colour.characterisation.polynomial_expansion_Vandermonde`}, Expanded polynomial degree, must be one of *[1, 2, 3, 4]* for :func:`colour.characterisation.polynomial_expansion_Finlayson2015` definition. terms : int {:func:`colour.characterisation.augmented_matrix_Cheung2004`}, Number of terms of the expanded polynomial, must be one of *[3, 5, 7, 8, 10, 11, 14, 16, 17, 19, 20, 22]*. root_polynomial_expansion : bool {:func:`colour.characterisation.polynomial_expansion_Finlayson2015`}, Whether to use the root-polynomials set for the expansion. Returns ------- ndarray, (3, n) Expanded :math:`a` array. References ---------- :cite:`Cheung2004`, :cite:`Finlayson2015`, :cite:`Westland2004`, :cite:`Wikipedia2003e` Examples -------- >>> RGB = np.array([0.17224810, 0.09170660, 0.06416938]) >>> polynomial_expansion(RGB) # doctest: +ELLIPSIS array([ 0.1722481..., 0.0917066..., 0.0641693...]) >>> polynomial_expansion(RGB, 'Cheung 2004', terms=5) # doctest: +ELLIPSIS array([ 0.1722481..., 0.0917066..., 0.0641693..., 0.0010136..., 1...]) """ function = POLYNOMIAL_EXPANSION_METHODS[method] return function(a, **filter_kwargs(function, **kwargs))
def polynomial_expansion(a, method='Cheung 2004', **kwargs): """ Performs polynomial expansion of given :math:`a` array. Parameters ---------- a : array_like, (3, n) :math:`a` array to expand. method : unicode, optional **{'Cheung 2004', 'Finlayson 2015', 'Vandermonde'}**, Computation method. Other Parameters ---------------- degree : int {:func:`colour.characterisation.polynomial_expansion_Finlayson2015`, :func:`colour.characterisation.polynomial_expansion_Vandermonde`}, Expanded polynomial degree, must be one of *[1, 2, 3, 4]* for :func:`colour.characterisation.polynomial_expansion_Finlayson2015` definition. terms : int {:func:`colour.characterisation.matrix_augmented_Cheung2004`}, Number of terms of the expanded polynomial, must be one of *[3, 5, 7, 8, 10, 11, 14, 16, 17, 19, 20, 22]*. root_polynomial_expansion : bool {:func:`colour.characterisation.polynomial_expansion_Finlayson2015`}, Whether to use the root-polynomials set for the expansion. Returns ------- ndarray, (3, n) Expanded :math:`a` array. References ---------- :cite:`Cheung2004`, :cite:`Finlayson2015`, :cite:`Westland2004`, :cite:`Wikipedia2003e` Examples -------- >>> RGB = np.array([0.17224810, 0.09170660, 0.06416938]) >>> polynomial_expansion(RGB) # doctest: +ELLIPSIS array([ 0.1722481..., 0.0917066..., 0.0641693...]) >>> polynomial_expansion(RGB, 'Cheung 2004', terms=5) # doctest: +ELLIPSIS array([ 0.1722481..., 0.0917066..., 0.0641693..., 0.0010136..., 1...]) """ function = POLYNOMIAL_EXPANSION_METHODS[method] return function(a, **filter_kwargs(function, **kwargs))
def test_filter_kwargs(self): """ Tests :func:`colour.utilities.common.filter_kwargs` definition. """ def fn_a(a): """ :func:`filter_kwargs` unit tests :func:`fn_a` definition. """ return a def fn_b(a, b=0): """ :func:`filter_kwargs` unit tests :func:`fn_b` definition. """ return a, b def fn_c(a, b=0, c=0): """ :func:`filter_kwargs` unit tests :func:`fn_c` definition. """ return a, b, c self.assertEqual(1, fn_a(1, **filter_kwargs(fn_a, b=2, c=3))) self.assertTupleEqual((1, 2), fn_b(1, **filter_kwargs(fn_b, b=2, c=3))) self.assertTupleEqual((1, 2, 3), fn_c(1, **filter_kwargs(fn_c, b=2, c=3))) if six.PY2: # pragma: no cover self.assertDictEqual(filter_kwargs(partial(fn_c, b=1), b=1), {}) else: # pragma: no cover self.assertDictEqual(filter_kwargs(partial(fn_c, b=1), b=1), {'b': 1})
def CCT_to_uv( CCT_D_uv: ArrayLike, method: Union[ Literal["Krystek 1985", "Ohno 2013", "Robertson 1968"], str ] = "Ohno 2013", **kwargs: Any, ) -> NDArray: """ Return the *CIE UCS* colourspace *uv* chromaticity coordinates from given correlated colour temperature :math:`T_{cp}` using given method. Parameters ---------- CCT_D_uv Correlated colour temperature :math:`T_{cp}`, :math:`\\Delta_{uv}`. method Computation method. Other Parameters ---------------- cmfs {:func:`colour.temperature.CCT_to_uv_Ohno2013`}, Standard observer colour matching functions. Returns ------- :class:`numpy.ndarray` *CIE UCS* colourspace *uv* chromaticity coordinates. References ---------- :cite:`AdobeSystems2013`, :cite:`AdobeSystems2013a`, :cite:`Krystek1985b`, :cite:`Ohno2014a`, :cite:`Wyszecki2000y` Examples -------- >>> import numpy as np >>> CCT_D_uv = np.array([6507.47380460, 0.00322335]) >>> CCT_to_uv(CCT_D_uv) # doctest: +ELLIPSIS array([ 0.1977999..., 0.3121999...]) """ method = validate_method(method, CCT_TO_UV_METHODS) function = CCT_TO_UV_METHODS[method] return function(CCT_D_uv, **filter_kwargs(function, **kwargs))
def eotf_reverse(value, function='ITU-R BT.1886', **kwargs): """ Encodes estimated tristimulus values in a scene to :math:`R'G'B'` video component signal value using given reverse electro-optical transfer function (EOTF / EOCF). Parameters ---------- value : numeric or array_like Value. function : unicode, optional **{'ITU-R BT.1886', 'ITU-R BT.2100 HLG', 'ITU-R BT.2100 PQ'}**, Reverse electro-optical transfer function (EOTF / EOCF). Other Parameters ---------------- L_B : numeric, optional {:func:`colour.models.eotf_reverse_BT1886`, :func:`colour.models.eotf_reverse_BT2100_HLG`}, Screen luminance for black. L_W : numeric, optional {:func:`colour.models.eotf_reverse_BT1886`, :func:`colour.models.eotf_reverse_BT2100_HLG`}, Screen luminance for white. gamma : numeric, optional {:func:`colour.models.eotf_BT2100_HLG`}, System gamma value, 1.2 at the nominal display peak luminance of :math:`1000 cd/m^2`. Returns ------- numeric or ndarray :math:`R'G'B'` video component signal value. Examples -------- >>> eotf_reverse(0.11699185725296059) # doctest: +ELLIPSIS 0.4090077... >>> eotf_reverse( # doctest: +ELLIPSIS ... 0.11699185725296059, function='ITU-R BT.1886') 0.4090077... """ function = EOTFS_REVERSE[function] return function(value, **filter_kwargs(function, **kwargs))
def ootf_reverse(value, function='ITU-R BT.2100 PQ', **kwargs): """ Maps relative display linear light to scene linear light using given reverse opto-optical transfer function (OOTF / OOCF). Parameters ---------- value : numeric or array_like Value. function : unicode, optional **{'ITU-R BT.2100 HLG', 'ITU-R BT.2100 PQ'}** Reverse opto-optical transfer function (OOTF / OOCF). Other Parameters ---------------- L_B : numeric, optional {:func:`colour.models.ootf_reverse_BT2100_HLG`}, :math:`L_B` is the display luminance for black in :math:`cd/m^2`. L_W : numeric, optional {:func:`colour.models.ootf_reverse_BT2100_HLG`}, :math:`L_W` is nominal peak luminance of the display in :math:`cd/m^2` for achromatic pixels. gamma : numeric, optional {:func:`colour.models.ootf_reverse_BT2100_HLG`}, System gamma value, 1.2 at the nominal display peak luminance of :math:`1000 cd/m^2`. Returns ------- numeric or ndarray Luminance of scene linear light. Examples -------- >>> ootf_reverse(779.988360834115840) # doctest: +ELLIPSIS 0.1000000... >>> ootf_reverse( # doctest: +ELLIPSIS ... 63.095734448019336, function='ITU-R BT.2100 HLG') 0.1000000... """ function = OOTFS_REVERSE[function] return function(value, **filter_kwargs(function, **kwargs))
def CCT_to_uv(CCT_D_uv, method='Ohno 2013', **kwargs): """ Returns the *CIE UCS* colourspace *uv* chromaticity coordinates from given correlated colour temperature :math:`T_{cp}` using given method. Parameters ---------- CCT_D_uv : ndarray Correlated colour temperature :math:`T_{cp}`, :math:`\\Delta_{uv}`. method : unicode, optional **{'Ohno 2013', 'Robertson 1968', 'Krystek 1985}**, Computation method. Other Parameters ---------------- cmfs : XYZ_ColourMatchingFunctions, optional {:func:`colour.temperature.CCT_to_uv_Ohno2013`}, Standard observer colour matching functions. Returns ------- ndarray *CIE UCS* colourspace *uv* chromaticity coordinates. References ---------- :cite:`AdobeSystems2013`, :cite:`AdobeSystems2013a`, :cite:`Krystek1985b`, :cite:`Ohno2014a`, :cite:`Wyszecki2000y` Examples -------- >>> from colour import STANDARD_OBSERVERS_CMFS >>> cmfs = STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer'] >>> CCT_D_uv = np.array([6507.47380460, 0.00322335]) >>> CCT_to_uv(CCT_D_uv, cmfs=cmfs) # doctest: +ELLIPSIS array([ 0.1977999..., 0.3121999...]) """ function = CCT_TO_UV_METHODS[method] return function(CCT_D_uv, **filter_kwargs(function, **kwargs))
def oetf_reverse(value, function='sRGB', **kwargs): """ Decodes :math:`R'G'B'` video component signal value to tristimulus values at the display using given reverse opto-electronic transfer function (OETF / OECF). Parameters ---------- value : numeric or array_like Value. function : unicode, optional **{'sRGB', 'ARIB STD-B67', 'ITU-R BT.2100 HLD', 'ITU-R BT.2100 PQ', 'ITU-R BT.601', 'ITU-R BT.709'}**, Reverse opto-electronic transfer function (OETF / OECF). Other Parameters ---------------- r : numeric, optional {:func:`colour.models.oetf_ARIBSTDB67`}, Video level corresponding to reference white level. Returns ------- numeric or ndarray Tristimulus values at the display. Examples -------- >>> oetf_reverse(0.461356129500442) # doctest: +ELLIPSIS 0.1... >>> oetf_reverse( # doctest: +ELLIPSIS ... 0.409007728864150, function='ITU-R BT.601') 0.1... """ function = OETFS_REVERSE[function] return function(value, **filter_kwargs(function, **kwargs))
def luminance(LV, method='CIE 1976', **kwargs): """ Returns the *luminance* :math:`Y` of given *Lightness* :math:`L^*` or given *Munsell* value :math:`V`. Parameters ---------- LV : numeric or array_like *Lightness* :math:`L^*` or *Munsell* value :math:`V`. method : unicode, optional **{'CIE 1976', 'Newhall 1943', 'ASTM D1535-08', 'Fairchild 2010', 'Fairchild 2011'}**, Computation method. Other Parameters ---------------- Y_n : numeric or array_like, optional {:func:`colour.colorimetry.luminance_CIE1976`}, White reference *luminance* :math:`Y_n`. epsilon : numeric or array_like, optional {:func:`colour.colorimetry.lightness_Fairchild2010`, :func:`colour.colorimetry.lightness_Fairchild2011`}, :math:`\\epsilon` exponent. Returns ------- numeric or array_like *luminance* :math:`Y`. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``LV`` | [0, 100] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``Y`` | [0, 100] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`ASTMInternational2008a`, :cite:`CIETC1-482004m`, :cite:`Fairchild2010`, :cite:`Fairchild2011`, :cite:`Newhall1943a`, :cite:`Wikipedia2001b`, :cite:`Wyszecki2000bd` Examples -------- >>> luminance(41.527875844653451) # doctest: +ELLIPSIS 12.1972253... >>> luminance(41.527875844653451, Y_n=100) # doctest: +ELLIPSIS 12.1972253... >>> luminance(42.51993072812094, Y_n=95) # doctest: +ELLIPSIS 12.1972253... >>> luminance(4.08244375 * 10, method='Newhall 1943') ... # doctest: +ELLIPSIS 12.5500788... >>> luminance(4.08244375 * 10, method='ASTM D1535-08') ... # doctest: +ELLIPSIS 12.2363426... >>> luminance(29.829510892279330, epsilon=0.710, method='Fairchild 2011') ... # doctest: +ELLIPSIS 12.1972253... """ function = LUMINANCE_METHODS[method] domain_range_reference = get_domain_range_scale() == 'reference' domain_1 = (luminance_Fairchild2010, luminance_Fairchild2011) domain_10 = (luminance_Newhall1943, luminance_ASTMD153508) if function in domain_10 and domain_range_reference: LV /= 10 Y_V = function(LV, **filter_kwargs(function, **kwargs)) if function in domain_1 and domain_range_reference: Y_V *= 100 return Y_V
def write_LUT(LUT, path, decimals=7, method=None, **kwargs): """ Writes given *LUT* to given file using given method. Parameters ---------- LUT : LUT1D or LUT3x1D or LUT3D :class:`LUT1D`, :class:`LUT3x1D` or :class:`LUT3D` class instance to write at given path. path : unicode *LUT* path. decimals : int, optional Formatting decimals. method : unicode, optional **{None, 'Cinespace', 'Iridas Cube', 'Resolve Cube', 'Sony SPI1D', 'Sony SPI3D'}**, Writing method, if *None*, the method will be auto-detected according to extension. Returns ------- bool Definition success. References ---------- :cite:`AdobeSystems2013b`, :cite:`Chamberlain2015`, :cite:`RisingSunResearch` Examples -------- Writing a 3x1D *Iridas* *.cube* *LUT*: >>> import numpy as np >>> from colour.algebra import spow >>> domain = np.array([[-0.1, -0.2, -0.4], [1.5, 3.0, 6.0]]) >>> LUT = LUT3x1D( ... spow(LUT3x1D.linear_table(16, domain), 1 / 2.2), ... 'My LUT', ... domain, ... comments=['A first comment.', 'A second comment.']) >>> write_LUT(LUT, 'My_LUT.cube') # doctest: +SKIP Writing a 1D *Sony* *.spi1d* *LUT*: >>> domain = np.array([-0.1, 1.5]) >>> LUT = LUT1D( ... spow(LUT1D.linear_table(16, domain), 1 / 2.2), ... 'My LUT', ... domain, ... comments=['A first comment.', 'A second comment.']) >>> write_LUT(LUT, 'My_LUT.spi1d') # doctest: +SKIP Writing a 3D *Sony* *.spi3d* *LUT*: >>> LUT = LUT3D( ... LUT3D.linear_table(16) ** (1 / 2.2), ... 'My LUT', ... np.array([[0, 0, 0], [1, 1, 1]]), ... comments=['A first comment.', 'A second comment.']) >>> write_LUT(LUT, 'My_LUT.cube') # doctest: +SKIP """ if method is None: method = EXTENSION_TO_LUT_FORMAT_MAPPING[os.path.splitext(path)[-1]] if method == 'Iridas Cube' and isinstance(LUT, LUTSequence): method = 'Resolve Cube' function = LUT_WRITE_METHODS[method] return function(LUT, path, decimals, **filter_kwargs(function, **kwargs))
def lightness(Y, method='CIE 1976', **kwargs): """ Returns the *Lightness* :math:`L` of given *luminance* :math:`Y` using given method. Parameters ---------- Y : numeric or array_like *luminance* :math:`Y`. method : unicode, optional **{'CIE 1976', 'Glasser 1958', 'Wyszecki 1963', 'Fairchild 2010', 'Fairchild 2011'}**, Computation method. Other Parameters ---------------- Y_n : numeric or array_like, optional {:func:`colour.colorimetry.lightness_CIE1976`}, White reference *luminance* :math:`Y_n`. epsilon : numeric or array_like, optional {:func:`colour.colorimetry.lightness_Fairchild2010`, :func:`colour.colorimetry.lightness_Fairchild2011`}, :math:`\\epsilon` exponent. Returns ------- numeric or array_like *Lightness* :math:`L`. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``Y`` | [0, 100] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``L`` | [0, 100] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`CIETC1-482004m`, :cite:`Fairchild2010`, :cite:`Fairchild2011`, :cite:`Glasser1958a`, :cite:`Wikipedia2007c`, :cite:`Wyszecki1963b`, :cite:`Wyszecki2000bd` Examples -------- >>> lightness(12.19722535) # doctest: +ELLIPSIS 41.5278758... >>> lightness(12.19722535, Y_n=100) # doctest: +ELLIPSIS 41.5278758... >>> lightness(12.19722535, Y_n=95) # doctest: +ELLIPSIS 42.5199307... >>> lightness(12.19722535, method='Glasser 1958') # doctest: +ELLIPSIS 39.8351264... >>> lightness(12.19722535, method='Wyszecki 1963') # doctest: +ELLIPSIS 40.5475745... >>> lightness(12.19722535, epsilon=0.710, method='Fairchild 2011') ... # doctest: +ELLIPSIS 29.8295108... """ Y = as_float_array(Y) function = LIGHTNESS_METHODS[method] domain_range_reference = get_domain_range_scale() == 'reference' domain_1 = (lightness_Fairchild2010, lightness_Fairchild2011) if function in domain_1 and domain_range_reference: Y = Y / 100 return function(Y, **filter_kwargs(function, **kwargs))
def colour_correction(RGB, M_T, M_R, method='Cheung 2004', **kwargs): """ Performs colour correction of given *RGB* colourspace array using the colour correction matrix from given :math:`M_T` colour array to :math:`M_R` colour array. Parameters ---------- RGB : array_like, (3, n) *RGB* colourspace array to colour correct. M_T : array_like, (3, n) Test array :math:`M_T` to fit onto array :math:`M_R`. M_R : array_like, (3, n) Reference array the array :math:`M_T` will be colour fitted against. method : unicode, optional **{'Cheung 2004', 'Finlayson 2015', 'Vandermonde'}**, Computation method. Other Parameters ---------------- degree : int {:func:`colour.characterisation.polynomial_expansion_Finlayson2015`, :func:`colour.characterisation.polynomial_expansion_Vandermonde`}, Expanded polynomial degree, must be one of *[1, 2, 3, 4]* for :func:`colour.characterisation.polynomial_expansion_Finlayson2015` definition. terms : int {:func:`colour.characterisation.augmented_matrix_Cheung2004`}, Number of terms of the expanded polynomial, must be one of *[3, 5, 7, 8, 10, 11, 14, 16, 17, 19, 20, 22]*. root_polynomial_expansion : bool {:func:`colour.characterisation.polynomial_expansion_Finlayson2015`}, Whether to use the root-polynomials set for the expansion. Returns ------- ndarray Colour corrected *RGB* colourspace array. References ---------- :cite:`Cheung2004`, :cite:`Finlayson2015`, :cite:`Westland2004`, :cite:`Wikipedia2003e` Examples -------- >>> RGB = np.array([0.17224810, 0.09170660, 0.06416938]) >>> M_T = np.array( ... [[0.17224810, 0.09170660, 0.06416938], ... [0.49189645, 0.27802050, 0.21923399], ... [0.10999751, 0.18658946, 0.29938611], ... [0.11666120, 0.14327905, 0.05713804], ... [0.18988879, 0.18227649, 0.36056247], ... [0.12501329, 0.42223442, 0.37027445], ... [0.64785606, 0.22396782, 0.03365194], ... [0.06761093, 0.11076896, 0.39779139], ... [0.49101797, 0.09448929, 0.11623839], ... [0.11622386, 0.04425753, 0.14469986], ... [0.36867946, 0.44545230, 0.06028681], ... [0.61632937, 0.32323906, 0.02437089], ... [0.03016472, 0.06153243, 0.29014596], ... [0.11103655, 0.30553067, 0.08149137], ... [0.41162190, 0.05816656, 0.04845934], ... [0.73339206, 0.53075188, 0.02475212], ... [0.47347718, 0.08834792, 0.30310315], ... [0.00000000, 0.25187016, 0.35062450], ... [0.76809639, 0.78486240, 0.77808297], ... [0.53822392, 0.54307997, 0.54710883], ... [0.35458526, 0.35318419, 0.35524431], ... [0.17976704, 0.18000531, 0.17991488], ... [0.09351417, 0.09510603, 0.09675027], ... [0.03405071, 0.03295077, 0.03702047]] ... ) >>> M_R = np.array( ... [[0.15579559, 0.09715755, 0.07514556], ... [0.39113140, 0.25943419, 0.21266708], ... [0.12824821, 0.18463570, 0.31508023], ... [0.12028974, 0.13455659, 0.07408400], ... [0.19368988, 0.21158946, 0.37955964], ... [0.19957425, 0.36085439, 0.40678123], ... [0.48896605, 0.20691688, 0.05816533], ... [0.09775522, 0.16710693, 0.47147724], ... [0.39358649, 0.12233400, 0.10526425], ... [0.10780332, 0.07258529, 0.16151473], ... [0.27502671, 0.34705454, 0.09728099], ... [0.43980441, 0.26880559, 0.05430533], ... [0.05887212, 0.11126272, 0.38552469], ... [0.12705825, 0.25787860, 0.13566464], ... [0.35612929, 0.07933258, 0.05118732], ... [0.48131976, 0.42082843, 0.07120612], ... [0.34665585, 0.15170714, 0.24969804], ... [0.08261116, 0.24588716, 0.48707733], ... [0.66054904, 0.65941137, 0.66376412], ... [0.48051509, 0.47870296, 0.48230082], ... [0.33045354, 0.32904184, 0.33228886], ... [0.18001305, 0.17978567, 0.18004416], ... [0.10283975, 0.10424680, 0.10384975], ... [0.04742204, 0.04772203, 0.04914226]] ... ) >>> colour_correction(RGB, M_T, M_R) # doctest: +ELLIPSIS array([ 0.1334872..., 0.0843921..., 0.0599014...]) """ function = COLOUR_CORRECTION_METHODS[method] return function(RGB, M_T, M_R, **filter_kwargs(function, **kwargs))
def read_LUT(path, method=None, **kwargs): """ Reads given *LUT* file using given method. Parameters ---------- path : unicode *LUT* path. method : unicode, optional **{None, 'Cinespace', 'Iridas Cube', 'Resolve Cube', 'Sony SPI1D', 'Sony SPI3D'}**, Reading method, if *None*, the method will be auto-detected according to extension. Returns ------- LUT1D or LUT3x1D or LUT3D :class:`LUT1D`, :class:`LUT3x1D` or :class:`LUT3D` class instance. References ---------- :cite:`AdobeSystems2013b`, :cite:`Chamberlain2015`, :cite:`RisingSunResearch` Examples -------- Reading a 3x1D *Iridas* *.cube* *LUT*: >>> path = os.path.join( ... os.path.dirname(__file__), 'tests', 'resources', 'iridas_cube', ... 'ACES_Proxy_10_to_ACES.cube') >>> print(read_LUT(path)) LUT3x1D - ACES Proxy 10 to ACES ------------------------------- <BLANKLINE> Dimensions : 2 Domain : [[ 0. 0. 0.] [ 1. 1. 1.]] Size : (32, 3) Reading a 1D *Sony* *.spi1d* *LUT*: >>> path = os.path.join( ... os.path.dirname(__file__), 'tests', 'resources', 'sony_spi1d', ... 'oetf_reverse_sRGB_1D.spi1d') >>> print(read_LUT(path)) LUT1D - oetf reverse sRGB 1D ---------------------------- <BLANKLINE> Dimensions : 1 Domain : [-0.1 1.5] Size : (16,) Comment 01 : Generated by "Colour 0.3.11". Comment 02 : "colour.models.oetf_reverse_sRGB". Reading a 3D *Sony* *.spi3d* *LUT*: >>> path = os.path.join( ... os.path.dirname(__file__), 'tests', 'resources', 'sony_spi3d', ... 'ColourCorrect.spi3d') >>> print(read_LUT(path)) LUT3D - ColourCorrect --------------------- <BLANKLINE> Dimensions : 3 Domain : [[ 0. 0. 0.] [ 1. 1. 1.]] Size : (4, 4, 4, 3) Comment 01 : Adapted from a LUT generated by Foundry::LUT. """ if method is None: method = EXTENSION_TO_LUT_FORMAT_MAPPING[os.path.splitext(path)[-1]] function = LUT_READ_METHODS[method] return function(path, **filter_kwargs(function, **kwargs))
def delta_E(a, b, method='CIE 2000', **kwargs): """ Returns the difference :math:`\\Delta E_{ab}` between two given *CIE L\\*a\\*b\\** or :math:`J'a'b'` colourspace arrays using given method. Parameters ---------- a : array_like *CIE L\\*a\\*b\\** or :math:`J'a'b'` colourspace array :math:`a`. b : array_like *CIE L\\*a\\*b\\** or :math:`J'a'b'` colourspace array :math:`b`. method : unicode, optional **{'CIE 2000', 'CIE 1976', 'CIE 1994', 'CMC', 'CAM02-LCD', 'CAM02-SCD', 'CAM02-UCS', 'CAM16-LCD', 'CAM16-SCD', 'CAM16-UCS', 'DIN99'}** Computation method. Other Parameters ---------------- textiles : bool, optional {:func:`colour.difference.delta_E_CIE1994`, :func:`colour.difference.delta_E_CIE2000`, :func:`colour.difference.delta_E_DIN99`}, Textiles application specific parametric factors :math:`k_L=2,\\ k_C=k_H=1,\\ k_1=0.048,\\ k_2=0.014,\\ k_E=2,\ \\ k_CH=0.5` weights are used instead of :math:`k_L=k_C=k_H=1,\\ k_1=0.045,\\ k_2=0.015,\\ k_E=k_CH=1.0`. l : numeric, optional {:func:`colour.difference.delta_E_CIE2000`}, Lightness weighting factor. c : numeric, optional {:func:`colour.difference.delta_E_CIE2000`}, Chroma weighting factor. Returns ------- numeric or ndarray Colour difference :math:`\\Delta E_{ab}`. References ---------- :cite:`ASTMInternational2007`, :cite:`Li2017`, :cite:`Lindbloom2003c`, :cite:`Lindbloom2011a`, :cite:`Lindbloom2009e`, :cite:`Lindbloom2009f`, :cite:`Luo2006b`, :cite:`Melgosa2013b`, :cite:`Wikipedia2008b` Examples -------- >>> import numpy as np >>> a = np.array([100.00000000, 21.57210357, 272.22819350]) >>> b = np.array([100.00000000, 426.67945353, 72.39590835]) >>> delta_E(a, b) # doctest: +ELLIPSIS 94.0356490... >>> delta_E(a, b, method='CIE 2000') # doctest: +ELLIPSIS 94.0356490... >>> delta_E(a, b, method='CIE 1976') # doctest: +ELLIPSIS 451.7133019... >>> delta_E(a, b, method='CIE 1994') # doctest: +ELLIPSIS 83.7792255... >>> delta_E(a, b, method='CIE 1994', textiles=False) ... # doctest: +ELLIPSIS 83.7792255... >>> delta_E(a, b, method='DIN99') # doctest: +ELLIPSIS 66.1119282... >>> a = np.array([54.90433134, -0.08450395, -0.06854831]) >>> b = np.array([54.90433134, -0.08442362, -0.06848314]) >>> delta_E(a, b, method='CAM02-UCS') # doctest: +ELLIPSIS 0.0001034... >>> delta_E(a, b, method='CAM16-LCD') # doctest: +ELLIPSIS 0.0001034... """ function = DELTA_E_METHODS[method] return function(a, b, **filter_kwargs(function, **kwargs))
def contrast_sensitivity_function(method='Barten 1999', **kwargs): """ Returns the contrast sensitivity :math:`S` of the human eye according to the contrast sensitivity function (CSF) described by given method. Parameters ---------- method : unicode, optional **{'Barten 1999'}**, Computation method. Other Parameters ---------------- E : numeric or array_like, optional {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`}, Retinal illuminance :math:`E` in Trolands. N_max : numeric or array_like, optional {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`}, Maximum number of cycles :math:`N_{max}` over which the eye can integrate the information. T : numeric or array_like, optional {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`}, Integration time :math:`T` in seconds of the eye. X_0 : numeric or array_like, optional {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`}, Angular size :math:`X_0` in degrees of the object in the x direction. Y_0 : numeric or array_like, optional {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`}, Angular size :math:`Y_0` in degrees of the object in the y direction. X_max : numeric or array_like, optional {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`}, Maximum angular size :math:`X_{max}` in degrees of the integration area in the x direction. Y_max : numeric or array_like, optional {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`}, Maximum angular size :math:`Y_{max}` in degrees of the integration area in the y direction. k : numeric or array_like, optional {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`}, Signal-to-noise (SNR) ratio :math:`k`. n : numeric or array_like, optional {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`}, Quantum efficiency of the eye :math:`n`. p : numeric or array_like, optional {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`}, Photon conversion factor :math:`p` in :math:`photons\\div seconds\\div degrees^2\\div Trolands` that depends on the light source. phi_0 : numeric or array_like, optional {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`}, Spectral density :math:`\\phi_0` in :math:`seconds degrees^2` of the neural noise. sigma : numeric or array_like, optional {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`}, Standard deviation :math:`\\sigma` of the line-spread function resulting from the convolution of the different elements of the convolution process. u : numeric {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`}, Spatial frequency :math:`u`, the cycles per degree. u_0 : numeric or array_like, optional {:func:`colour.contrast.contrast_sensitivity_function_Barten1999`}, Spatial frequency :math:`u_0` in :math:`cycles\\div degrees` above which the lateral inhibition ceases. Returns ------- ndarray Contrast sensitivity :math:`S`. References ---------- :cite:`Barten1999`, :cite:`Barten2003`, :cite:`Cowan2004`, :cite:`InternationalTelecommunicationUnion2015`, Examples -------- >>> contrast_sensitivity_function(u=4) # doctest: +ELLIPSIS 360.8691122... >>> contrast_sensitivity_function('Barten 1999', u=4) # doctest: +ELLIPSIS 360.8691122... """ function = CONTRAST_SENSITIVITY_METHODS[method] S = function(**filter_kwargs(function, **kwargs)) return S
def chromatic_adaptation(XYZ, XYZ_w, XYZ_wr, method='Von Kries', **kwargs): """ Adapts given stimulus from test viewing conditions to reference viewing conditions. Parameters ---------- XYZ : array_like *CIE XYZ* tristimulus values of stimulus to adapt. XYZ_w : array_like Test viewing condition *CIE XYZ* tristimulus values of the whitepoint. XYZ_wr : array_like Reference viewing condition *CIE XYZ* tristimulus values of the whitepoint. method : unicode, optional **{'Von Kries', 'CIE 1994', 'CMCCAT2000', 'Fairchild 1990'}**, Computation method. Other Parameters ---------------- E_o1 : numeric {:func:`colour.adaptation.chromatic_adaptation_CIE1994`}, Test illuminance :math:`E_{o1}` in :math:`cd/m^2`. E_o2 : numeric {:func:`colour.adaptation.chromatic_adaptation_CIE1994`}, Reference illuminance :math:`E_{o2}` in :math:`cd/m^2`. L_A1 : numeric or array_like {:func:`colour.adaptation.chromatic_adaptation_CMCCAT2000`}, Luminance of test adapting field :math:`L_{A1}` in :math:`cd/m^2`. L_A2 : numeric or array_like {:func:`colour.adaptation.chromatic_adaptation_CMCCAT2000`}, Luminance of reference adapting field :math:`L_{A2}` in :math:`cd/m^2`. Y_n : numeric or array_like {:func:`colour.adaptation.chromatic_adaptation_Fairchild1990`}, Luminance :math:`Y_n` of test adapting stimulus in :math:`cd/m^2`. Y_o : numeric {:func:`colour.adaptation.chromatic_adaptation_CIE1994`}, Luminance factor :math:`Y_o` of achromatic background normalised to domain [0.18, 1] in **'Reference'** domain-range scale. direction : unicode, optional {:func:`colour.adaptation.chromatic_adaptation_CMCCAT2000`}, **{'Forward', 'Reverse'}**, Chromatic adaptation direction. discount_illuminant : bool, optional {:func:`colour.adaptation.chromatic_adaptation_Fairchild1990`}, Truth value indicating if the illuminant should be discounted. n : numeric, optional {:func:`colour.adaptation.chromatic_adaptation_CIE1994`}, Noise component in fundamental primary system. surround : CMCCAT2000_InductionFactors, optional {:func:`colour.adaptation.chromatic_adaptation_CMCCAT2000`}, Surround viewing conditions induction factors. transform : unicode, optional {:func:`colour.adaptation.chromatic_adaptation_VonKries`}, **{'CAT02', 'XYZ Scaling', 'Von Kries', 'Bradford', 'Sharp', 'Fairchild', 'CMCCAT97', 'CMCCAT2000', 'CAT02_BRILL_CAT', 'Bianco', 'Bianco PC'}**, Chromatic adaptation transform. Returns ------- ndarray *CIE XYZ_c* tristimulus values of the stimulus corresponding colour. Notes ----- +------------+-----------------------+---------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``XYZ`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ | ``XYZ_w`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ | ``XYZ_wr`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ | ``Y_o`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ +------------+-----------------------+---------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+===============+ | ``XYZ_c`` | [0, 1] | [0, 1] | +------------+-----------------------+---------------+ References ---------- :cite:`CIETC1-321994b`, :cite:`Fairchild1991a`, :cite:`Fairchild2013s`, :cite:`Fairchild2013t`, :cite:`Li2002a`, :cite:`Westland2012k` Examples -------- *Von Kries* chromatic adaptation: >>> import numpy as np >>> XYZ = np.array([0.20654008, 0.12197225, 0.05136952]) >>> XYZ_w = np.array([0.95045593, 1.00000000, 1.08905775]) >>> XYZ_wr = np.array([0.96429568, 1.00000000, 0.82510460]) >>> chromatic_adaptation(XYZ, XYZ_w, XYZ_wr) ... # doctest: +ELLIPSIS array([ 0.2163881..., 0.1257 , 0.0384749...]) *CIE 1994* chromatic adaptation, requires extra *kwargs*: >>> XYZ = np.array([0.2800, 0.2126, 0.0527]) >>> XYZ_w = np.array([1.09867452, 1.00000000, 0.35591556]) >>> XYZ_wr = np.array([0.95045593, 1.00000000, 1.08905775]) >>> Y_o = 0.20 >>> E_o = 1000 >>> chromatic_adaptation( ... XYZ, XYZ_w, XYZ_wr, method='CIE 1994', Y_o=Y_o, E_o1=E_o, E_o2=E_o) ... # doctest: +ELLIPSIS array([ 0.2403379..., 0.2115621..., 0.1764301...]) *CMCCAT2000* chromatic adaptation, requires extra *kwargs*: >>> XYZ = np.array([0.2248, 0.2274, 0.0854]) >>> XYZ_w = np.array([1.1115, 1.0000, 0.3520]) >>> XYZ_wr = np.array([0.9481, 1.0000, 1.0730]) >>> L_A = 200 >>> chromatic_adaptation( ... XYZ, XYZ_w, XYZ_wr, method='CMCCAT2000', L_A1=L_A, L_A2=L_A) ... # doctest: +ELLIPSIS array([ 0.1952698..., 0.2306834..., 0.2497175...]) *Fairchild (1990)* chromatic adaptation, requires extra *kwargs*: >>> XYZ = np.array([0.1953, 0.2307, 0.2497]) >>> Y_n = 200 >>> chromatic_adaptation( ... XYZ, XYZ_w, XYZ_wr, method='Fairchild 1990', Y_n=Y_n) ... # doctest: +ELLIPSIS array([ 0.2332526..., 0.2332455..., 0.7611593...]) """ function = CHROMATIC_ADAPTATION_METHODS[method] domain_range_reference = get_domain_range_scale() == 'reference' domain_100 = (chromatic_adaptation_CIE1994, chromatic_adaptation_CMCCAT2000, chromatic_adaptation_Fairchild1990) if function in domain_100 and domain_range_reference: XYZ = as_float_array(XYZ) * 100 XYZ_w = as_float_array(XYZ_w) * 100 XYZ_wr = as_float_array(XYZ_wr) * 100 if kwargs.get('Y_o'): kwargs['Y_o'] = kwargs['Y_o'] * 100 kwargs.update({'XYZ_w': XYZ_w, 'XYZ_wr': XYZ_wr}) if function is chromatic_adaptation_CIE1994: from colour import XYZ_to_xy kwargs.update({'xy_o1': XYZ_to_xy(XYZ_w), 'xy_o2': XYZ_to_xy(XYZ_wr)}) elif function is chromatic_adaptation_Fairchild1990: kwargs.update({'XYZ_n': XYZ_w, 'XYZ_r': XYZ_wr}) XYZ_c = function(XYZ, **filter_kwargs(function, **kwargs)) if function in domain_100 and domain_range_reference: XYZ_c /= 100 return XYZ_c
def eotf(value, function='ITU-R BT.1886', **kwargs): """ Decodes :math:`R'G'B'` video component signal value to tristimulus values at the display using given electro-optical transfer function (EOTF / EOCF). Parameters ---------- value : numeric or array_like Value. function : unicode, optional **{'ITU-R BT.1886', 'DCDM', 'DICOM GSDF', 'ITU-R BT.2020', 'ITU-R BT.2100 HLG', 'ITU-R BT.2100 PQ', 'ProPhoto RGB', 'RIMM RGB', 'ROMM RGB', 'SMPTE 240M', 'ST 2084'}**, Electro-optical transfer function (EOTF / EOCF). Other Parameters ---------------- E_clip : numeric, optional {:func:`colour.models.eotf_RIMMRGB`}, Maximum exposure level. I_max : numeric, optional {:func:`colour.models.eotf_ROMMRGB`, :func:`colour.models.eotf_RIMMRGB`}, Maximum code value: 255, 4095 and 650535 for respectively 8-bit, 12-bit and 16-bit per channel. L_B : numeric, optional {:func:`colour.models.eotf_BT1886`, :func:`colour.models.eotf_BT2100_HLG`}, Screen luminance for black. L_W : numeric, optional {:func:`colour.models.eotf_BT1886`, :func:`colour.models.eotf_BT2100_HLG`}, Screen luminance for white. L_p : numeric, optional {:func:`colour.models.eotf_ST2084`}, Display peak luminance :math:`cd/m^2`. gamma : numeric, optional {:func:`colour.models.eotf_BT2100_HLG`}, System gamma value, 1.2 at the nominal display peak luminance of :math:`1000 cd/m^2`. is_12_bits_system : bool {:func:`colour.models.eotf_BT2020`}, *ITU-R BT.2020* *alpha* and *beta* constants are used if system is not 12-bit. Returns ------- numeric or ndarray Tristimulus values at the display. Examples -------- >>> eotf(0.461356129500442) # doctest: +ELLIPSIS 0.1... >>> eotf(0.409007728864150, function='ITU-R BT.2020') ... # doctest: +ELLIPSIS 0.1... >>> eotf(0.182011532850008, function='ST 2084', L_p=1000) ... # doctest: +ELLIPSIS 0.1... """ function = EOTFS[function] return function(value, **filter_kwargs(function, **kwargs))
def scattering_cross_section(wavelength, CO2_concentration=STANDARD_CO2_CONCENTRATION, temperature=STANDARD_AIR_TEMPERATURE, avogadro_constant=AVOGADRO_CONSTANT, n_s=air_refraction_index_Bodhaine1999, F_air=F_air_Bodhaine1999): """ Returns the scattering cross section per molecule :math:`\\sigma` of dry air as function of wavelength :math:`\\lambda` in centimeters (cm) using given :math:`CO_2` concentration in parts per million (ppm) and temperature :math:`T[K]` in kelvin degrees following *Van de Hulst (1957)* method. Parameters ---------- wavelength : numeric or array_like Wavelength :math:`\\lambda` in centimeters (cm). CO2_concentration : numeric or array_like, optional :math:`CO_2` concentration in parts per million (ppm). temperature : numeric or array_like, optional Air temperature :math:`T[K]` in kelvin degrees. avogadro_constant : numeric or array_like, optional *Avogadro*'s number (molecules :math:`mol^{-1}`). n_s : object Air refraction index :math:`n_s` computation method. F_air : object :math:`(6+3_p)/(6-7_p)`, the depolarisation term :math:`F(air)` or *King Factor* computation method. Returns ------- numeric or ndarray Scattering cross section per molecule :math:`\\sigma` of dry air. Warning ------- Unlike most objects of :mod:`colour.phenomena.rayleigh` module, :func:`colour.scattering_cross_section` expects wavelength :math:`\\lambda` to be expressed in centimeters (cm). References ---------- :cite:`Bodhaine1999a`, :cite:`Wikipedia2001c` Examples -------- >>> scattering_cross_section(555 * 10e-8) # doctest: +ELLIPSIS 4.6613309...e-27 """ wl = as_float_array(wavelength) CO2_c = as_float_array(CO2_concentration) temperature = as_float_array(temperature) wl_micrometers = wl * 10e3 n_s = n_s(wl_micrometers) # n_s = n_s(**filter_kwargs( # n_s, wavelength=wl_micrometers, CO2_concentration=CO2_c)) N_s = molecular_density(temperature, avogadro_constant) F_air = F_air(**filter_kwargs( F_air, wavelength=wl_micrometers, CO2_concentration=CO2_c)) sigma = (24 * np.pi ** 3 * (n_s ** 2 - 1) ** 2 / (wl ** 4 * N_s ** 2 * (n_s ** 2 + 2) ** 2)) sigma *= F_air return sigma
def log_decoding_curve(value, curve='Cineon', **kwargs): """ Decodes :math:`R'G'B'` video component signal value to linear-light values using given *log* curve. Parameters ---------- value : numeric or array_like Value. curve : unicode, optional **{'ACEScc', 'ACEScct', 'ACESproxy', 'ALEXA Log C', 'Canon Log 2', 'Canon Log 3', 'Canon Log', 'Cineon', 'D-Log', 'ERIMM RGB', 'Filmic Pro 6', 'Log3G10', 'Log3G12', 'Panalog', 'PLog', 'Protune', 'REDLog', 'REDLogFilm', 'S-Log', 'S-Log2', 'S-Log3', 'T-Log', 'V-Log', 'ViperLog'}**, Computation curve. Other Parameters ---------------- EI : int, optional {:func:`colour.models.log_decoding_ALEXALogC`}, Ei. E_clip : numeric, optional {:func:`colour.models.log_decoding_ERIMMRGB`}, Maximum exposure limit. E_min : numeric, optional {:func:`colour.models.log_decoding_ERIMMRGB`}, Minimum exposure limit. I_max : numeric, optional {:func:`colour.models.log_decoding_ERIMMRGB`}, Maximum code value: 255, 4095 and 650535 for respectively 8-bit, 12-bit and 16-bit per channel. bit_depth : int, optional {:func:`colour.models.log_decoding_ACESproxy`, :func:`colour.models.log_decoding_SLog`, :func:`colour.models.log_decoding_SLog2`}, **{8, 10, 12}**, Bit depth used for conversion, *ACESproxy* uses **{10, 12}**. black_offset : numeric or array_like {:func:`colour.models.log_decoding_Cineon`, :func:`colour.models.log_decoding_Panalog`, :func:`colour.models.log_decoding_REDLog`, :func:`colour.models.log_decoding_REDLogFilm`}, Black offset. density_per_code_value : numeric or array_like {:func:`colour.models.log_decoding_PivotedLog`}, Density per code value. firmware : unicode, optional {:func:`colour.models.log_decoding_ALEXALogC`}, **{'SUP 3.x', 'SUP 2.x'}**, Alexa firmware version. in_legal : bool, optional {:func:`colour.models.log_decoding_SLog`, :func:`colour.models.log_decoding_SLog2`, :func:`colour.models.log_decoding_SLog3`}, Whether the non-linear *Sony S-Log*, *Sony S-Log2* or *Sony S-Log3* data :math:`y` is encoded in legal range. linear_reference : numeric or array_like {:func:`colour.models.log_decoding_PivotedLog`}, Linear reference. log_reference : numeric or array_like {:func:`colour.models.log_decoding_PivotedLog`}, Log reference. negative_gamma : numeric or array_like {:func:`colour.models.log_decoding_PivotedLog`}, Negative gamma. out_reflection : bool, optional {:func:`colour.models.log_decoding_SLog`, :func:`colour.models.log_decoding_SLog2`}, Whether the light level :math:`x` to a camera is reflection. method : unicode, optional {:func:`colour.models.log_decoding_ALEXALogC`}, **{'Linear Scene Exposure Factor', 'Normalised Sensor Signal'}**, Conversion method. Returns ------- numeric or ndarray *Log* value. Examples -------- >>> log_decoding_curve(0.457319613085418) # doctest: +ELLIPSIS 0.1... >>> log_decoding_curve(0.413588402492442, curve='ACEScc') ... # doctest: +ELLIPSIS 0.1... >>> log_decoding_curve(0.391006842619746, curve='PLog', log_reference=400) ... # doctest: +ELLIPSIS 0.1... >>> log_decoding_curve(0.376512722254600, curve='S-Log') ... # doctest: +ELLIPSIS 0.1... """ function = LOG_DECODING_CURVES[curve] return function(value, **filter_kwargs(function, **kwargs))
def whiteness(XYZ, XYZ_0, method='CIE 2004', **kwargs): """ Returns the *whiteness* :math:`W` using given method. Parameters ---------- XYZ : array_like *CIE XYZ* tristimulus values of sample. XYZ_0 : array_like *CIE XYZ* tristimulus values of reference white. method : unicode, optional **{'CIE 2004', 'Berger 1959', 'Taube 1960', 'Stensby 1968', 'ASTM E313', 'Ganz 1979'}**, Computation method. Other Parameters ---------------- observer : unicode, optional {:func:`colour.colorimetry.whiteness_CIE2004`}, **{'CIE 1931 2 Degree Standard Observer', 'CIE 1964 10 Degree Standard Observer'}**, *CIE Standard Observer* used for computations, *tint* :math:`T` or :math:`T_{10}` value is dependent on viewing field angular subtense. Returns ------- numeric or ndarray *whiteness* :math:`W`. Notes ----- +------------+-----------------------+-----------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+=================+ +------------+-----------------------+-----------------+ | ``XYZ`` | [0, 100] | [0, 1] | +------------+-----------------------+-----------------+ | ``XYZ_0`` | [0, 100] | [0, 1] | +------------+-----------------------+-----------------+ +------------+-----------------------+-----------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+=================+ | ``W`` | [0, 100] | [0, 1] | +------------+-----------------------+-----------------+ References ---------- :cite:`CIETC1-482004k`, :cite:`Wyszecki2000ba`, :cite:`X-Rite2012a`, :cite:`Wikipedia2004b` Examples -------- >>> import numpy as np >>> from colour.models import xyY_to_XYZ >>> XYZ = xyY_to_XYZ(np.array([0.3167, 0.3334, 100])) >>> XYZ_0 = xyY_to_XYZ(np.array([0.3139, 0.3311, 100])) >>> whiteness(XYZ, XYZ_0) # doctest: +ELLIPSIS array([ 93.85..., -1.305...]) >>> XYZ = np.array([95.00000000, 100.00000000, 105.00000000]) >>> XYZ_0 = np.array([94.80966767, 100.00000000, 107.30513595]) >>> whiteness(XYZ, XYZ_0, method='Taube 1960') # doctest: +ELLIPSIS 91.4071738... """ kwargs.update({'XYZ': XYZ, 'XYZ_0': XYZ_0}) function = WHITENESS_METHODS.get(method) if function is whiteness_Stensby1968: from colour.models import XYZ_to_Lab, XYZ_to_xy if get_domain_range_scale() == 'reference': XYZ = XYZ / 100 XYZ_0 = XYZ_0 / 100 kwargs.update({'Lab': XYZ_to_Lab(XYZ, XYZ_to_xy(XYZ_0))}) elif function in (whiteness_Ganz1979, whiteness_CIE2004): from colour.models import XYZ_to_xy _X_0, Y_0, _Z_0 = tsplit(XYZ_0) kwargs.update({ 'xy': XYZ_to_xy(XYZ), 'Y': Y_0, 'xy_n': XYZ_to_xy(XYZ_0) }) return function(**filter_kwargs(function, **kwargs))