def chromaticity_diagram_visual(samples=256, cmfs='CIE 1931 2 Degree Standard Observer', transformation='CIE 1931', parent=None): """ Creates a chromaticity diagram visual based on :class:`colour_analysis.visuals.Primitive` class. Parameters ---------- samples : int, optional Inner samples count used to construct the chromaticity diagram triangulation. cmfs : unicode, optional Standard observer colour matching functions used for the chromaticity diagram boundaries. transformation : unicode, optional **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**, Chromaticity diagram transformation. parent : Node, optional Parent of the chromaticity diagram in the `SceneGraph`. Returns ------- Primitive Chromaticity diagram visual. """ cmfs = first_item(filter_cmfs(cmfs).values()) illuminant = DEFAULT_PLOTTING_ILLUMINANT XYZ_to_ij = ( CHROMATICITY_DIAGRAM_TRANSFORMATIONS[transformation]['XYZ_to_ij']) ij_to_XYZ = ( CHROMATICITY_DIAGRAM_TRANSFORMATIONS[transformation]['ij_to_XYZ']) ij_c = XYZ_to_ij(cmfs.values, illuminant) triangulation = Delaunay(ij_c, qhull_options='QJ') samples = np.linspace(0, 1, samples) ii, jj = np.meshgrid(samples, samples) ij = tstack([ii, jj]) ij = np.vstack([ij_c, ij[triangulation.find_simplex(ij) > 0]]) ij_p = np.hstack([ij, np.full((ij.shape[0], 1), 0, DEFAULT_FLOAT_DTYPE)]) triangulation = Delaunay(ij, qhull_options='QJ') RGB = normalise_maximum( XYZ_to_sRGB(ij_to_XYZ(ij, illuminant), illuminant), axis=-1) diagram = Primitive( vertices=ij_p, faces=triangulation.simplices, vertex_colours=RGB, parent=parent) return diagram
def spectrum_to_rgb( wavelength, spectrum, # cmfs=None, illuminant='LED-B3', Y=None, ): """ Calculate the rgb color given a wavelength and spectrum. Note spectrum should have spacing of 1, 5, 10 or 10 nm. Parameters ---------- wavelength spectrum cmfs illuminant Returns ------- """ # if is_uniform(wavelength) and interval(wavelength) XYZ = spectrum_to_XYZ( wavelength=wavelength, spectrum=spectrum, # cmfs=cmfs, illuminant=illuminant) XYZ = XYZ / 100 if Y is not None: xyY = XYZ_to_xyY(XYZ) xyY[2] = Y XYZ = xyY_to_XYZ(xyY) # Convert to rgb. Note the illuminant doesn't matter here except for points # where XYZ=0. rgb = XYZ_to_sRGB(XYZ) return rgb
def spectral_locus_visual(reference_colourspace='CIE xyY', cmfs='CIE 1931 2 Degree Standard Observer', width=2.0, uniform_colour=None, uniform_opacity=1.0, method='gl', parent=None): """ Returns a :class:`vispy.scene.visuals.Line` class instance representing the spectral locus. Parameters ---------- reference_colourspace : unicode, optional **{'CIE XYZ', 'CIE xyY', 'CIE Lab', 'CIE Luv', 'CIE UCS', 'CIE UVW', 'IPT', 'Hunter Lab', 'Hunter Rdab'}**, Reference colourspace to use for colour conversions / transformations. cmfs : unicode, optional Standard observer colour matching functions used to draw the spectral locus. width : numeric, optional Line width. uniform_colour : array_like, optional Uniform symbol colour. uniform_opacity : numeric, optional Uniform symbol opacity. method : unicode, optional **{'gl', 'agg'}**, Line drawing method. parent : Node, optional Parent of the spectral locus visual in the `SceneGraph`. Returns ------- Line Spectral locus visual. """ cmfs = first_item(filter_cmfs(cmfs).values()) XYZ = cmfs.values XYZ = np.vstack([XYZ, XYZ[0, ...]]) illuminant = DEFAULT_PLOTTING_ILLUMINANT points = common_colourspace_model_axis_reorder( XYZ_to_colourspace_model(XYZ, illuminant, reference_colourspace), reference_colourspace) points[np.isnan(points)] = 0 if uniform_colour is None: RGB = normalise_maximum(XYZ_to_sRGB(XYZ, illuminant), axis=-1) RGB = np.hstack([ RGB, np.full((RGB.shape[0], 1), uniform_opacity, DEFAULT_FLOAT_DTYPE) ]) else: RGB = ColorArray(uniform_colour, alpha=uniform_opacity).rgba line = Line(points, np.clip(RGB, 0, 1), width=width, method=method, parent=parent) return line