def __init__( self, sds, shape, cmfs=STANDARD_OBSERVER_CMFS['CIE 1931 2 Degree Standard Observer'], illuminant=sd_ones()): """ Parameters ---------- sds : ndarray (n,m) Reflectances of the ``n`` reference colours to be used for optimisation. shape : SpectralShape Spectral shape of ``sds``. cmfs : XYZ_ColourMatchingFunctions, optional Standard observer colour matching functions. illuminant : SpectralDistribution, optional Illuminant spectral distribution. """ self.shape = shape self.wl = shape.range() self.dw = self.wl[1] - self.wl[0] self.cmfs = cmfs.copy().align(shape) self.illuminant = illuminant.copy().align(shape) self.xy_w = XYZ_to_xy(sd_to_XYZ(illuminant, cmfs=cmfs)) # The normalising constant used in sd_to_XYZ. self.k = 1 / (np.sum(self.cmfs.values[:, 1] * self.illuminant.values) * self.dw) # Python 3: super().__init__(...) super(Otsu2018Tree, self).__init__(self, Colours(self, sds))
def XYZ_to_sd_Otsu2018( XYZ, cmfs=STANDARD_OBSERVER_CMFS['CIE 1931 2 Degree Standard Observer']. copy().align(OTSU_2018_SPECTRAL_SHAPE), illuminant=ILLUMINANT_SDS['D65'].copy().align( OTSU_2018_SPECTRAL_SHAPE), clip=True): XYZ = as_float_array(XYZ) xy = XYZ_to_xy(XYZ) cluster = select_cluster_Otsu2018(xy) basis_functions = OTSU_2018_BASIS_FUNCTIONS[cluster] mean = OTSU_2018_MEANS[cluster] M = np.empty((3, 3)) for i in range(3): sd = SpectralDistribution( basis_functions[i, :], OTSU_2018_SPECTRAL_SHAPE.range(), ) M[:, i] = sd_to_XYZ(sd, illuminant=illuminant) / 100 M_inverse = np.linalg.inv(M) sd = SpectralDistribution(mean, OTSU_2018_SPECTRAL_SHAPE.range()) XYZ_mu = sd_to_XYZ(sd, illuminant=illuminant) / 100 weights = np.dot(M_inverse, XYZ - XYZ_mu) recovered_sd = np.dot(weights, basis_functions) + mean if clip: recovered_sd = np.clip(recovered_sd, 0, 1) return SpectralDistribution(recovered_sd, OTSU_2018_SPECTRAL_SHAPE.range())
def mutiple(): cmfs = CMFS['CIE 1931 2 Degree Standard Observer'] spd = [] for d in ['test.txt', 'test1.txt']: with open(d) as f: data = pd.read_csv(f, sep="\t" or ' ' or ',', header=None) f.close() w = [i[0] for i in data.values] s = [i[1] for i in data.values] data_formated = dict(zip(w, s)) spd.append(SpectralPowerDistribution('Sample', data_formated)) b = multi_spd_plot(spd, standalone=False, figure_size=(5, 5), title='Spectrum') figfile_b = StringIO() b.savefig(figfile_b, format='svg') figfile_b.seek(0) figdata_svg_b = '<svg' + figfile_b.getvalue().split('<svg')[1] b.clf() plot.close(b) CIE_1931_chromaticity_diagram_plot(standalone=False, figure_size=(5, 5), grid=False, title='CIE 1931 Chromaticity Diagram', bounding_box=(-0.1, 0.9, -0.05, 0.95)) illuminant = ILLUMINANTS_RELATIVE_SPDS['D50'] for s in spd: XYZ = spectral_to_XYZ(s, cmfs, illuminant) xy = XYZ_to_xy(XYZ) print(xy) x, y = xy pylab.plot(x, y, 'o-', color='white') pylab.annotate((("%.4f" % x), ("%.4f" % y)), xy=xy, xytext=(-50, 30), textcoords='offset points', arrowprops=dict(arrowstyle='->', connectionstyle='arc3, rad=-0.2')) a = plot.gcf() figfile = StringIO() a.savefig(figfile, format='svg') figfile.seek(0) figdata_svg = '<svg' + figfile.getvalue().split('<svg')[1] a.clf() plot.close(a) del a, b # pprint.pprint(figdata_svg) return render_template('index.html', spd=figdata_svg_b, result=figdata_svg)
def get_cct(self, methods="Hernandez 1999"): ''' approximate CCT using CIE 1931 xy values ''' x, y, z = self.get_xyz() if 0 in [x, y, z]: return 0.0 logs.logger.debug(f"x = {x}, y = {y}, z = {z}") if isinstance(methods, str): methods = [methods] ccts = list() for curr_method in methods: if curr_method == 'me_mccamy': # McCamy's Approx small_x = x / (x + y + z) small_y = y / (x + y + z) n = (small_x - 0.3320) / (0.1858 - small_y) cct = 437 * (n**3) + 3601 * (n**2) + 6861 * n + 5517 if DEBUG: logs.logger.debug( f"[me_mccamy] calc x = {small_x}, calc y = {small_y} | Calc CCT = {cct} K" ) elif curr_method in XY_TO_CCT_METHODS: xyz_arr = np_array([x, y, z]) xy_arr = XYZ_to_xy(xyz_arr) cct = xy_to_CCT(xy_arr, curr_method) if DEBUG: logs.logger.debug( f"[{curr_method}] calc x,y = {xy_arr} | CCT = {cct}") else: options = ["me_mccamy"] + list(XY_TO_CCT_METHODS) logs.logger.error( f"{curr_method} Not found!\nCCT calculation methods: \n {options}" ) return ccts.append(int(cct)) if len(ccts) == 1: return ccts[0] else: return ccts
def calc_day_light_xy(temperature=6500, cmfs_name=cm.CIE1931): day_light_spd = cm.get_day_light_spd(temperature) cmfs = cm.load_cmfs(cmfs_name) normalize_coef = cm.get_nomalize_large_y_coef( d_light_before_trim=day_light_spd, cmfs_before_trim=cmfs) # trim shape = cm.calc_appropriate_shape(day_light_spd, cmfs) day_light_spd.trim(shape) cmfs.trim(shape) # calc large_xyz = [ np.sum(day_light_spd.values * cmfs.values[:, x]) * normalize_coef for x in range(3) ] print(large_xyz) print(XYZ_to_xy(large_xyz))
def get_normalize_large_y_param_cie1931_5nm_test(): temperature = 5000 shape = SpectralShape(380, 780) coef = get_normalize_large_y_param_cie1931_5nm(temperature) d_light = make_day_light_by_calculation(temperature=temperature, interpolater=LinearInterpolator, interval=5) d_light.trim(shape) cmfs_cie1931 = load_cie1931_1nm_data().trim(shape) cmfs_cie1931_5nm = cmfs_cie1931.values[::5] large_x = np.sum(d_light.values * cmfs_cie1931_5nm[:, 0]) large_y = np.sum(d_light.values * cmfs_cie1931_5nm[:, 1]) large_z = np.sum(d_light.values * cmfs_cie1931_5nm[:, 2]) large_xyz = [large_x * coef, large_y * coef, large_z * coef] print(large_xyz) print(XYZ_to_xy(large_xyz))
def calc_cie2015_d65_white_xy(): shape = SpectralShape(390, 830, 1) cmfs = STANDARD_OBSERVERS_CMFS['CIE 2012 2 Degree Standard Observer'] d65_spd = load_d65_spd_1nmdata().trim(shape) d65_1nm = d65_spd.values[:, 1] cmfs_1nm = cmfs.values large_x = np.sum(d65_1nm * cmfs_1nm[:, 0]) large_y = np.sum(d65_1nm * cmfs_1nm[:, 1]) large_z = np.sum(d65_1nm * cmfs_1nm[:, 2]) normalize_coef = 100 / large_y large_xyz = [ large_x * normalize_coef, large_y * normalize_coef, large_z * normalize_coef ] print(large_xyz) print(XYZ_to_xy(large_xyz))
def reconstruct(self, XYZ): """ Reconstructs the reflectance for the given *XYZ* tristimulus values. If this is a leaf, data from this node will be used. Otherwise the code will look for the appropriate subnode. Parameters ========== XYZ : ndarray, (3,) *CIE XYZ* tristimulus values to recover the spectral distribution from. Returns ------- SpectralDistribution Recovered spectral distribution. """ xy = XYZ_to_xy(XYZ) return self._reconstruct_xy(XYZ, xy)
def __init__(self, tree, reflectances): """ Parameters ========== tree : tree The parent tree. This determines what cmfs and illuminant are used in colourimetric calculations. reflectances : ndarray (n,m) Reflectances of the ``n`` colours to be stored in this class. The shape must match ``tree.shape`` with ``m`` points for each colour. """ self.reflectances = reflectances self.XYZ = np.empty((reflectances.shape[0], 3)) self.xy = np.empty((reflectances.shape[0], 2)) for i in range(len(self)): sd = SpectralDistribution(reflectances[i, :], tree.wl) XYZ = sd_to_XYZ(sd, illuminant=tree.illuminant) / 100 self.XYZ[i, :] = XYZ self.xy[i, :] = XYZ_to_xy(XYZ)
def calc_d65_white_xy(): """ とりあえず D65 White の XYZ および xy を求めてみる。 """ # temperature = 6500 # d65_spd = make_day_light_by_calculation(temperature=temperature, # interpolater=LinearInterpolator, # interval=5) # d65_spd.values = fit_significant_figures(d65_spd.values, 6) d65_spd = load_d65_spd_1nmdata().trim(SpectralShape(380, 780)) cmfs_cie1931 = load_cie1931_1nm_data().trim(SpectralShape(380, 780)) d65_spd_5nm = d65_spd.values[::5] cmfs_cie1931_5nm = cmfs_cie1931.values[::5] large_x = np.sum(d65_spd_5nm[:, 1] * cmfs_cie1931_5nm[:, 0]) large_y = np.sum(d65_spd_5nm[:, 1] * cmfs_cie1931_5nm[:, 1]) large_z = np.sum(d65_spd_5nm[:, 1] * cmfs_cie1931_5nm[:, 2]) normalize_coef = 100 / large_y large_xyz = [ large_x * normalize_coef, large_y * normalize_coef, large_z * normalize_coef ] print(large_xyz) print(XYZ_to_xy(large_xyz))
from colour import (Luv_to_uv, Luv_uv_to_xy, UCS_to_uv, UCS_uv_to_xy, xy_to_XYZ, XYZ_to_Luv, XYZ_to_UCS, XYZ_to_xy) __author__ = 'Colour Developers' __copyright__ = 'Copyright (C) 2013-2019 - Colour Developers' __license__ = 'New BSD License - https://opensource.org/licenses/BSD-3-Clause' __maintainer__ = 'Colour Developers' __email__ = '*****@*****.**' __status__ = 'Production' __all__ = ['CHROMATICITY_DIAGRAM_TRANSFORMATIONS', 'Cycle'] CHROMATICITY_DIAGRAM_TRANSFORMATIONS = { 'CIE 1931': { 'XYZ_to_ij': lambda a, i: XYZ_to_xy(a, i), 'ij_to_XYZ': lambda a, i: xy_to_XYZ(a) }, 'CIE 1960 UCS': { 'XYZ_to_ij': lambda a, i: UCS_to_uv(XYZ_to_UCS(a)), 'ij_to_XYZ': lambda a, i: xy_to_XYZ(UCS_uv_to_xy(a)) }, 'CIE 1976 UCS': { 'XYZ_to_ij': lambda a, i: Luv_to_uv(XYZ_to_Luv(a, i), i), 'ij_to_XYZ': lambda a, i: xy_to_XYZ(Luv_uv_to_xy(a)) } } """ Chromaticity diagram specific helper conversion objects. CHROMATICITY_DIAGRAM_TRANSFORMATIONS : dict
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 index(): cmfs = CMFS['CIE 1931 2 Degree Standard Observer'] with open('test.txt') as f: data = pd.read_csv(f, sep="\t" or ' ' or ',', header=None) f.close() w = [i[0] for i in data.values] s = [i[1] for i in data.values] data_formated = dict(zip(w, s)) spd = SpectralPowerDistribution('Sample', data_formated) b = single_spd_plot(spd, standalone=False, figure_size=(5, 5), title='Spectrum') figfile_b = StringIO() b.savefig(figfile_b, format='svg') figfile_b.seek(0) figdata_svg_b = '<svg' + figfile_b.getvalue().split('<svg')[1] b.clf() plot.close(b) illuminant = ILLUMINANTS_RELATIVE_SPDS['D50'] XYZ = spectral_to_XYZ(spd, cmfs, illuminant) xy = XYZ_to_xy(XYZ) print(xy) cct = xy_to_CCT(xy) print(cct) cri = colour_rendering_index(spd, additional_data=True) print(cri.Q_a) Q_as = cri.Q_as y = [s[1].Q_a for s in sorted(Q_as.items(), key=lambda s: s[0])] print(y) single_spd_colour_rendering_index_bars_plot(spd, standalone=False, figure_size=(7, 7), title='Colour rendering index') c = plot.gcf() figfile_c = StringIO() c.savefig(figfile_c, format='svg') figfile_c.seek(0) figdata_svg_c = '<svg' + figfile_c.getvalue().split('<svg')[1] c.clf() plot.close(c) CIE_1931_chromaticity_diagram_plot(standalone=False, figure_size=(6, 5), grid=False, title='CIE 1931 Chromaticity Diagram', bounding_box=(-0.1, 0.9, -0.05, 0.95)) x, y = xy pylab.plot(x, y, 'o-', color='white') pylab.annotate((("%.4f" % x), ("%.4f" % y)), xy=xy, xytext=(-50, 30), textcoords='offset points', arrowprops=dict(arrowstyle='->', connectionstyle='arc3, rad=-0.2')) a = plot.gcf() figfile = StringIO() a.savefig(figfile, format='svg') figfile.seek(0) figdata_svg = '<svg' + figfile.getvalue().split('<svg')[1] a.clf() plot.close(a) del a, b, c # pprint.pprint(figdata_svg) return render_template('index.html', spd=figdata_svg_b, result=figdata_svg, colour_rendering_index=figdata_svg_c)
def RGB_to_CCT(rgb): RGB = np.array(rgb) XYZ = sRGB_to_XYZ(RGB / 255) xy = XYZ_to_xy(XYZ) CCT = xy_to_CCT(xy, "hernandez1999") return CCT
def chromatic_adaptation( XYZ: ArrayLike, XYZ_w: ArrayLike, XYZ_wr: ArrayLike, method: Union[Literal["CIE 1994", "CMCCAT2000", "Fairchild 1990", "Zhai 2018", "Von Kries", ], str, ] = "Von Kries", **kwargs: Any, ) -> NDArray: """ Adapt given stimulus from test viewing conditions to reference viewing conditions. Parameters ---------- XYZ *CIE XYZ* tristimulus values of stimulus to adapt. XYZ_w Test viewing condition *CIE XYZ* tristimulus values of the whitepoint. XYZ_wr Reference viewing condition *CIE XYZ* tristimulus values of the whitepoint. method Computation method. Other Parameters ---------------- E_o1 {:func:`colour.adaptation.chromatic_adaptation_CIE1994`}, Test illuminance :math:`E_{o1}` in :math:`cd/m^2`. E_o2 {:func:`colour.adaptation.chromatic_adaptation_CIE1994`}, Reference illuminance :math:`E_{o2}` in :math:`cd/m^2`. n {:func:`colour.adaptation.chromatic_adaptation_CIE1994`}, Noise component in fundamental primary system. Y_o {: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 {:func:`colour.adaptation.chromatic_adaptation_CMCCAT2000`}, Chromatic adaptation direction. L_A1 {:func:`colour.adaptation.chromatic_adaptation_CMCCAT2000`}, Luminance of test adapting field :math:`L_{A1}` in :math:`cd/m^2`. L_A2 {:func:`colour.adaptation.chromatic_adaptation_CMCCAT2000`}, Luminance of reference adapting field :math:`L_{A2}` in :math:`cd/m^2`. surround {:func:`colour.adaptation.chromatic_adaptation_CMCCAT2000`}, Surround viewing conditions induction factors. discount_illuminant {:func:`colour.adaptation.chromatic_adaptation_Fairchild1990`}, Truth value indicating if the illuminant should be discounted. Y_n {:func:`colour.adaptation.chromatic_adaptation_Fairchild1990`}, Luminance :math:`Y_n` of test adapting stimulus in :math:`cd/m^2`. D_b {:func:`colour.adaptation.chromatic_adaptation_Zhai2018`}, Degree of adaptation :math:`D_\\beta` of input illuminant :math:`\\beta`. D_d {:func:`colour.adaptation.chromatic_adaptation_Zhai2018`}, Degree of adaptation :math:`D_\\Delta` of output illuminant :math:`\\Delta`. transform {:func:`colour.adaptation.chromatic_adaptation_VonKries`, :func:`colour.adaptation.chromatic_adaptation_Zhai2018`}, Chromatic adaptation transform. XYZ_wo {:func:`colour.adaptation.chromatic_adaptation_Zhai2018`}, Baseline illuminant (:math:`BI`) :math:`o`. Returns ------- :class:`numpy.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] | +------------+-----------------------+---------------+ | ``XYZ_wo`` | [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...]) *Zhai and Luo (2018)* chromatic adaptation: >>> 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, method='Zhai 2018') ... # doctest: +ELLIPSIS array([ 0.2163881..., 0.1257 , 0.0384749...]) >>> chromatic_adaptation( ... XYZ, XYZ_w, XYZ_wr, method='Zhai 2018', D_b=0.9, ... XYZ_wo=np.array([100, 100, 100])) ... # doctest: +ELLIPSIS array([ 0.2152436..., 0.1253522..., 0.0388406...]) """ method = validate_method(method, CHROMATIC_ADAPTATION_METHODS) function = CHROMATIC_ADAPTATION_METHODS[method] domain_range_reference = get_domain_range_scale() == "reference" domain_100 = ( chromatic_adaptation_CIE1994, chromatic_adaptation_CMCCAT2000, chromatic_adaptation_Fairchild1990, chromatic_adaptation_Zhai2018, ) 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 "Y_o" in kwargs: kwargs["Y_o"] = kwargs["Y_o"] * 100 if "XYZ_wo" in kwargs: kwargs["XYZ_wo"] = kwargs["XYZ_wo"] * 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}) elif function is chromatic_adaptation_Zhai2018: kwargs.update({"XYZ_wb": XYZ_w, "XYZ_wd": 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 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 as percentage in domain [18, 100]. 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. 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.07049534, 0.10080000, 0.09558313]) >>> XYZ_w = np.array([1.09846607, 1.00000000, 0.35582280]) >>> XYZ_wr = np.array([0.95042855, 1.00000000, 1.08890037]) >>> chromatic_adaptation(XYZ, XYZ_w, XYZ_wr) ... # doctest: +ELLIPSIS array([ 0.0839746..., 0.1141321..., 0.2862554...]) *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 = 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...]) """ XYZ = np.asarray(XYZ) XYZ_w = np.asarray(XYZ_w) XYZ_wr = np.asarray(XYZ_wr) function = CHROMATIC_ADAPTATION_METHODS[method] # Callables with percentage domain. # TODO: Handle scaling with metadata. percentage_domain = (chromatic_adaptation_CIE1994, chromatic_adaptation_CMCCAT2000, chromatic_adaptation_Fairchild1990) if function in percentage_domain: XYZ = XYZ * 100 XYZ_w = XYZ_w * 100 XYZ_wr = XYZ_wr * 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 percentage_domain: XYZ_c /= 100 return XYZ_c
cmfs = CMFS['CIE 1931 2 Degree Standard Observer'] with open('test.txt') as f: data = pd.read_csv(f, sep="\t" or ' ' or ',', header=None) f.close() w = [i[0] for i in data.values] s = [i[1] for i in data.values] data_formated = dict(zip(w, s)) print(data) print(data.values) print(data_formated) spd = SpectralPowerDistribution('Sample', data_formated) illuminant = ILLUMINANTS_RELATIVE_SPDS['D50'] XYZ = spectral_to_XYZ(spd, cmfs, illuminant) print(XYZ) xy = XYZ_to_xy(XYZ) print(xy) CIE_1931_chromaticity_diagram_plot(standalone=False) x, y = xy pylab.plot(x, y, 'o-', color='white') pylab.annotate('test', xy=xy, xytext=(-50, 30), textcoords='offset points', arrowprops=dict(arrowstyle='->', connectionstyle='arc3, rad=-0.2')) a = display(standalone=False) print(type(a)) figfile = BytesIO()
from Quartz.CoreGraphics import CGGetDisplayTransferByTable, CGMainDisplayID from colour import xy_to_CCT_Hernandez1999, XYZ_to_xy, sRGB_to_XYZ from time import sleep lasttemp = None while True: (_, red, green, blue, _) = CGGetDisplayTransferByTable(CGMainDisplayID(), 3, None, None, None, None) rgb = [red[2], green[2], blue[2]] # print("rgb", rgb) temp = xy_to_CCT_Hernandez1999(XYZ_to_xy(sRGB_to_XYZ(rgb))) if temp != lasttemp: print temp sleeptime = 0.1 else: sleeptime = 1 lasttemp = temp sleep(sleeptime)