Ejemplo n.º 1
0
    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))
Ejemplo n.º 2
0
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())
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
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))
Ejemplo n.º 6
0
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))
Ejemplo n.º 7
0
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))
Ejemplo n.º 8
0
    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)
Ejemplo n.º 9
0
    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)
Ejemplo n.º 10
0
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))
Ejemplo n.º 11
0
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
Ejemplo n.º 12
0
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
Ejemplo n.º 13
0
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)
Ejemplo n.º 14
0
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
Ejemplo n.º 15
0
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
Ejemplo n.º 16
0
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
Ejemplo n.º 17
0
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()
Ejemplo n.º 18
0
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)