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)
Ejemplo n.º 2
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
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.º 4
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