Ejemplo n.º 1
0
    def test_filter_RGB_colourspaces(self):
        """
        Test :func:`colour.plotting.common.filter_RGB_colourspaces`
        definition.
        """

        self.assertListEqual(
            sorted(colourspace.name for colourspace in filter_RGB_colourspaces(
                ["^ACES.*"]).values()),
            ["ACES2065-1", "ACEScc", "ACEScct", "ACEScg", "ACESproxy"],
        )
Ejemplo n.º 2
0
    def test_filter_RGB_colourspaces(self):
        """
        Tests :func:`colour.plotting.common.filter_RGB_colourspaces`
        definition.
        """

        self.assertListEqual(
            sorted([
                colourspace.name for colourspace in filter_RGB_colourspaces(
                    ['^ACES.*']).values()
            ]), ['ACES2065-1', 'ACEScc', 'ACEScct', 'ACEScg', 'ACESproxy'])
def RGB_colourspace_volume_visual(colourspace=PRIMARY_COLOURSPACE,
                                  colourspace_model=COLOURSPACE_MODEL,
                                  segments=16,
                                  wireframe=False):
    """
    Returns a RGB colourspace volume visual geometry formatted as *JSON*.

    Parameters
    ----------
    colourspace : unicode, optional
        RGB colourspace used to generate the visual geometry.
    colourspace_model : unicode, optional
        Colourspace model used to generate the visual geometry.
    segments : int, optional
        Segments count per side of the *box* used to generate the visual
        geometry.
    wireframe : bool, optional
        Whether the visual geometry must represent a wireframe visual.

    Returns
    -------
    unicode
        RGB colourspace volume visual geometry formatted as *JSON*.
    """

    colourspace = first_item(
        filter_RGB_colourspaces(re.escape(colourspace)).values())

    cube = conform_primitive_dtype(
        primitive_cube(width_segments=segments,
                       height_segments=segments,
                       depth_segments=segments))

    vertices = cube[0]['position'] + 0.5
    faces = colourspace_model_faces_reorder(np.reshape(cube[1], (-1, 1)),
                                            colourspace_model)
    RGB = cube[0]['colour']

    XYZ = RGB_to_XYZ(
        vertices,
        colourspace.whitepoint,
        colourspace.whitepoint,
        colourspace.matrix_RGB_to_XYZ,
    )
    vertices = colourspace_model_axis_reorder(
        XYZ_to_colourspace_model(
            XYZ,
            colourspace.whitepoint,
            colourspace_model,
        ), colourspace_model)

    return buffer_geometry(position=vertices, color=RGB, index=faces)
def RGB_colourspace_triangle_visual(colourspace='ITU-R BT.709',
                                    diagram='CIE 1931',
                                    uniform_colour=None,
                                    uniform_opacity=1.0,
                                    width=4.0,
                                    parent=None):
    """
    Returns a :class:`vispy.scene.visuals.Line` class instance representing
    a *RGB* colourspace triangle visual.

    Parameters
    ----------
    colourspace : unicode, optional
        See :func:`RGB_colourspace_volume_visual` argument for possible values.

        :class:`colour.RGB_Colourspace` class instance name defining the *RGB*
        colourspace triangle to draw.
    diagram : unicode, optional
        **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**,
        Chromaticity diagram to use.
    uniform_colour : array_like, optional
        Uniform triangle colour.
    uniform_opacity : numeric, optional
        Uniform mesh opacity.
    width : numeric, optional
        Triangle edge width.
    parent : Node, optional
        Parent of the *RGB* colourspace volume visual in the `SceneGraph`.
    """

    if uniform_colour is None:
        uniform_colour = (0.8, 0.8, 0.8)

    colourspace = first_item(filter_RGB_colourspaces(colourspace).values())

    illuminant = DEFAULT_PLOTTING_ILLUMINANT

    XYZ_to_ij = CHROMATICITY_DIAGRAM_TRANSFORMATIONS[diagram]['XYZ_to_ij']

    ij = XYZ_to_ij(xy_to_XYZ(colourspace.primaries), illuminant)
    # TODO: Remove following hack dealing with 'agg' method issues.
    ij = np.vstack([ij[-1, ...], ij, ij[0, ...]])

    ij[np.isnan(ij)] = 0

    RGB = np.hstack([uniform_colour, uniform_opacity])

    line = Line(ij, RGB, width=width, method='agg', parent=parent)

    return line
Ejemplo n.º 5
0
def RGB_colourspace_triangle_visual(colourspace='ITU-R BT.709',
                                    diagram='CIE 1931',
                                    uniform_colour=None,
                                    uniform_opacity=1.0,
                                    width=4.0,
                                    parent=None):
    """
    Returns a :class:`vispy.scene.visuals.Line` class instance representing
    a *RGB* colourspace triangle visual.

    Parameters
    ----------
    colourspace : unicode, optional
        See :func:`RGB_colourspace_volume_visual` argument for possible values.

        :class:`colour.RGB_Colourspace` class instance name defining the *RGB*
        colourspace triangle to draw.
    diagram : unicode, optional
        **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**,
        Chromaticity diagram to use.
    uniform_colour : array_like, optional
        Uniform triangle colour.
    uniform_opacity : numeric, optional
        Uniform mesh opacity.
    width : numeric, optional
        Triangle edge width.
    parent : Node, optional
        Parent of the *RGB* colourspace volume visual in the `SceneGraph`.
    """

    if uniform_colour is None:
        uniform_colour = (0.8, 0.8, 0.8)

    colourspace = first_item(filter_RGB_colourspaces(colourspace).values())

    illuminant = DEFAULT_PLOTTING_ILLUMINANT

    XYZ_to_ij = CHROMATICITY_DIAGRAM_TRANSFORMATIONS[diagram]['XYZ_to_ij']

    ij = XYZ_to_ij(xy_to_XYZ(colourspace.primaries), illuminant)
    # TODO: Remove following hack dealing with 'agg' method issues.
    ij = np.vstack([ij[-1, ...], ij, ij[0, ...]])

    ij[np.isnan(ij)] = 0

    RGB = np.hstack([uniform_colour, uniform_opacity])

    line = Line(ij, RGB, width=width, method='agg', parent=parent)

    return line
Ejemplo n.º 6
0
def RGB_colourspace_whitepoint_axis_visual(colourspace='ITU-R BT.709',
                                           reference_colourspace='CIE xyY',
                                           width=2.0,
                                           method='gl',
                                           parent=None):
    """
    Returns a :class:`vispy.scene.visuals.Line` class instance representing
    a given RGB colourspace whitepoint axis.

    Parameters
    ----------
    colourspace : unicode, optional
        See :func:`RGB_colourspace_volume_visual` argument for possible values.

        :class:`colour.RGB_Colourspace` class instance name defining the *RGB*
        colourspace whitepoint axis to draw.
    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.
    width : numeric, optional
        Line width.
    method : unicode, optional
        **{'gl', 'agg'}**,
        Line drawing method.
    parent : Node, optional
        Parent of the spectral locus visual in the `SceneGraph`.

    Returns
    -------
    Line
        RGB colourspace whitepoint axis.
    """

    colourspace = first_item(filter_RGB_colourspaces(colourspace).values())
    XYZ_o = xy_to_XYZ(colourspace.whitepoint + (0, ))
    XYZ_f = xy_to_XYZ(colourspace.whitepoint + (1.1, ))
    XYZ_l = np.vstack([XYZ_o, XYZ_f])

    illuminant = DEFAULT_PLOTTING_ILLUMINANT

    points = common_colourspace_model_axis_reorder(
        XYZ_to_colourspace_model(XYZ_l, illuminant, reference_colourspace),
        reference_colourspace)

    line = Line(points, (1, 1, 1), width=width, method=method, parent=parent)

    return line
def RGB_colourspace_whitepoint_axis_visual(colourspace='ITU-R BT.709',
                                           reference_colourspace='CIE xyY',
                                           width=2.0,
                                           method='gl',
                                           parent=None):
    """
    Returns a :class:`vispy.scene.visuals.Line` class instance representing
    a given RGB colourspace whitepoint axis.

    Parameters
    ----------
    colourspace : unicode, optional
        See :func:`RGB_colourspace_volume_visual` argument for possible values.

        :class:`colour.RGB_Colourspace` class instance name defining the *RGB*
        colourspace whitepoint axis to draw.
    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.
    width : numeric, optional
        Line width.
    method : unicode, optional
        **{'gl', 'agg'}**,
        Line drawing method.
    parent : Node, optional
        Parent of the spectral locus visual in the `SceneGraph`.

    Returns
    -------
    Line
        RGB colourspace whitepoint axis.
    """

    colourspace = first_item(filter_RGB_colourspaces(colourspace).values())
    XYZ_o = xy_to_XYZ(colourspace.whitepoint + (0, ))
    XYZ_f = xy_to_XYZ(colourspace.whitepoint + (1.1, ))
    XYZ_l = np.vstack([XYZ_o, XYZ_f])

    illuminant = DEFAULT_PLOTTING_ILLUMINANT

    points = common_colourspace_model_axis_reorder(
        XYZ_to_colourspace_model(XYZ_l, illuminant, reference_colourspace),
        reference_colourspace)

    line = Line(points, (1, 1, 1), width=width, method=method, parent=parent)

    return line
def spectral_locus_visual(colourspace=PRIMARY_COLOURSPACE,
                          colourspace_model=COLOURSPACE_MODEL,
                          cmfs='CIE 1931 2 Degree Standard Observer'):
    """
    Returns the spectral locus visual geometry formatted as *JSON*.

    Parameters
    ----------
    colourspace : unicode, optional
        RGB colourspace used to generate the visual geometry.
    colourspace_model : unicode, optional
        Colourspace model used to generate the visual geometry.
    cmfs : unicode, optional
        Standard observer colour matching functions used to draw the spectral
        locus.

    Returns
    -------
    unicode
        Spectral locus visual geometry formatted as *JSON*.
    """

    colourspace = first_item(
        filter_RGB_colourspaces(re.escape(colourspace)).values())

    cmfs = first_item(filter_cmfs(cmfs).values())
    XYZ = cmfs.values

    XYZ = np.vstack([XYZ, XYZ[0, ...]])

    vertices = colourspace_model_axis_reorder(
        XYZ_to_colourspace_model(
            XYZ,
            colourspace.whitepoint,
            colourspace_model,
        ), colourspace_model)

    RGB = normalise_maximum(XYZ_to_RGB(
        XYZ,
        colourspace.whitepoint,
        colourspace.whitepoint,
        colourspace.matrix_XYZ_to_RGB,
    ),
                            axis=-1)

    return buffer_geometry(position=vertices, color=RGB)
Ejemplo n.º 9
0
def plot_RGB_colourspaces_gamuts(colourspaces=None,
                                 reference_colourspace='CIE xyY',
                                 segments=8,
                                 show_grid=True,
                                 grid_segments=10,
                                 show_spectral_locus=False,
                                 spectral_locus_colour=None,
                                 cmfs='CIE 1931 2 Degree Standard Observer',
                                 **kwargs):
    """
    Plots given *RGB* colourspaces gamuts in given reference colourspace.

    Parameters
    ----------
    colourspaces : array_like, optional
        *RGB* colourspaces to plot the gamuts.
    reference_colourspace : unicode, optional
        **{'CIE XYZ', 'CIE xyY', 'CIE xy', 'CIE Lab', 'CIE LCHab', 'CIE Luv',
        'CIE Luv uv', 'CIE LCHuv', 'CIE UCS', 'CIE UCS uv', 'CIE UVW',
        'DIN 99', 'Hunter Lab', 'Hunter Rdab', 'IPT', 'JzAzBz', 'OSA UCS',
        'hdr-CIELAB', 'hdr-IPT'}**,
        Reference colourspace to plot the gamuts into.
    segments : int, optional
        Edge segments count for each *RGB* colourspace cubes.
    show_grid : bool, optional
        Whether to show a grid at the bottom of the *RGB* colourspace cubes.
    grid_segments : bool, optional
        Edge segments count for the grid.
    show_spectral_locus : bool, optional
        Whether to show the spectral locus.
    spectral_locus_colour : array_like, optional
        Spectral locus colour.
    cmfs : unicode, optional
        Standard observer colour matching functions used for spectral locus.

    Other Parameters
    ----------------
    \\**kwargs : dict, optional
        {:func:`colour.plotting.artist`,
        :func:`colour.plotting.volume.nadir_grid`},
        Please refer to the documentation of the previously listed definitions.
    face_colours : array_like, optional
        Face colours array such as `face_colours = (None, (0.5, 0.5, 1.0))`.
    edge_colours : array_like, optional
        Edge colours array such as `edge_colours = (None, (0.5, 0.5, 1.0))`.
    face_alpha : numeric, optional
        Face opacity value such as `face_alpha = (0.5, 1.0)`.
    edge_alpha : numeric, optional
        Edge opacity value such as `edge_alpha = (0.0, 1.0)`.

    Returns
    -------
    tuple
        Current figure and axes.

    Examples
    --------
    >>> plot_RGB_colourspaces_gamuts(['ITU-R BT.709', 'ACEScg', 'S-Gamut'])
    ... # doctest: +SKIP

    .. image:: ../_static/Plotting_Plot_RGB_Colourspaces_Gamuts.png
        :align: center
        :alt: plot_RGB_colourspaces_gamuts
    """

    if colourspaces is None:
        colourspaces = ('ITU-R BT.709', 'ACEScg')

    colourspaces = filter_RGB_colourspaces(colourspaces).values()

    count_c = len(colourspaces)

    title = '{0} - {1} Reference Colourspace'.format(
        ', '.join([colourspace.name for colourspace in colourspaces]),
        reference_colourspace,
    )

    settings = Structure(
        **{
            'face_colours': [None] * count_c,
            'edge_colours': [None] * count_c,
            'face_alpha': [1] * count_c,
            'edge_alpha': [1] * count_c,
            'title': title,
        })
    settings.update(kwargs)

    figure = plt.figure()
    axes = figure.add_subplot(111, projection='3d')

    illuminant = COLOUR_STYLE_CONSTANTS.colour.colourspace.whitepoint

    points = np.zeros((4, 3))
    if show_spectral_locus:
        cmfs = first_item(filter_cmfs(cmfs).values())
        XYZ = cmfs.values

        points = common_colourspace_model_axis_reorder(
            XYZ_to_colourspace_model(XYZ, illuminant, reference_colourspace),
            reference_colourspace)

        points[np.isnan(points)] = 0

        c = ((0.0, 0.0, 0.0, 0.5)
             if spectral_locus_colour is None else spectral_locus_colour)

        axes.plot(
            points[..., 0], points[..., 1], points[..., 2], color=c, zorder=1)
        axes.plot(
            (points[-1][0], points[0][0]), (points[-1][1], points[0][1]),
            (points[-1][2], points[0][2]),
            color=c,
            zorder=1)

    quads, RGB_f, RGB_e = [], [], []
    for i, colourspace in enumerate(colourspaces):
        quads_c, RGB = RGB_identity_cube(
            width_segments=segments,
            height_segments=segments,
            depth_segments=segments)

        XYZ = RGB_to_XYZ(
            quads_c,
            colourspace.whitepoint,
            colourspace.whitepoint,
            colourspace.RGB_to_XYZ_matrix,
        )

        quads.extend(
            common_colourspace_model_axis_reorder(
                XYZ_to_colourspace_model(
                    XYZ,
                    colourspace.whitepoint,
                    reference_colourspace,
                ), reference_colourspace))

        if settings.face_colours[i] is not None:
            RGB = np.ones(RGB.shape) * settings.face_colours[i]

        RGB_f.extend(
            np.hstack([
                RGB,
                np.full((RGB.shape[0], 1), settings.face_alpha[i],
                        DEFAULT_FLOAT_DTYPE)
            ]))

        if settings.edge_colours[i] is not None:
            RGB = np.ones(RGB.shape) * settings.edge_colours[i]

        RGB_e.extend(
            np.hstack([
                RGB,
                np.full((RGB.shape[0], 1), settings.edge_alpha[i],
                        DEFAULT_FLOAT_DTYPE)
            ]))

    quads = as_float_array(quads)
    quads[np.isnan(quads)] = 0

    if quads.size != 0:
        for i, axis in enumerate('xyz'):
            min_a = min(np.min(quads[..., i]), np.min(points[..., i]))
            max_a = max(np.max(quads[..., i]), np.max(points[..., i]))
            getattr(axes, 'set_{}lim'.format(axis))((min_a, max_a))

    labels = COLOURSPACE_MODELS_LABELS[reference_colourspace]
    for i, axis in enumerate('xyz'):
        getattr(axes, 'set_{}label'.format(axis))(labels[i])

    if show_grid:
        if reference_colourspace == 'CIE Lab':
            limits = np.array([[-450, 450], [-450, 450]])
        elif reference_colourspace == 'CIE Luv':
            limits = np.array([[-650, 650], [-650, 650]])
        elif reference_colourspace == 'CIE UVW':
            limits = np.array([[-850, 850], [-850, 850]])
        elif reference_colourspace in ('Hunter Lab', 'Hunter Rdab'):
            limits = np.array([[-250, 250], [-250, 250]])
        else:
            limits = np.array([[-1.5, 1.5], [-1.5, 1.5]])

        quads_g, RGB_gf, RGB_ge = nadir_grid(limits, grid_segments, labels,
                                             axes, **settings)
        quads = np.vstack([quads_g, quads])
        RGB_f = np.vstack([RGB_gf, RGB_f])
        RGB_e = np.vstack([RGB_ge, RGB_e])

    collection = Poly3DCollection(quads)
    collection.set_facecolors(RGB_f)
    collection.set_edgecolors(RGB_e)

    axes.add_collection3d(collection)

    settings.update({
        'axes': axes,
        'axes_visible': False,
        'camera_aspect': 'equal'
    })
    settings.update(kwargs)

    return render(**settings)
Ejemplo n.º 10
0
def RGB_colourspace_volume_visual(colourspace='ITU-R BT.709',
                                  reference_colourspace='CIE xyY',
                                  segments=16,
                                  uniform_colour=None,
                                  uniform_opacity=0.5,
                                  wireframe=True,
                                  wireframe_colour=None,
                                  wireframe_opacity=1.0,
                                  parent=None):
    """
    Returns a :class:`vispy.scene.visuals.Node` class instance with one or two
    :class:`colour_analysis.visuals.Box` class instance children representing
    a *RGB* colourspace volume visual.

    Parameters
    ----------
    colourspace : unicode, optional
        **{'ITU-R BT.709', 'ACES2065-1', 'ACEScc', 'ACEScg', 'ACESproxy',
        'ALEXA Wide Gamut', 'Adobe RGB (1998)', 'Adobe Wide Gamut RGB',
        'Apple RGB', 'Best RGB', 'Beta RGB', 'CIE RGB', 'Cinema Gamut',
        'ColorMatch RGB', 'DCI-P3', 'DCI-P3+', 'DRAGONcolor', 'DRAGONcolor2',
        'Don RGB 4', 'ECI RGB v2', 'ERIMM RGB', 'Ekta Space PS 5', 'Max RGB',
        'NTSC', 'Pal/Secam', 'ProPhoto RGB', 'REDcolor', 'REDcolor2',
        'REDcolor3', 'REDcolor4', 'RIMM RGB', 'ROMM RGB', 'ITU-R BT.2020',
        'Russell RGB', 'S-Gamut', 'S-Gamut3', 'S-Gamut3.Cine', 'SMPTE-C RGB',
        'V-Gamut', 'Xtreme RGB', 'sRGB'}**,
        :class:`colour.RGB_Colourspace` class instance name defining the *RGB*
        colourspace volume to draw.
    reference_colourspace : unicode
        **{'CIE XYZ', 'CIE xyY', 'CIE Lab', 'CIE Luv', 'CIE UCS', 'CIE UVW',
        'IPT', 'Hunter Lab', 'Hunter Rdab'}**,
        Reference colourspace to convert the *CIE XYZ* tristimulus values to.
    segments : int, optional
        Box segments.
    uniform_colour : array_like, optional
        Uniform mesh colour.
    uniform_opacity : numeric, optional
        Uniform mesh opacity.
    wireframe : bool, optional
        Use wireframe display.
        Uniform mesh opacity.
    wireframe_colour : array_like, optional
        Wireframe mesh colour.
    wireframe_opacity : numeric, optional
        Wireframe mesh opacity.
    parent : Node, optional
        Parent of the *RGB* colourspace volume visual in the `SceneGraph`.
    """

    node = Node(parent)

    colourspace = first_item(filter_RGB_colourspaces(colourspace).values())

    RGB_cube_f = RGB_identity_cube(width_segments=segments,
                                   height_segments=segments,
                                   depth_segments=segments,
                                   uniform_colour=uniform_colour,
                                   uniform_opacity=uniform_opacity,
                                   vertex_colours=not uniform_colour,
                                   parent=node)

    vertices = RGB_cube_f.mesh_data.get_vertices()
    XYZ = RGB_to_XYZ(vertices, colourspace.whitepoint, colourspace.whitepoint,
                     colourspace.RGB_to_XYZ_matrix)
    value = common_colourspace_model_axis_reorder(
        XYZ_to_colourspace_model(XYZ, colourspace.whitepoint,
                                 reference_colourspace), reference_colourspace)
    value[np.isnan(value)] = 0

    RGB_cube_f.mesh_data.set_vertices(value)

    if wireframe:
        RGB_cube_w = RGB_identity_cube(width_segments=segments,
                                       height_segments=segments,
                                       depth_segments=segments,
                                       uniform_colour=wireframe_colour,
                                       uniform_opacity=wireframe_opacity,
                                       vertex_colours=not wireframe_colour,
                                       wireframe=True,
                                       parent=node)
        RGB_cube_w.mesh_data.set_vertices(value)

    return node
Ejemplo n.º 11
0
def RGB_scatter_visual(RGB,
                       colourspace='ITU-R BT.709',
                       reference_colourspace='CIE xyY',
                       symbol='disc',
                       size=4.0,
                       edge_size=0.5,
                       uniform_colour=None,
                       uniform_opacity=1.0,
                       uniform_edge_colour=None,
                       uniform_edge_opacity=1.0,
                       resampling='auto',
                       parent=None):
    """
    Returns a :class:`vispy.scene.visuals.Symbol` class instance representing
    *RGB* data using given symbols.

    Parameters
    ----------
    RGB : array_like
        *RGB* data to draw.
    colourspace : unicode, optional
        **{'ITU-R BT.709', 'ACES2065-1', 'ACEScc', 'ACEScg', 'ACESproxy',
        'ALEXA Wide Gamut', 'Adobe RGB (1998)', 'Adobe Wide Gamut RGB',
        'Apple RGB', 'Best RGB', 'Beta RGB', 'CIE RGB', 'Cinema Gamut',
        'ColorMatch RGB', 'DCI-P3', 'DCI-P3+', 'DRAGONcolor', 'DRAGONcolor2',
        'Don RGB 4', 'ECI RGB v2', 'ERIMM RGB', 'Ekta Space PS 5', 'Max RGB',
        'NTSC', 'Pal/Secam', 'ProPhoto RGB', 'REDcolor', 'REDcolor2',
        'REDcolor3', 'REDcolor4', 'RIMM RGB', 'ROMM RGB', 'ITU-R BT.2020',
        'Russell RGB', 'S-Gamut', 'S-Gamut3', 'S-Gamut3.Cine', 'SMPTE-C RGB',
        'V-Gamut', 'Xtreme RGB', 'sRGB'}**,
        :class:`colour.RGB_Colourspace` class instance name defining the *RGB*
        colourspace of the data to draw.
    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.
    symbol : unicode, optional
        Symbol type to draw.
    size : numeric, optional
        Symbol size.
    edge_size : numeric, optional
        Symbol edge size.
    uniform_colour : array_like, optional
        Uniform symbol colour.
    uniform_opacity : numeric, optional
        Uniform symbol opacity.
    uniform_edge_colour : array_like, optional
        Uniform symbol edge colour.
    uniform_edge_opacity : numeric, optional
        Uniform symbol edge opacity.
    resampling : numeric or unicode, optional
        Resampling value, if numeric input, one pixel every `resampling`
        argument value will be kept.
    parent : Node, optional
        Parent of the *RGB* scatter visual in the `SceneGraph`.

    Returns
    -------
    Symbol
        *RGB* scatter visual.
    """

    colourspace = first_item(filter_RGB_colourspaces(colourspace).values())

    RGB = np.asarray(RGB)

    if resampling == 'auto':
        resampling = max(int((0.0078125 * np.average(RGB.shape[0:1])) // 2), 1)

        RGB = RGB[::resampling, ::resampling].reshape([-1, 3])

    XYZ = RGB_to_XYZ(RGB, colourspace.whitepoint, colourspace.whitepoint,
                     colourspace.RGB_to_XYZ_matrix)

    points = common_colourspace_model_axis_reorder(
        XYZ_to_colourspace_model(XYZ, colourspace.whitepoint,
                                 reference_colourspace), reference_colourspace)

    points[np.isnan(points)] = 0

    RGB = np.clip(RGB, 0, 1)

    if uniform_colour is None:
        RGB = np.hstack([RGB,
                         np.full((RGB.shape[0], 1), uniform_opacity,
                                 DEFAULT_FLOAT_DTYPE)])
    else:
        RGB = ColorArray(uniform_colour, alpha=uniform_opacity).rgba

    if uniform_edge_colour is None:
        RGB_e = RGB
    else:
        RGB_e = ColorArray(
            uniform_edge_colour, alpha=uniform_edge_opacity).rgba

    markers = Symbol(
        symbol=symbol,
        positions=points,
        size=size,
        edge_size=edge_size,
        face_colour=RGB,
        edge_colour=RGB_e,
        parent=parent)

    return markers
Ejemplo n.º 12
0
def plot_RGB_colourspaces_gamuts(
    colourspaces: Union[RGB_Colourspace, str, Sequence[Union[RGB_Colourspace,
                                                             str]]],
    reference_colourspace: Union[Literal["CAM02LCD", "CAM02SCD", "CAM02UCS",
                                         "CAM16LCD", "CAM16SCD", "CAM16UCS",
                                         "CIE XYZ", "CIE xyY", "CIE Lab",
                                         "CIE Luv", "CIE UCS", "CIE UVW",
                                         "DIN99", "Hunter Lab", "Hunter Rdab",
                                         "ICaCb", "ICtCp", "IPT", "IgPgTg",
                                         "Jzazbz", "OSA UCS", "Oklab",
                                         "hdr-CIELAB", "hdr-IPT", ],
                                 str, ] = "CIE xyY",
    segments: Integer = 8,
    show_grid: Boolean = True,
    grid_segments: Integer = 10,
    show_spectral_locus: Boolean = False,
    spectral_locus_colour: Optional[Union[ArrayLike, str]] = None,
    cmfs: Union[MultiSpectralDistributions, str, Sequence[Union[
        MultiSpectralDistributions,
        str]], ] = "CIE 1931 2 Degree Standard Observer",
    chromatically_adapt: Boolean = False,
    convert_kwargs: Optional[Dict] = None,
    **kwargs: Any,
) -> Tuple[plt.Figure, plt.Axes]:
    """
    Plot given *RGB* colourspaces gamuts in given reference colourspace.

    Parameters
    ----------
    colourspaces
        *RGB* colourspaces to plot the gamuts. ``colourspaces`` elements
        can be of any type or form supported by the
        :func:`colour.plotting.filter_RGB_colourspaces` definition.
    reference_colourspace
        Reference colourspace model to plot the gamuts into, see
        :attr:`colour.COLOURSPACE_MODELS` attribute for the list of supported
        colourspace models.
    segments
        Edge segments count for each *RGB* colourspace cubes.
    show_grid
        Whether to show a grid at the bottom of the *RGB* colourspace cubes.
    grid_segments
        Edge segments count for the grid.
    show_spectral_locus
        Whether to show the spectral locus.
    spectral_locus_colour
        Spectral locus colour.
    cmfs
        Standard observer colour matching functions used for computing the
        spectral locus boundaries. ``cmfs`` can be of any type or form
        supported by the :func:`colour.plotting.filter_cmfs` definition.
    chromatically_adapt
        Whether to chromatically adapt the *RGB* colourspaces given in
        ``colourspaces`` to the whitepoint of the default plotting colourspace.
    convert_kwargs
        Keyword arguments for the :func:`colour.convert` definition.

    Other Parameters
    ----------------
    edge_colours
        Edge colours array such as `edge_colours = (None, (0.5, 0.5, 1.0))`.
    edge_alpha
        Edge opacity value such as `edge_alpha = (0.0, 1.0)`.
    face_alpha
        Face opacity value such as `face_alpha = (0.5, 1.0)`.
    face_colours
        Face colours array such as `face_colours = (None, (0.5, 0.5, 1.0))`.
    kwargs
        {:func:`colour.plotting.artist`,
        :func:`colour.plotting.volume.nadir_grid`},
        See the documentation of the previously listed definitions.

    Returns
    -------
    :class:`tuple`
        Current figure and axes.

    Examples
    --------
    >>> plot_RGB_colourspaces_gamuts(['ITU-R BT.709', 'ACEScg', 'S-Gamut'])
    ... # doctest: +ELLIPSIS
    (<Figure size ... with 1 Axes>, <...Axes3DSubplot...>)

    .. image:: ../_static/Plotting_Plot_RGB_Colourspaces_Gamuts.png
        :align: center
        :alt: plot_RGB_colourspaces_gamuts
    """

    colourspaces = cast(
        List[RGB_Colourspace],
        list(filter_RGB_colourspaces(colourspaces).values()),
    )

    convert_kwargs = optional(convert_kwargs, {})

    count_c = len(colourspaces)

    title = (
        f"{', '.join([colourspace.name for colourspace in colourspaces])} "
        f"- {reference_colourspace} Reference Colourspace")

    illuminant = CONSTANTS_COLOUR_STYLE.colour.colourspace.whitepoint

    convert_settings = {"illuminant": illuminant}
    convert_settings.update(convert_kwargs)

    settings = Structure(
        **{
            "face_colours": [None] * count_c,
            "edge_colours": [None] * count_c,
            "face_alpha": [1] * count_c,
            "edge_alpha": [1] * count_c,
            "title": title,
        })
    settings.update(kwargs)

    figure = plt.figure()
    axes = figure.add_subplot(111, projection="3d")

    points = zeros((4, 3))
    if show_spectral_locus:
        cmfs = cast(MultiSpectralDistributions,
                    first_item(filter_cmfs(cmfs).values()))
        XYZ = cmfs.values

        points = colourspace_model_axis_reorder(
            convert(XYZ, "CIE XYZ", reference_colourspace, **convert_settings),
            reference_colourspace,
        )

        points[np.isnan(points)] = 0

        c = ((0.0, 0.0, 0.0,
              0.5) if spectral_locus_colour is None else spectral_locus_colour)

        axes.plot(
            points[..., 0],
            points[..., 1],
            points[..., 2],
            color=c,
            zorder=CONSTANTS_COLOUR_STYLE.zorder.midground_line,
        )
        axes.plot(
            (points[-1][0], points[0][0]),
            (points[-1][1], points[0][1]),
            (points[-1][2], points[0][2]),
            color=c,
            zorder=CONSTANTS_COLOUR_STYLE.zorder.midground_line,
        )

    plotting_colourspace = CONSTANTS_COLOUR_STYLE.colour.colourspace

    quads_c: List = []
    RGB_cf: List = []
    RGB_ce: List = []
    for i, colourspace in enumerate(colourspaces):

        if chromatically_adapt and not np.array_equal(
                colourspace.whitepoint, plotting_colourspace.whitepoint):
            colourspace = colourspace.chromatically_adapt(
                plotting_colourspace.whitepoint,
                plotting_colourspace.whitepoint_name,
            )

        quads_cb, RGB = RGB_identity_cube(
            width_segments=segments,
            height_segments=segments,
            depth_segments=segments,
        )

        XYZ = RGB_to_XYZ(
            quads_cb,
            colourspace.whitepoint,
            colourspace.whitepoint,
            colourspace.matrix_RGB_to_XYZ,
        )

        convert_settings = {"illuminant": colourspace.whitepoint}
        convert_settings.update(convert_kwargs)

        quads_c.extend(
            colourspace_model_axis_reorder(
                convert(XYZ, "CIE XYZ", reference_colourspace,
                        **convert_settings),
                reference_colourspace,
            ))

        if settings.face_colours[i] is not None:
            RGB = ones(RGB.shape) * settings.face_colours[i]

        RGB_cf.extend(
            np.hstack([RGB,
                       full((RGB.shape[0], 1), settings.face_alpha[i])]))

        if settings.edge_colours[i] is not None:
            RGB = ones(RGB.shape) * settings.edge_colours[i]

        RGB_ce.extend(
            np.hstack([RGB,
                       full((RGB.shape[0], 1), settings.edge_alpha[i])]))

    quads = as_float_array(quads_c)
    RGB_f = as_float_array(RGB_cf)
    RGB_e = as_float_array(RGB_ce)

    quads[np.isnan(quads)] = 0

    if quads.size != 0:
        for i, axis in enumerate("xyz"):
            min_a = np.minimum(np.min(quads[..., i]), np.min(points[..., i]))
            max_a = np.maximum(np.max(quads[..., i]), np.max(points[..., i]))
            getattr(axes, f"set_{axis}lim")((min_a, max_a))

    labels = np.array(
        COLOURSPACE_MODELS_AXIS_LABELS[reference_colourspace])[as_int_array(
            colourspace_model_axis_reorder([0, 1, 2], reference_colourspace))]
    for i, axis in enumerate("xyz"):
        getattr(axes, f"set_{axis}label")(labels[i])

    if show_grid:
        limits = np.array([[-1.5, 1.5], [-1.5, 1.5]])

        quads_g, RGB_gf, RGB_ge = nadir_grid(limits, grid_segments, labels,
                                             axes, **settings)
        quads = np.vstack([quads_g, quads])
        RGB_f = np.vstack([RGB_gf, RGB_f])
        RGB_e = np.vstack([RGB_ge, RGB_e])

    collection = Poly3DCollection(quads)
    collection.set_facecolors(RGB_f)
    collection.set_edgecolors(RGB_e)

    axes.add_collection3d(collection)

    settings.update({
        "axes": axes,
        "axes_visible": False,
        "camera_aspect": "equal"
    })
    settings.update(kwargs)

    return render(**settings)
Ejemplo n.º 13
0
def plot_RGB_scatter(
    RGB: ArrayLike,
    colourspace: Union[RGB_Colourspace, str, Sequence[Union[RGB_Colourspace,
                                                            str]]],
    reference_colourspace: Union[Literal["CAM02LCD", "CAM02SCD", "CAM02UCS",
                                         "CAM16LCD", "CAM16SCD", "CAM16UCS",
                                         "CIE XYZ", "CIE xyY", "CIE Lab",
                                         "CIE Luv", "CIE UCS", "CIE UVW",
                                         "DIN99", "Hunter Lab", "Hunter Rdab",
                                         "ICaCb", "ICtCp", "IPT", "IgPgTg",
                                         "Jzazbz", "OSA UCS", "Oklab",
                                         "hdr-CIELAB", "hdr-IPT", ],
                                 str, ] = "CIE xyY",
    colourspaces: Optional[Union[RGB_Colourspace, str,
                                 Sequence[Union[RGB_Colourspace,
                                                str]]]] = None,
    segments: Integer = 8,
    show_grid: Boolean = True,
    grid_segments: Integer = 10,
    show_spectral_locus: Boolean = False,
    spectral_locus_colour: Optional[Union[ArrayLike, str]] = None,
    points_size: Floating = 12,
    cmfs: Union[MultiSpectralDistributions, str, Sequence[Union[
        MultiSpectralDistributions,
        str]], ] = "CIE 1931 2 Degree Standard Observer",
    chromatically_adapt: Boolean = False,
    convert_kwargs: Optional[Dict] = None,
    **kwargs: Any,
) -> Tuple[plt.Figure, plt.Axes]:
    """
    Plot given *RGB* colourspace array in a scatter plot.

    Parameters
    ----------
    RGB
        *RGB* colourspace array.
    colourspace
        *RGB* colourspace of the *RGB* array. ``colourspace`` can be of any
        type or form supported by the
        :func:`colour.plotting.filter_RGB_colourspaces` definition.
    reference_colourspace
        Reference colourspace model to plot the gamuts into, see
        :attr:`colour.COLOURSPACE_MODELS` attribute for the list of supported
        colourspace models.
    colourspaces
        *RGB* colourspaces to plot the gamuts. ``colourspaces`` elements
        can be of any type or form supported by the
        :func:`colour.plotting.filter_RGB_colourspaces` definition.
    segments
        Edge segments count for each *RGB* colourspace cubes.
    show_grid
        Whether to show a grid at the bottom of the *RGB* colourspace cubes.
    grid_segments
        Edge segments count for the grid.
    show_spectral_locus
        Whether to show the spectral locus.
    spectral_locus_colour
        Spectral locus colour.
    points_size
        Scatter points size.
    cmfs
        Standard observer colour matching functions used for computing the
        spectral locus boundaries. ``cmfs`` can be of any type or form
        supported by the :func:`colour.plotting.filter_cmfs` definition.
    chromatically_adapt
        Whether to chromatically adapt the *RGB* colourspaces given in
        ``colourspaces`` to the whitepoint of the default plotting colourspace.
    convert_kwargs
        Keyword arguments for the :func:`colour.convert` definition.

    Other Parameters
    ----------------
    kwargs
        {:func:`colour.plotting.artist`,
        :func:`colour.plotting.plot_RGB_colourspaces_gamuts`},
        See the documentation of the previously listed definitions.

    Returns
    -------
    :class:`tuple`
        Current figure and axes.

    Examples
    --------
    >>> RGB = np.random.random((128, 128, 3))
    >>> plot_RGB_scatter(RGB, 'ITU-R BT.709')  # doctest: +ELLIPSIS
    (<Figure size ... with 1 Axes>, <...Axes3DSubplot...>)

    .. image:: ../_static/Plotting_Plot_RGB_Scatter.png
        :align: center
        :alt: plot_RGB_scatter
    """

    colourspace = cast(
        RGB_Colourspace,
        first_item(filter_RGB_colourspaces(colourspace).values()),
    )
    colourspaces = cast(List[str], optional(colourspaces, [colourspace.name]))

    convert_kwargs = optional(convert_kwargs, {})

    count_c = len(colourspaces)
    settings = Structure(
        **{
            "face_colours": [None] * count_c,
            "edge_colours": [(0.25, 0.25, 0.25)] * count_c,
            "face_alpha": [0.0] * count_c,
            "edge_alpha": [0.1] * count_c,
        })
    settings.update(kwargs)
    settings["standalone"] = False

    plot_RGB_colourspaces_gamuts(
        colourspaces=colourspaces,
        reference_colourspace=reference_colourspace,
        segments=segments,
        show_grid=show_grid,
        grid_segments=grid_segments,
        show_spectral_locus=show_spectral_locus,
        spectral_locus_colour=spectral_locus_colour,
        cmfs=cmfs,
        chromatically_adapt=chromatically_adapt,
        **settings,
    )

    XYZ = RGB_to_XYZ(
        RGB,
        colourspace.whitepoint,
        colourspace.whitepoint,
        colourspace.matrix_RGB_to_XYZ,
    )

    convert_settings = {"illuminant": colourspace.whitepoint}
    convert_settings.update(convert_kwargs)

    points = colourspace_model_axis_reorder(
        convert(XYZ, "CIE XYZ", reference_colourspace, **convert_settings),
        reference_colourspace,
    )

    axes = plt.gca()
    axes.scatter(
        points[..., 0],
        points[..., 1],
        points[..., 2],
        color=np.reshape(RGB, (-1, 3)),
        s=points_size,
        zorder=CONSTANTS_COLOUR_STYLE.zorder.midground_scatter,
    )

    settings.update({"axes": axes, "standalone": True})
    settings.update(kwargs)

    return render(**settings)
Ejemplo n.º 14
0
def plot_RGB_chromaticities_in_chromaticity_diagram(
        RGB,
        colourspace='sRGB',
        chromaticity_diagram_callable=(
            plot_RGB_colourspaces_in_chromaticity_diagram),
        method='CIE 1931',
        scatter_parameters=None,
        **kwargs):
    """
    Plots given *RGB* colourspace array in the *Chromaticity Diagram* according
    to given method.

    Parameters
    ----------
    RGB : array_like
        *RGB* colourspace array.
    colourspace : optional, unicode
        *RGB* colourspace of the *RGB* array.
    chromaticity_diagram_callable : callable, optional
        Callable responsible for drawing the *Chromaticity Diagram*.
    method : unicode, optional
        **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**,
        *Chromaticity Diagram* method.
    scatter_parameters : dict, optional
        Parameters for the :func:`plt.scatter` definition, if ``c`` is set to
        *RGB*, the scatter will use given ``RGB`` colours.

    Other Parameters
    ----------------
    \\**kwargs : dict, optional
        {:func:`colour.plotting.artist`,
        :func:`colour.plotting.diagrams.plot_chromaticity_diagram`,
        :func:`colour.plotting.render`},
        Please refer to the documentation of the previously listed definitions.

    Returns
    -------
    tuple
        Current figure and axes.

    Examples
    --------
    >>> RGB = np.random.random((128, 128, 3))
    >>> plot_RGB_chromaticities_in_chromaticity_diagram(
    ...     RGB, 'ITU-R BT.709')
    ... # doctest: +SKIP

    .. image:: ../_static/Plotting_\
Plot_RGB_Chromaticities_In_Chromaticity_Diagram_Plot.png
        :align: center
        :alt: plot_RGB_chromaticities_in_chromaticity_diagram
    """

    RGB = as_float_array(RGB).reshape(-1, 3)

    settings = {'uniform': True}
    settings.update(kwargs)

    figure, axes = artist(**settings)

    method = method.upper()

    scatter_settings = {
        's': 40,
        'c': 'RGB',
        'marker': 'o',
        'alpha': 0.85,
    }
    if scatter_parameters is not None:
        scatter_settings.update(scatter_parameters)

    settings = dict(kwargs)
    settings.update({'axes': axes, 'standalone': False})

    colourspace = first_item(filter_RGB_colourspaces(colourspace).values())
    settings['colourspaces'] = (['^{0}$'.format(colourspace.name)] +
                                settings.get('colourspaces', []))

    chromaticity_diagram_callable(**settings)

    use_RGB_colours = scatter_settings['c'].upper() == 'RGB'
    if use_RGB_colours:
        RGB = RGB[RGB[:, 1].argsort()]
        scatter_settings['c'] = np.clip(
            RGB_to_RGB(RGB,
                       colourspace,
                       COLOUR_STYLE_CONSTANTS.colour.colourspace,
                       apply_encoding_cctf=True).reshape(-1, 3), 0, 1)

    XYZ = RGB_to_XYZ(RGB, colourspace.whitepoint, colourspace.whitepoint,
                     colourspace.RGB_to_XYZ_matrix)

    if method == 'CIE 1931':
        ij = XYZ_to_xy(XYZ, colourspace.whitepoint)
    elif method == 'CIE 1960 UCS':
        ij = UCS_to_uv(XYZ_to_UCS(XYZ))

    elif method == 'CIE 1976 UCS':
        ij = Luv_to_uv(XYZ_to_Luv(XYZ, colourspace.whitepoint),
                       colourspace.whitepoint)

    axes.scatter(ij[..., 0], ij[..., 1], **scatter_settings)

    settings.update({'standalone': True})
    settings.update(kwargs)

    return render(**settings)
Ejemplo n.º 15
0
def RGB_scatter_visual(RGB,
                       colourspace='ITU-R BT.709',
                       reference_colourspace='CIE xyY',
                       symbol='disc',
                       size=4.0,
                       edge_size=0.5,
                       uniform_colour=None,
                       uniform_opacity=1.0,
                       uniform_edge_colour=None,
                       uniform_edge_opacity=1.0,
                       resampling='auto',
                       parent=None):
    """
    Returns a :class:`vispy.scene.visuals.Symbol` class instance representing
    *RGB* data using given symbols.

    Parameters
    ----------
    RGB : array_like
        *RGB* data to draw.
    colourspace : unicode, optional
        **{'ITU-R BT.709', 'ACES2065-1', 'ACEScc', 'ACEScg', 'ACESproxy',
        'ALEXA Wide Gamut', 'Adobe RGB (1998)', 'Adobe Wide Gamut RGB',
        'Apple RGB', 'Best RGB', 'Beta RGB', 'CIE RGB', 'Cinema Gamut',
        'ColorMatch RGB', 'DCI-P3', 'DCI-P3+', 'DRAGONcolor', 'DRAGONcolor2',
        'Don RGB 4', 'ECI RGB v2', 'ERIMM RGB', 'Ekta Space PS 5', 'Max RGB',
        'NTSC', 'Pal/Secam', 'ProPhoto RGB', 'REDcolor', 'REDcolor2',
        'REDcolor3', 'REDcolor4', 'RIMM RGB', 'ROMM RGB', 'ITU-R BT.2020',
        'Russell RGB', 'S-Gamut', 'S-Gamut3', 'S-Gamut3.Cine', 'SMPTE-C RGB',
        'V-Gamut', 'Xtreme RGB', 'sRGB'}**,
        :class:`colour.RGB_Colourspace` class instance name defining the *RGB*
        colourspace of the data to draw.
    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.
    symbol : unicode, optional
        Symbol type to draw.
    size : numeric, optional
        Symbol size.
    edge_size : numeric, optional
        Symbol edge size.
    uniform_colour : array_like, optional
        Uniform symbol colour.
    uniform_opacity : numeric, optional
        Uniform symbol opacity.
    uniform_edge_colour : array_like, optional
        Uniform symbol edge colour.
    uniform_edge_opacity : numeric, optional
        Uniform symbol edge opacity.
    resampling : numeric or unicode, optional
        Resampling value, if numeric input, one pixel every `resampling`
        argument value will be kept.
    parent : Node, optional
        Parent of the *RGB* scatter visual in the `SceneGraph`.

    Returns
    -------
    Symbol
        *RGB* scatter visual.
    """

    colourspace = first_item(filter_RGB_colourspaces(colourspace).values())

    RGB = np.asarray(RGB)

    if resampling == 'auto':
        resampling = max(int((0.0078125 * np.average(RGB.shape[0:1])) // 2), 1)

        RGB = RGB[::resampling, ::resampling].reshape([-1, 3])

    XYZ = RGB_to_XYZ(RGB, colourspace.whitepoint, colourspace.whitepoint,
                     colourspace.RGB_to_XYZ_matrix)

    points = common_colourspace_model_axis_reorder(
        XYZ_to_colourspace_model(XYZ, colourspace.whitepoint,
                                 reference_colourspace), reference_colourspace)

    points[np.isnan(points)] = 0

    RGB = np.clip(RGB, 0, 1)

    if uniform_colour is None:
        RGB = np.hstack([
            RGB,
            np.full((RGB.shape[0], 1), uniform_opacity, DEFAULT_FLOAT_DTYPE)
        ])
    else:
        RGB = ColorArray(uniform_colour, alpha=uniform_opacity).rgba

    if uniform_edge_colour is None:
        RGB_e = RGB
    else:
        RGB_e = ColorArray(uniform_edge_colour,
                           alpha=uniform_edge_opacity).rgba

    markers = Symbol(symbol=symbol,
                     positions=points,
                     size=size,
                     edge_size=edge_size,
                     face_colour=RGB,
                     edge_colour=RGB_e,
                     parent=parent)

    return markers
Ejemplo n.º 16
0
from colormath.color_objects import LabColor, sRGBColor
from colour.models import (RGB_to_HSL, RGB_to_HSV, RGB_to_XYZ, XYZ_to_Lab,
                           XYZ_to_RGB, XYZ_to_xy)
from colour.plotting import filter_RGB_colourspaces
from colour.utilities import first_item
from comet_ml import Optimizer
from lightgbm import LGBMRegressor
from six.moves import zip
from sklearn.metrics.scorer import make_scorer
from sklearn.model_selection import cross_val_score, train_test_split
from sklearn.multioutput import MultiOutputRegressor
from sklearn.preprocessing import StandardScaler

from ..utils.descriptornames import *  # pylint:disable=unused-wildcard-import

colourspace = first_item(filter_RGB_colourspaces('sRGB').values())


def get_delta_e(rgba, rgbb):
    color1_rgb = sRGBColor(rgba[0], rgba[1], rgba[2])
    color2_rgb = sRGBColor(rgbb[0], rgbb[1], rgbb[2])

    # Convert from RGB to Lab Color Space
    color1_lab = convert_color(color1_rgb, LabColor)

    # Convert from RGB to Lab Color Space
    color2_lab = convert_color(color2_rgb, LabColor)

    # Find the color difference
    delta_e = delta_e_cie2000(color1_lab, color2_lab)
Ejemplo n.º 17
0
def plot_RGB_colourspace_section(
    colourspace: Union[RGB_Colourspace, str, Sequence[Union[RGB_Colourspace,
                                                            str]]],
    model: Union[Literal["CAM02LCD", "CAM02SCD", "CAM02UCS", "CAM16LCD",
                         "CAM16SCD", "CAM16UCS", "CIE XYZ", "CIE xyY",
                         "CIE Lab", "CIE Luv", "CIE UCS", "CIE UVW", "DIN99",
                         "Hunter Lab", "Hunter Rdab", "ICaCb", "ICtCp", "IPT",
                         "IgPgTg", "Jzazbz", "OSA UCS", "Oklab", "hdr-CIELAB",
                         "hdr-IPT", ], str, ] = "CIE xyY",
    axis: Union[Literal["+z", "+x", "+y"], str] = "+z",
    origin: Floating = 0.5,
    normalise: Boolean = True,
    show_section_colours: Boolean = True,
    show_section_contour: Boolean = True,
    **kwargs: Any,
) -> Tuple[plt.Figure, plt.Axes]:
    """
    Plot given *RGB* colourspace section colours along given axis and origin.

    Parameters
    ----------
    colourspace
        *RGB* colourspace of the *RGB* array. ``colourspace`` can be of any
        type or form supported by the
        :func:`colour.plotting.filter_RGB_colourspaces` definition.
    model
        Colourspace model, see :attr:`colour.COLOURSPACE_MODELS` attribute for
        the list of supported colourspace models.
    axis
        Axis the hull section will be normal to.
    origin
        Coordinate along ``axis`` at which to plot the hull section.
    normalise
        Whether to normalise ``axis`` to the extent of the hull along it.
    show_section_colours
        Whether to show the hull section colours.
    show_section_contour
        Whether to show the hull section contour.

    Other Parameters
    ----------------
    kwargs
        {:func:`colour.plotting.artist`,
        :func:`colour.plotting.render`,
        :func:`colour.plotting.section.plot_hull_section_colours`
        :func:`colour.plotting.section.plot_hull_section_contour`},
        See the documentation of the previously listed definitions.

    Returns
    -------
    :class:`tuple`
        Current figure and axes.

    Examples
    --------
    >>> from colour.utilities import is_trimesh_installed
    >>> if is_trimesh_installed:
    ...     plot_RGB_colourspace_section(
    ...         'sRGB', section_colours='RGB', section_opacity=0.15)
    ...     # doctest: +ELLIPSIS
    (<Figure size ... with 1 Axes>, <...AxesSubplot...>)

    .. image:: ../_static/Plotting_Plot_RGB_Colourspace_Section.png
        :align: center
        :alt: plot_RGB_colourspace_section
    """

    import trimesh

    settings: Dict[str, Any] = {"uniform": True}
    settings.update(kwargs)

    _figure, axes = artist(**settings)

    colourspace = cast(
        RGB_Colourspace,
        first_item(filter_RGB_colourspaces(colourspace).values()),
    )

    vertices, faces, _outline = primitive_cube(1, 1, 1, 64, 64, 64)
    XYZ_vertices = RGB_to_XYZ(
        vertices["position"] + 0.5,
        colourspace.whitepoint,
        colourspace.whitepoint,
        colourspace.matrix_RGB_to_XYZ,
    )
    hull = trimesh.Trimesh(XYZ_vertices, faces, process=False)

    if show_section_colours:
        settings = {"axes": axes}
        settings.update(kwargs)
        settings["standalone"] = False

        plot_hull_section_colours(hull, model, axis, origin, normalise,
                                  **settings)

    if show_section_contour:
        settings = {"axes": axes}
        settings.update(kwargs)
        settings["standalone"] = False

        plot_hull_section_contour(hull, model, axis, origin, normalise,
                                  **settings)

    title = (f"{colourspace.name} Section - "
             f"{f'{origin * 100}%' if normalise else origin} - "
             f"{model}")

    plane = MAPPING_AXIS_TO_PLANE[axis]

    labels = np.array(COLOURSPACE_MODELS_AXIS_LABELS[model])[as_int_array(
        colourspace_model_axis_reorder([0, 1, 2], model))]
    x_label, y_label = labels[plane[0]], labels[plane[1]]

    settings.update({
        "axes": axes,
        "standalone": True,
        "title": title,
        "x_label": x_label,
        "y_label": y_label,
    })
    settings.update(kwargs)

    return render(**settings)
def image_data(path,
               primary_colourspace=PRIMARY_COLOURSPACE,
               secondary_colourspace=SECONDARY_COLOURSPACE,
               image_colourspace=IMAGE_COLOURSPACE,
               image_decoding_cctf=IMAGE_DECODING_CCTF,
               out_of_primary_colourspace_gamut=False,
               out_of_secondary_colourspace_gamut=False,
               out_of_pointer_gamut=False,
               saturate=False):
    """
    Returns given image RGB data or its out of gamut values formatted as
    *JSON*.

    Parameters
    ----------
    path : unicode
        Server side path of the image to read.
    primary_colourspace : unicode, optional
        Primary RGB colourspace used to generate out of gamut values.
    secondary_colourspace: unicode, optional
        Secondary RGB colourspace used to generate out of gamut values.
    image_colourspace: unicode, optional
        **{'Primary', 'Secondary'}**,
        Analysed image RGB colourspace.
    image_decoding_cctf : unicode, optional
        Analysed image decoding colour component transfer function
        (Decoding CCTF) / electro-optical transfer function (EOTF / EOCF) that
        maps an :math:`R'G'B'` video component signal value to tristimulus
        values at the display.
    out_of_primary_colourspace_gamut : bool, optional
        Whether to only generate the out of primary RGB colourspace gamut
        values.
    out_of_secondary_colourspace_gamut : bool, optional
        Whether to only generate the out of secondary RGB colourspace gamut
        values.
    out_of_pointer_gamut : bool, optional
        Whether to only generate the out of *Pointer's Gamut* values.
    saturate : bool, optional
        Whether to clip the image in domain [0, 1].

    Returns
    -------
    unicode
        RGB image data or its out of gamut values formatted as *JSON*.
    """

    primary_colourspace = first_item(
        filter_RGB_colourspaces('^{0}$'.format(
            re.escape(primary_colourspace))))
    secondary_colourspace = first_item(
        filter_RGB_colourspaces('^{0}$'.format(
            re.escape(secondary_colourspace))))

    colourspace = (primary_colourspace if image_colourspace == 'Primary' else
                   secondary_colourspace)

    RGB = load_image(path, image_decoding_cctf)

    if saturate:
        RGB = np.clip(RGB, 0, 1)

    if out_of_primary_colourspace_gamut:
        if image_colourspace == 'Secondary':
            RGB = RGB_to_RGB(RGB, secondary_colourspace, primary_colourspace)

        RGB[np.logical_and(RGB >= 0, RGB <= 1)] = 0
        RGB[RGB != 0] = 1
        RGB[np.any(RGB == 1, axis=-1)] = 1

    if out_of_secondary_colourspace_gamut:
        if image_colourspace == 'Primary':
            RGB = RGB_to_RGB(RGB, primary_colourspace, secondary_colourspace)

        RGB[np.logical_and(RGB >= 0, RGB <= 1)] = 0
        RGB[RGB != 0] = 1
        RGB[np.any(RGB == 1, axis=-1)] = 1

    if out_of_pointer_gamut:
        O_PG = is_within_pointer_gamut(
            RGB_to_XYZ(RGB, colourspace.whitepoint, colourspace.whitepoint,
                       colourspace.RGB_to_XYZ_matrix)).astype(np.int_)
        O_PG = 1 - O_PG
        RGB[O_PG != 1] = 0
        RGB[O_PG == 1] = 1

    shape = RGB.shape
    RGB = np.ravel(RGB[..., 0:3].reshape(-1, 3))
    RGB = np.around(RGB, np.finfo(COLOUR_DTYPE).precision)

    return json.dumps({
        'width': shape[1],
        'height': shape[0],
        'data': RGB.tolist()
    })
Ejemplo n.º 19
0
def plot_RGB_chromaticities_in_chromaticity_diagram(
        RGB,
        colourspace='sRGB',
        chromaticity_diagram_callable=(
            plot_RGB_colourspaces_in_chromaticity_diagram),
        method='CIE 1931',
        scatter_parameters=None,
        **kwargs):
    """
    Plots given *RGB* colourspace array in the *Chromaticity Diagram* according
    to given method.

    Parameters
    ----------
    RGB : array_like
        *RGB* colourspace array.
    colourspace : optional, unicode
        *RGB* colourspace of the *RGB* array.
    chromaticity_diagram_callable : callable, optional
        Callable responsible for drawing the *Chromaticity Diagram*.
    method : unicode, optional
        **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**,
        *Chromaticity Diagram* method.
    scatter_parameters : dict, optional
        Parameters for the :func:`plt.scatter` definition, if ``c`` is set to
        *RGB*, the scatter will use given ``RGB`` colours.

    Other Parameters
    ----------------
    \\**kwargs : dict, optional
        {:func:`colour.plotting.artist`,
        :func:`colour.plotting.diagrams.plot_chromaticity_diagram`,
        :func:`colour.plotting.diagrams.\
plot_RGB_colourspaces_in_chromaticity_diagram`,
        :func:`colour.plotting.render`},
        Please refer to the documentation of the previously listed definitions.

    Returns
    -------
    tuple
        Current figure and axes.

    Examples
    --------
    >>> RGB = np.random.random((128, 128, 3))
    >>> plot_RGB_chromaticities_in_chromaticity_diagram(
    ...     RGB, 'ITU-R BT.709')
    ... # doctest: +SKIP

    .. image:: ../_static/Plotting_\
Plot_RGB_Chromaticities_In_Chromaticity_Diagram_Plot.png
        :align: center
        :alt: plot_RGB_chromaticities_in_chromaticity_diagram
    """

    RGB = as_float_array(RGB).reshape(-1, 3)

    settings = {'uniform': True}
    settings.update(kwargs)

    _figure, axes = artist(**settings)

    method = method.upper()

    scatter_settings = {
        's': 40,
        'c': 'RGB',
        'marker': 'o',
        'alpha': 0.85,
    }
    if scatter_parameters is not None:
        scatter_settings.update(scatter_parameters)

    settings = dict(kwargs)
    settings.update({'axes': axes, 'standalone': False})

    colourspace = first_item(filter_RGB_colourspaces(colourspace).values())
    settings['colourspaces'] = (
        ['^{0}$'.format(colourspace.name)] + settings.get('colourspaces', []))

    chromaticity_diagram_callable(**settings)

    use_RGB_colours = scatter_settings['c'].upper() == 'RGB'
    if use_RGB_colours:
        RGB = RGB[RGB[:, 1].argsort()]
        scatter_settings['c'] = np.clip(
            RGB_to_RGB(
                RGB,
                colourspace,
                COLOUR_STYLE_CONSTANTS.colour.colourspace,
                apply_encoding_cctf=True).reshape(-1, 3), 0, 1)

    XYZ = RGB_to_XYZ(RGB, colourspace.whitepoint, colourspace.whitepoint,
                     colourspace.RGB_to_XYZ_matrix)

    if method == 'CIE 1931':
        ij = XYZ_to_xy(XYZ, colourspace.whitepoint)
    elif method == 'CIE 1960 UCS':
        ij = UCS_to_uv(XYZ_to_UCS(XYZ))

    elif method == 'CIE 1976 UCS':
        ij = Luv_to_uv(
            XYZ_to_Luv(XYZ, colourspace.whitepoint), colourspace.whitepoint)

    axes.scatter(ij[..., 0], ij[..., 1], **scatter_settings)

    settings.update({'standalone': True})
    settings.update(kwargs)

    return render(**settings)
Ejemplo n.º 20
0
def plot_RGB_colourspaces_in_chromaticity_diagram(
        colourspaces=None,
        cmfs='CIE 1931 2 Degree Standard Observer',
        chromaticity_diagram_callable=plot_chromaticity_diagram,
        method='CIE 1931',
        show_whitepoints=True,
        show_pointer_gamut=False,
        **kwargs):
    """
    Plots given *RGB* colourspaces in the *Chromaticity Diagram* according
    to given method.

    Parameters
    ----------
    colourspaces : array_like, optional
        *RGB* colourspaces to plot.
    cmfs : unicode, optional
        Standard observer colour matching functions used for
        *Chromaticity Diagram* bounds.
    chromaticity_diagram_callable : callable, optional
        Callable responsible for drawing the *Chromaticity Diagram*.
    method : unicode, optional
        **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**,
        *Chromaticity Diagram* method.
    show_whitepoints : bool, optional
        Whether to display the *RGB* colourspaces whitepoints.
    show_pointer_gamut : bool, optional
        Whether to display the *Pointer's Gamut*.

    Other Parameters
    ----------------
    \\**kwargs : dict, optional
        {:func:`colour.plotting.artist`,
        :func:`colour.plotting.diagrams.plot_chromaticity_diagram`,
        :func:`colour.plotting.plot_pointer_gamut`,
        :func:`colour.plotting.render`},
        Please refer to the documentation of the previously listed definitions.

    Returns
    -------
    tuple
        Current figure and axes.

    Examples
    --------
    >>> plot_RGB_colourspaces_in_chromaticity_diagram(
    ...     ['ITU-R BT.709', 'ACEScg', 'S-Gamut'])
    ... # doctest: +SKIP

    .. image:: ../_static/Plotting_\
Plot_RGB_Colourspaces_In_Chromaticity_Diagram.png
        :align: center
        :alt: plot_RGB_colourspaces_in_chromaticity_diagram
    """

    if colourspaces is None:
        colourspaces = ['ITU-R BT.709', 'ACEScg', 'S-Gamut']

    colourspaces = filter_RGB_colourspaces(colourspaces).values()

    settings = {'uniform': True}
    settings.update(kwargs)

    _figure, axes = artist(**settings)

    method = method.upper()

    cmfs = first_item(filter_cmfs(cmfs).values())

    title = '{0}\n{1} - {2} Chromaticity Diagram'.format(
        ', '.join([colourspace.name for colourspace in colourspaces]),
        cmfs.name, method)

    settings = {'axes': axes, 'title': title, 'method': method}
    settings.update(kwargs)
    settings['standalone'] = False

    chromaticity_diagram_callable(**settings)

    if show_pointer_gamut:
        settings = {'axes': axes, 'method': method}
        settings.update(kwargs)
        settings['standalone'] = False

        plot_pointer_gamut(**settings)

    if method == 'CIE 1931':

        def xy_to_ij(xy):
            """
            Converts given *xy* chromaticity coordinates to *ij* chromaticity
            coordinates.
            """

            return xy

        x_limit_min, x_limit_max = [-0.1], [0.9]
        y_limit_min, y_limit_max = [-0.1], [0.9]
    elif method == 'CIE 1960 UCS':

        def xy_to_ij(xy):
            """
            Converts given *xy* chromaticity coordinates to *ij* chromaticity
            coordinates.
            """

            return xy_to_UCS_uv(xy)

        x_limit_min, x_limit_max = [-0.1], [0.7]
        y_limit_min, y_limit_max = [-0.2], [0.6]

    elif method == 'CIE 1976 UCS':

        def xy_to_ij(xy):
            """
            Converts given *xy* chromaticity coordinates to *ij* chromaticity
            coordinates.
            """

            return xy_to_Luv_uv(xy)

        x_limit_min, x_limit_max = [-0.1], [0.7]
        y_limit_min, y_limit_max = [-0.1], [0.7]
    else:
        raise ValueError(
            'Invalid method: "{0}", must be one of '
            '{{\'CIE 1931\', \'CIE 1960 UCS\', \'CIE 1976 UCS\'}}'.format(
                method))

    settings = {'colour_cycle_count': len(colourspaces)}
    settings.update(kwargs)

    cycle = colour_cycle(**settings)

    for colourspace in colourspaces:
        R, G, B, _A = next(cycle)

        # RGB colourspaces such as *ACES2065-1* have primaries with
        # chromaticity coordinates set to 0 thus we prevent nan from being
        # yield by zero division in later colour transformations.
        P = np.where(
            colourspace.primaries == 0,
            EPSILON,
            colourspace.primaries,
        )
        P = xy_to_ij(P)
        W = xy_to_ij(colourspace.whitepoint)

        axes.plot(
            (W[0], W[0]), (W[1], W[1]),
            color=(R, G, B),
            label=colourspace.name)

        if show_whitepoints:
            axes.plot((W[0], W[0]), (W[1], W[1]), 'o', color=(R, G, B))

        axes.plot(
            (P[0, 0], P[1, 0]), (P[0, 1], P[1, 1]), 'o-', color=(R, G, B))
        axes.plot(
            (P[1, 0], P[2, 0]), (P[1, 1], P[2, 1]), 'o-', color=(R, G, B))
        axes.plot(
            (P[2, 0], P[0, 0]), (P[2, 1], P[0, 1]), 'o-', color=(R, G, B))

        x_limit_min.append(np.amin(P[..., 0]) - 0.1)
        y_limit_min.append(np.amin(P[..., 1]) - 0.1)
        x_limit_max.append(np.amax(P[..., 0]) + 0.1)
        y_limit_max.append(np.amax(P[..., 1]) + 0.1)

    bounding_box = (
        min(x_limit_min),
        max(x_limit_max),
        min(y_limit_min),
        max(y_limit_max),
    )

    settings.update({
        'standalone': True,
        'legend': True,
        'bounding_box': bounding_box,
    })
    settings.update(kwargs)

    return render(**settings)
def RGB_image_scatter_visual(path,
                             primary_colourspace=PRIMARY_COLOURSPACE,
                             secondary_colourspace=SECONDARY_COLOURSPACE,
                             image_colourspace=IMAGE_COLOURSPACE,
                             image_decoding_cctf=IMAGE_DECODING_CCTF,
                             colourspace_model=COLOURSPACE_MODEL,
                             out_of_primary_colourspace_gamut=False,
                             out_of_secondary_colourspace_gamut=False,
                             out_of_pointer_gamut=False,
                             sub_sampling=25,
                             saturate=False):
    """
    Returns a RGB image scatter visual geometry formatted as *JSON* for
    given image.

    Parameters
    ----------
    path : unicode
        Server side path of the image to read to generate the scatter points.
    primary_colourspace : unicode, optional
        Primary RGB colourspace used to generate the visual geometry.
    secondary_colourspace: unicode, optional
        Secondary RGB colourspace used to generate the visual geometry.
    image_colourspace: unicode, optional
        **{'Primary', 'Secondary'}**,
        Analysed image RGB colourspace.
    image_decoding_cctf : unicode, optional
        Analysed image decoding colour component transfer function
        (Decoding CCTF) / electro-optical transfer function (EOTF / EOCF) that
        maps an :math:`R'G'B'` video component signal value to tristimulus
        values at the display.
    colourspace_model : unicode, optional
        Colourspace model used to generate the visual geometry.
    out_of_primary_colourspace_gamut : bool, optional
        Whether to only generate the out of primary RGB colourspace gamut
        visual geometry.
    out_of_secondary_colourspace_gamut : bool, optional
        Whether to only generate the out of secondary RGB colourspace gamut
        visual geometry.
    out_of_pointer_gamut : bool, optional
        Whether to only generate the out of *Pointer's Gamut* visual geometry.
    sub_sampling : int, optional
        Consider every ``sub_sampling`` pixels of the image to generate the
        visual geometry. Using a low number will yield a large quantity of
        points, e.g. *1* yields *2073600* points for a *1080p* image.
    saturate : bool, optional
        Whether to clip the image in domain [0, 1].

    Returns
    -------
    unicode
        RGB image scatter visual geometry formatted as *JSON*.
    """

    primary_colourspace = first_item(
        filter_RGB_colourspaces('^{0}$'.format(
            re.escape(primary_colourspace))))
    secondary_colourspace = first_item(
        filter_RGB_colourspaces('^{0}$'.format(
            re.escape(secondary_colourspace))))

    colourspace = (primary_colourspace if image_colourspace == 'Primary' else
                   secondary_colourspace)

    RGB = load_image(path, image_decoding_cctf)

    if saturate:
        RGB = np.clip(RGB, 0, 1)

    RGB = RGB[..., 0:3].reshape(-1, 3)[::sub_sampling]

    if out_of_primary_colourspace_gamut:
        RGB_c = np.copy(RGB)

        if image_colourspace == 'Secondary':
            RGB_c = RGB_to_RGB(RGB, secondary_colourspace, primary_colourspace)

        RGB = RGB[np.any(np.logical_or(RGB_c < 0, RGB_c > 1), axis=-1)]

    if out_of_secondary_colourspace_gamut:
        RGB_c = np.copy(RGB)

        if image_colourspace == 'Primary':
            RGB_c = RGB_to_RGB(RGB, primary_colourspace, secondary_colourspace)

        RGB = RGB[np.any(np.logical_or(RGB_c < 0, RGB_c > 1), axis=-1)]

    if out_of_pointer_gamut:
        O_PG = is_within_pointer_gamut(
            RGB_to_XYZ(RGB, colourspace.whitepoint, colourspace.whitepoint,
                       colourspace.RGB_to_XYZ_matrix)).astype(np.int_)
        O_PG = 1 - O_PG
        RGB = RGB[O_PG == 1]

    XYZ = RGB_to_XYZ(RGB, colourspace.whitepoint, colourspace.whitepoint,
                     colourspace.RGB_to_XYZ_matrix)

    vertices = colourspace_model_axis_reorder(
        XYZ_to_colourspace_model_normalised(XYZ, colourspace.whitepoint,
                                            colourspace_model),
        colourspace_model)

    if (out_of_primary_colourspace_gamut or out_of_secondary_colourspace_gamut
            or out_of_pointer_gamut):
        RGB = np.ones(RGB.shape)

    return buffer_geometry(position=vertices, color=RGB)
def RGB_colourspace_volume_visual(colourspace='ITU-R BT.709',
                                  reference_colourspace='CIE xyY',
                                  segments=16,
                                  uniform_colour=None,
                                  uniform_opacity=0.5,
                                  wireframe=True,
                                  wireframe_colour=None,
                                  wireframe_opacity=1.0,
                                  parent=None):
    """
    Returns a :class:`vispy.scene.visuals.Node` class instance with one or two
    :class:`colour_analysis.visuals.Box` class instance children representing
    a *RGB* colourspace volume visual.

    Parameters
    ----------
    colourspace : unicode, optional
        **{'ITU-R BT.709', 'ACES2065-1', 'ACEScc', 'ACEScg', 'ACESproxy',
        'ALEXA Wide Gamut', 'Adobe RGB (1998)', 'Adobe Wide Gamut RGB',
        'Apple RGB', 'Best RGB', 'Beta RGB', 'CIE RGB', 'Cinema Gamut',
        'ColorMatch RGB', 'DCI-P3', 'DCI-P3+', 'DRAGONcolor', 'DRAGONcolor2',
        'Don RGB 4', 'ECI RGB v2', 'ERIMM RGB', 'Ekta Space PS 5', 'Max RGB',
        'NTSC', 'Pal/Secam', 'ProPhoto RGB', 'REDcolor', 'REDcolor2',
        'REDcolor3', 'REDcolor4', 'RIMM RGB', 'ROMM RGB', 'ITU-R BT.2020',
        'Russell RGB', 'S-Gamut', 'S-Gamut3', 'S-Gamut3.Cine', 'SMPTE-C RGB',
        'V-Gamut', 'Xtreme RGB', 'sRGB'}**,
        :class:`colour.RGB_Colourspace` class instance name defining the *RGB*
        colourspace volume to draw.
    reference_colourspace : unicode
        **{'CIE XYZ', 'CIE xyY', 'CIE Lab', 'CIE Luv', 'CIE UCS', 'CIE UVW',
        'IPT', 'Hunter Lab', 'Hunter Rdab'}**,
        Reference colourspace to convert the *CIE XYZ* tristimulus values to.
    segments : int, optional
        Box segments.
    uniform_colour : array_like, optional
        Uniform mesh colour.
    uniform_opacity : numeric, optional
        Uniform mesh opacity.
    wireframe : bool, optional
        Use wireframe display.
        Uniform mesh opacity.
    wireframe_colour : array_like, optional
        Wireframe mesh colour.
    wireframe_opacity : numeric, optional
        Wireframe mesh opacity.
    parent : Node, optional
        Parent of the *RGB* colourspace volume visual in the `SceneGraph`.
    """

    node = Node(parent)

    colourspace = first_item(filter_RGB_colourspaces(colourspace).values())

    RGB_cube_f = RGB_identity_cube(
        width_segments=segments,
        height_segments=segments,
        depth_segments=segments,
        uniform_colour=uniform_colour,
        uniform_opacity=uniform_opacity,
        vertex_colours=not uniform_colour,
        parent=node)

    vertices = RGB_cube_f.mesh_data.get_vertices()
    XYZ = RGB_to_XYZ(vertices, colourspace.whitepoint, colourspace.whitepoint,
                     colourspace.RGB_to_XYZ_matrix)
    value = common_colourspace_model_axis_reorder(
        XYZ_to_colourspace_model(XYZ, colourspace.whitepoint,
                                 reference_colourspace), reference_colourspace)
    value[np.isnan(value)] = 0

    RGB_cube_f.mesh_data.set_vertices(value)

    if wireframe:
        RGB_cube_w = RGB_identity_cube(
            width_segments=segments,
            height_segments=segments,
            depth_segments=segments,
            uniform_colour=wireframe_colour,
            uniform_opacity=wireframe_opacity,
            vertex_colours=not wireframe_colour,
            wireframe=True,
            parent=node)
        RGB_cube_w.mesh_data.set_vertices(value)

    return node
Ejemplo n.º 23
0
def plot_RGB_scatter(RGB,
                     colourspace,
                     reference_colourspace='CIE xyY',
                     colourspaces=None,
                     segments=8,
                     show_grid=True,
                     grid_segments=10,
                     show_spectral_locus=False,
                     spectral_locus_colour=None,
                     points_size=12,
                     cmfs='CIE 1931 2 Degree Standard Observer',
                     **kwargs):
    """
    Plots given *RGB* colourspace array in a scatter plot.

    Parameters
    ----------
    RGB : array_like
        *RGB* colourspace array.
    colourspace : RGB_Colourspace
        *RGB* colourspace of the *RGB* array.
    reference_colourspace : unicode, optional
        **{'CIE XYZ', 'CIE xyY', 'CIE xy', 'CIE Lab', 'CIE LCHab', 'CIE Luv',
        'CIE Luv uv', 'CIE LCHuv', 'CIE UCS', 'CIE UCS uv', 'CIE UVW',
        'DIN 99', 'Hunter Lab', 'Hunter Rdab', 'IPT', 'JzAzBz', 'OSA UCS',
        'hdr-CIELAB', 'hdr-IPT'}**,
        Reference colourspace for colour conversion.
    colourspaces : array_like, optional
        *RGB* colourspaces to plot the gamuts.
    segments : int, optional
        Edge segments count for each *RGB* colourspace cubes.
    show_grid : bool, optional
        Whether to show a grid at the bottom of the *RGB* colourspace cubes.
    grid_segments : bool, optional
        Edge segments count for the grid.
    show_spectral_locus : bool, optional
        Whether to show the spectral locus.
    spectral_locus_colour : array_like, optional
        Spectral locus colour.
    points_size : numeric, optional
        Scatter points size.
    cmfs : unicode, optional
        Standard observer colour matching functions used for spectral locus.

    Other Parameters
    ----------------
    \\**kwargs : dict, optional
        {:func:`colour.plotting.artist`,
        :func:`colour.plotting.plot_RGB_colourspaces_gamuts`},
        Please refer to the documentation of the previously listed definitions.

    Returns
    -------
    tuple
        Current figure and axes.

    Examples
    --------
    >>> RGB = np.random.random((128, 128, 3))
    >>> plot_RGB_scatter(RGB, 'ITU-R BT.709')  # doctest: +SKIP

    .. image:: ../_static/Plotting_Plot_RGB_Scatter.png
        :align: center
        :alt: plot_RGB_scatter
    """

    colourspace = first_item(filter_RGB_colourspaces(colourspace).values())

    if colourspaces is None:
        colourspaces = (colourspace.name, )

    count_c = len(colourspaces)
    settings = Structure(
        **{
            'face_colours': [None] * count_c,
            'edge_colours': [(0.25, 0.25, 0.25)] * count_c,
            'face_alpha': [0.0] * count_c,
            'edge_alpha': [0.1] * count_c,
        })
    settings.update(kwargs)
    settings['standalone'] = False

    plot_RGB_colourspaces_gamuts(
        colourspaces=colourspaces,
        reference_colourspace=reference_colourspace,
        segments=segments,
        show_grid=show_grid,
        grid_segments=grid_segments,
        show_spectral_locus=show_spectral_locus,
        spectral_locus_colour=spectral_locus_colour,
        cmfs=cmfs,
        **settings)

    XYZ = RGB_to_XYZ(RGB, colourspace.whitepoint, colourspace.whitepoint,
                     colourspace.RGB_to_XYZ_matrix)

    points = common_colourspace_model_axis_reorder(
        XYZ_to_colourspace_model(XYZ, colourspace.whitepoint,
                                 reference_colourspace), reference_colourspace)

    axes = plt.gca()
    axes.scatter(
        points[..., 0],
        points[..., 1],
        points[..., 2],
        color=np.reshape(RGB, (-1, 3)),
        s=points_size)

    settings.update({'axes': axes, 'standalone': True})
    settings.update(kwargs)

    return render(**settings)
Ejemplo n.º 24
0
def plot_RGB_colourspaces_in_chromaticity_diagram(
        colourspaces=None,
        cmfs='CIE 1931 2 Degree Standard Observer',
        chromaticity_diagram_callable=plot_chromaticity_diagram,
        method='CIE 1931',
        show_whitepoints=True,
        show_pointer_gamut=False,
        **kwargs):
    """
    Plots given *RGB* colourspaces in the *Chromaticity Diagram* according
    to given method.

    Parameters
    ----------
    colourspaces : array_like, optional
        *RGB* colourspaces to plot.
    cmfs : unicode, optional
        Standard observer colour matching functions used for
        *Chromaticity Diagram* bounds.
    chromaticity_diagram_callable : callable, optional
        Callable responsible for drawing the *Chromaticity Diagram*.
    method : unicode, optional
        **{'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'}**,
        *Chromaticity Diagram* method.
    show_whitepoints : bool, optional
        Whether to display the *RGB* colourspaces whitepoints.
    show_pointer_gamut : bool, optional
        Whether to display the *Pointer's Gamut*.

    Other Parameters
    ----------------
    \\**kwargs : dict, optional
        {:func:`colour.plotting.artist`,
        :func:`colour.plotting.diagrams.plot_chromaticity_diagram`,
        :func:`colour.plotting.plot_pointer_gamut`,
        :func:`colour.plotting.render`},
        Please refer to the documentation of the previously listed definitions.

    Returns
    -------
    tuple
        Current figure and axes.

    Examples
    --------
    >>> plot_RGB_colourspaces_in_chromaticity_diagram(
    ...     ['ITU-R BT.709', 'ACEScg', 'S-Gamut'])
    ... # doctest: +SKIP

    .. image:: ../_static/Plotting_\
Plot_RGB_Colourspaces_In_Chromaticity_Diagram.png
        :align: center
        :alt: plot_RGB_colourspaces_in_chromaticity_diagram
    """

    if colourspaces is None:
        colourspaces = ['ITU-R BT.709', 'ACEScg', 'S-Gamut']

    colourspaces = filter_RGB_colourspaces(colourspaces).values()

    settings = {'uniform': True}
    settings.update(kwargs)

    figure, axes = artist(**settings)

    method = method.upper()

    cmfs = first_item(filter_cmfs(cmfs).values())

    title = '{0}\n{1} - {2} Chromaticity Diagram'.format(
        ', '.join([colourspace.name for colourspace in colourspaces]),
        cmfs.name, method)

    settings = {'axes': axes, 'title': title, 'method': method}
    settings.update(kwargs)
    settings['standalone'] = False

    chromaticity_diagram_callable(**settings)

    if show_pointer_gamut:
        settings = {'axes': axes, 'method': method}
        settings.update(kwargs)
        settings['standalone'] = False

        plot_pointer_gamut(**settings)

    if method == 'CIE 1931':

        def xy_to_ij(xy):
            """
            Converts given *xy* chromaticity coordinates to *ij* chromaticity
            coordinates.
            """

            return xy

        x_limit_min, x_limit_max = [-0.1], [0.9]
        y_limit_min, y_limit_max = [-0.1], [0.9]
    elif method == 'CIE 1960 UCS':

        def xy_to_ij(xy):
            """
            Converts given *xy* chromaticity coordinates to *ij* chromaticity
            coordinates.
            """

            return xy_to_UCS_uv(xy)

        x_limit_min, x_limit_max = [-0.1], [0.7]
        y_limit_min, y_limit_max = [-0.2], [0.6]

    elif method == 'CIE 1976 UCS':

        def xy_to_ij(xy):
            """
            Converts given *xy* chromaticity coordinates to *ij* chromaticity
            coordinates.
            """

            return xy_to_Luv_uv(xy)

        x_limit_min, x_limit_max = [-0.1], [0.7]
        y_limit_min, y_limit_max = [-0.1], [0.7]
    else:
        raise ValueError(
            'Invalid method: "{0}", must be one of '
            '{\'CIE 1931\', \'CIE 1960 UCS\', \'CIE 1976 UCS\'}'.format(
                method))

    settings = {'colour_cycle_count': len(colourspaces)}
    settings.update(kwargs)

    cycle = colour_cycle(**settings)

    for colourspace in colourspaces:
        R, G, B, _A = next(cycle)

        # RGB colourspaces such as *ACES2065-1* have primaries with
        # chromaticity coordinates set to 0 thus we prevent nan from being
        # yield by zero division in later colour transformations.
        P = np.where(
            colourspace.primaries == 0,
            EPSILON,
            colourspace.primaries,
        )
        P = xy_to_ij(P)
        W = xy_to_ij(colourspace.whitepoint)

        axes.plot((W[0], W[0]), (W[1], W[1]),
                  color=(R, G, B),
                  label=colourspace.name)

        if show_whitepoints:
            axes.plot((W[0], W[0]), (W[1], W[1]), 'o', color=(R, G, B))

        axes.plot((P[0, 0], P[1, 0]), (P[0, 1], P[1, 1]),
                  'o-',
                  color=(R, G, B))
        axes.plot((P[1, 0], P[2, 0]), (P[1, 1], P[2, 1]),
                  'o-',
                  color=(R, G, B))
        axes.plot((P[2, 0], P[0, 0]), (P[2, 1], P[0, 1]),
                  'o-',
                  color=(R, G, B))

        x_limit_min.append(np.amin(P[..., 0]) - 0.1)
        y_limit_min.append(np.amin(P[..., 1]) - 0.1)
        x_limit_max.append(np.amax(P[..., 0]) + 0.1)
        y_limit_max.append(np.amax(P[..., 1]) + 0.1)

    bounding_box = (
        min(x_limit_min),
        max(x_limit_max),
        min(y_limit_min),
        max(y_limit_max),
    )

    settings.update({
        'standalone': True,
        'legend': True,
        'bounding_box': bounding_box,
    })
    settings.update(kwargs)

    return render(**settings)