Ejemplo n.º 1
0
def make_orimask(radians, mag=None, alpha=1.0):
    """
    Makes a colormap in HSV space where the orientation changes color and mag
    changes the saturation/value.

    Args:
        radians (ndarray): orientation in radians
        mag (ndarray): magnitude (must be normalized between 0 and 1)
        alpha (float | ndarray):
            if False or None, then the image is returned without alpha
            if a float, then mag is scaled by this and used as the alpha channel
            if an ndarray, then this is explicilty set as the alpha channel

    Returns:
        ndarray[float32]: an rgb / rgba image in 01 space

    SeeAlso:
        kwimage.overlay_alpha_images

    Example:
        >>> # xdoc: +REQUIRES(module:matplotlib)
        >>> x, y = np.meshgrid(np.arange(64), np.arange(64))
        >>> dx, dy = x - 32, y - 32
        >>> radians = np.arctan2(dx, dy)
        >>> mag = np.sqrt(dx ** 2 + dy ** 2)
        >>> orimask = make_orimask(radians, mag)
        >>> # xdoc: +REQUIRES(--show)
        >>> import kwplot
        >>> kwplot.imshow(orimask, fnum=1, doclf=True, colorspace='rgb')
        >>> kwplot.show_if_requested()
    """
    import matplotlib as mpl
    import matplotlib.cm  # NOQA
    TAU = np.pi * 2
    # Map radians to 0 to 1
    ori01 = (radians % TAU) / TAU
    cmap_ = mpl.cm.get_cmap('hsv')
    color_rgb = cmap_(ori01)[..., 0:3].astype(np.float32)
    if mag is not None:
        import kwimage
        if mag.max() > 1:
            mag = mag / mag.max()
        color_hsv = kwimage.convert_colorspace(color_rgb, 'rgb', 'hsv')
        color_hsv[..., 1:3] = mag[..., None]
        color_rgb = kwimage.convert_colorspace(color_hsv, 'hsv', 'rgb')
    else:
        mag = 1
    orimask = np.array(color_rgb, dtype=np.float32)

    if isinstance(alpha, np.ndarray):
        # Alpha specified as explicit numpy array
        orimask = kwimage.ensure_alpha_channel(orimask)
        orimask[:, :, 3] = alpha
    elif alpha is not False and alpha is not None:
        orimask = kwimage.ensure_alpha_channel(orimask)
        orimask[:, :, 3] = mag * alpha
    return orimask
Ejemplo n.º 2
0
    def _draw_batch(harn, batch, decoded, limit=32):
        """
        Example:
            >>> # xdoctest: +REQUIRES(--download)
            >>> harn = setup_harn().initialize()
            >>> #
            >>> batch = harn._demo_batch(0, tag='test')
            >>> outputs, loss = harn.run_batch(batch)
            >>> bx = harn.bxs[harn.current_tag]
            >>> decoded = harn._decode(outputs, batch['label'])
            >>> fpath = harn._draw_batch(bx, batch, decoded, limit=42)
            >>> print('fpath = {!r}'.format(fpath))
            >>> # xdoctest: +REQUIRES(--show)
            >>> import kwplot
            >>> kwplot.autompl()
            >>> kwplot.imshow(fpath, colorspace='rgb', doclf=True)
            >>> kwplot.show_if_requested()
        """
        import kwimage
        import kwplot
        inputs = batch['input']
        inputs = inputs[0:limit]

        input_shape = inputs.shape
        dims = [160] * (len(input_shape) - 2)
        min_, max_ = inputs.min(), inputs.max()
        inputs = (inputs - min_) / (max_ - min_)
        inputs = torch.nn.functional.interpolate(inputs, size=dims)
        inputs = (inputs * 255).byte()
        inputs = inputs.data.cpu().numpy()

        dset = harn.datasets[harn.current_tag]

        true_cxs = batch['label'].data.cpu().numpy()
        pred_cxs = decoded['pred_cxs'].data.cpu().numpy()
        class_probs = decoded['class_probs'].data.cpu().numpy()

        todraw = []
        for im, pcx, tcx, probs in zip(inputs, pred_cxs, true_cxs,
                                       class_probs):
            im_ = im.transpose(1, 2, 0)
            im_ = kwimage.convert_colorspace(im_, 'gray', 'rgb')
            im_ = np.ascontiguousarray(im_)
            im_ = kwplot.draw_clf_on_image(im_, dset.classes, tcx, probs)
            todraw.append(im_)

        stacked = kwimage.stack_images_grid(todraw,
                                            overlap=-10,
                                            bg_value=(10, 40, 30),
                                            chunksize=8)
        return stacked
Ejemplo n.º 3
0
def make_heatmask(probs,
                  cmap='plasma',
                  with_alpha=1.0,
                  space='rgb',
                  dsize=None):
    """
    Colorizes a single-channel intensity mask (with an alpha channel)

    Args:
        probs (ndarray): 2D probability map with values between 0 and 1
        cmap (str): mpl colormap
        with_alpha (float): between 0 and 1, uses probs as the alpha multipled
            by this number.
        space (str): output colorspace
        dsize (tuple): if not None, then output is resized to W,H=dsize

    SeeAlso:
        kwimage.overlay_alpha_images

    Example:
        >>> # xdoc: +REQUIRES(module:matplotlib)
        >>> probs = np.tile(np.linspace(0, 1, 10), (10, 1))
        >>> heatmask = make_heatmask(probs, with_alpha=0.8, dsize=(100, 100))
        >>> # xdoc: +REQUIRES(--show)
        >>> import kwplot
        >>> kwplot.imshow(heatmask, fnum=1, doclf=True, colorspace='rgb')
        >>> kwplot.show_if_requested()
    """
    import kwimage
    import matplotlib as mpl
    import matplotlib.cm  # NOQA
    assert len(probs.shape) == 2
    cmap_ = mpl.cm.get_cmap(cmap)
    probs = kwimage.ensure_float01(probs)
    heatmask = cmap_(probs).astype(np.float32)
    heatmask = kwimage.convert_colorspace(heatmask,
                                          'rgba',
                                          space,
                                          implicit=True)
    if with_alpha is not False and with_alpha is not None:
        heatmask[:, :,
                 3] = (probs * with_alpha)  # assign probs to alpha channel
    if dsize is not None:
        import cv2
        heatmask = cv2.resize(heatmask,
                              tuple(dsize),
                              interpolation=cv2.INTER_NEAREST)
    return heatmask
Ejemplo n.º 4
0
def ensure_grayscale(img, colorspace_hint='BGR'):
    """
    Example:
        >>> # xdoctest: +REQUIRES(module:kwimage)
        >>> import numpy as np
        >>> ensure_grayscale(np.array([[[0, 0, 1]]], dtype=np.float32))
        array([[0.299]], dtype=float32)
    """
    import kwimage
    img = kwimage.ensure_float01(img, copy=False)
    c = get_num_channels(img)
    if c == 1:
        return img
    else:
        return kwimage.convert_colorspace(img,
                                          src_space=colorspace_hint,
                                          dst_space='gray')
Ejemplo n.º 5
0
def imshow(img,
           fnum=None, pnum=None,
           xlabel=None, title=None, figtitle=None, ax=None,
           norm=None, cmap=None, data_colorbar=False,
           colorspace='rgb',
           interpolation='nearest', alpha=None,
           **kwargs):
    r"""
    Args:
        img (ndarray): image data. Height, Width, and Channel dimensions
            can either be in standard (H, W, C) format or in (C, H, W) format.
            If C in [3, 4], we assume data is in the rgb / rgba colorspace by
            default.

        colorspace (str): if the data is 3-4 channels, this indicates the
            colorspace 1 channel data is assumed grayscale. 4 channels assumes
            alpha.

        interpolation (str): either nearest (default), bicubic, bilinear

        norm (bool): if True, normalizes the image intensities to fit in a
            colormap.

        cmap (Colormap): color map used if data is not starndard image data

        data_colorbar (bool): if True, displays a color scale indicating how
            colors map to image intensities.

        fnum (int): figure number

        pnum (tuple): plot number

        xlabel (str): sets the label for the x axis

        title (str): set axes title (if ax is not given)

        figtitle (None): set figure title (if ax is not given)

        ax (Axes): axes to draw on (alternative to fnum and pnum)

        **kwargs: docla, doclf, projection

    Returns:
        tuple: (fig, ax)

    Ignore:
        >>> import kwplot
        >>> kwplot.autompl()
        >>> import kwimage
        >>> img = kwimage.grab_test_image('carl')
        >>> (fig, ax) = imshow(img)
        >>> result = ('(fig, ax) = %s' % (str((fig, ax)),))
        >>> print(result)
        >>> kwplot.show_if_requested()
    """
    import matplotlib as mpl
    import matplotlib.pyplot as plt

    if ax is not None:
        fig = ax.figure
        nospecial = True
    else:
        fig = figure(fnum=fnum, pnum=pnum, title=title, figtitle=figtitle, **kwargs)
        ax = fig.gca()
        nospecial = False

    if isinstance(img, six.string_types):
        # Allow for path to image to be specified
        img_fpath = img
        import kwimage
        img = kwimage.imread(img_fpath)

    valid_interpolation_choices = ['nearest', 'bicubic', 'bilinear']

    if interpolation not in valid_interpolation_choices:
        raise KeyError(
            'Invalid interpolation choice {}. Can be {}'.format(
                interpolation, valid_interpolation_choices))

    plt_imshow_kwargs = {
        'interpolation': interpolation,
    }
    if alpha is not None:
        plt_imshow_kwargs['alpha'] = alpha

    if norm is not None:
        if norm is True:
            norm = 'linear'
        if isinstance(norm, six.string_types):
            norm_choices = {
                'linear': mpl.colors.Normalize,
                'log': mpl.colors.LogNorm,
            }
            try:
                norm = norm_choices[norm]()
            except KeyError:
                raise KeyError('norm={} not in valid choices: {}'.format(
                    norm, list(norm_choices)
                ))
        if not isinstance(norm, mpl.colors.Normalize):
            raise TypeError('norm={} must be an instance of {} or in {}'.format(
                norm, mpl.colors.Normalize, list(norm_choices)))

        plt_imshow_kwargs['norm'] = norm
    else:
        if cmap is None and not nospecial:
            plt_imshow_kwargs['vmin'] = 0
            plt_imshow_kwargs['vmax'] = 255

    # Handle tensor chw format in most cases
    try:
        if 'torch' in img.__module__:
            img = img.cpu().data.numpy()
    except Exception:
        pass

    if img.ndim == 3:
        if img.shape[0] == 3 or img.shape[0] == 1:
            if img.shape[2] > 4:
                # probably in chw format
                img = img.transpose(1, 2, 0)
    try:
        if len(img.shape) == 3 and (img.shape[2] == 3 or img.shape[2] == 4):
            # img is in a color format
            dst_space = 'rgb'
            import kwimage
            imgRGB = kwimage.convert_colorspace(img, src_space=colorspace,
                                                dst_space=dst_space,
                                                implicit=True)
            if not norm:
                if  imgRGB.dtype.kind == 'f':
                    maxval = imgRGB.max()
                    if maxval > 1.01 and maxval < 256:
                        imgRGB = np.array(imgRGB, dtype=np.uint8)
            cs = ax.imshow(imgRGB, **plt_imshow_kwargs)

        elif len(img.shape) == 2 or (len(img.shape) == 3 and img.shape[2] == 1):
            # img is in grayscale
            if len(img.shape) == 3:
                imgGRAY = img.reshape(img.shape[0:2])
            else:
                imgGRAY = img
            if cmap is None:
                cmap = plt.get_cmap('gray')
            if isinstance(cmap, six.string_types):
                cmap = plt.get_cmap(cmap)
            # for some reason gray floats aren't working right
            if not norm:
                if imgGRAY.max() <= 1.01 and imgGRAY.min() >= -1E-9:
                    imgGRAY = (imgGRAY * 255).astype(np.uint8)
            cs = ax.imshow(imgGRAY, cmap=cmap, **plt_imshow_kwargs)
        else:
            raise AssertionError(
                'Unknown image format. '
                'img.dtype={!r}, img.shape={!r}'.format(
                    img.dtype, img.shape)
            )
    except TypeError as te:
        print('[imshow] imshow ERROR %r' % (te,))
        raise
    except Exception as ex:
        print('!!! WARNING !!!')
        print('[imshow] type(img) = %r' % type(img))
        if not isinstance(img, np.ndarray):
            print('!!! ERRROR !!!')
            pass
        print('[imshow] img.dtype = %r' % (img.dtype,))
        print('[imshow] type(img) = %r' % (type(img),))
        print('[imshow] img.shape = %r' % (img.shape,))
        print('[imshow] imshow ERROR %r' % ex)
        raise
    ax.set_xticks([])
    ax.set_yticks([])

    if data_colorbar:
        # Use the axes to supply the colorbar info
        # Does this mean we can depricate `colorbar`?
        cbar = fig.colorbar(cs)

        if isinstance(norm, mpl.colors.LogNorm):
            # References:
            #    https://github.com/matplotlib/matplotlib/issues/8307
            cbar.ax.yaxis.set_major_locator(mpl.ticker.LogLocator())  # <- Why? See refs
            cbar.set_ticks(cbar.ax.yaxis.get_major_locator().tick_values(
                img.min(), img.max()))

        # scores = np.unique(img.flatten())
        # if cmap is None:
        #     cmap = 'hot'
        # colors = scores_to_color(scores, cmap)
        # colorbar(scores, colors)

    if xlabel is not None:
        ax.set_xlabel(xlabel)

    if figtitle is not None:
        set_figtitle(figtitle)
    return fig, ax
Ejemplo n.º 6
0
def make_legend_img(label_to_color,
                    dpi=96,
                    shape=(200, 200),
                    mode='line',
                    transparent=False):
    """
    Makes an image of a categorical legend

    Args:
        label_to_color (Dict[str, Color]): mapping from string label to the
            color.

    CommandLine:
        xdoctest -m kwplot.mpl_make make_legend_img --show

    Example:
        >>> # xdoctest: +REQUIRES(module:kwplot)
        >>> import kwplot
        >>> import kwimage
        >>> label_to_color = {
        >>>     'blue': kwimage.Color('blue').as01(),
        >>>     'red': kwimage.Color('red').as01(),
        >>>     'green': 'green',
        >>>     'yellow': 'yellow',
        >>>     'orangered': 'orangered',
        >>> }
        >>> img = make_legend_img(label_to_color, transparent=True)
        >>> # xdoctest: +REQUIRES(--show)
        >>> kwplot.autompl()
        >>> kwplot.imshow(img)
        >>> kwplot.show_if_requested()
    """
    import kwplot
    import kwimage
    plt = kwplot.autoplt()

    def append_phantom_legend_label(label,
                                    color,
                                    type_='line',
                                    alpha=1.0,
                                    ax=None):
        if ax is None:
            ax = plt.gca()
        _phantom_legend_list = getattr(ax, '_phantom_legend_list', None)
        if _phantom_legend_list is None:
            _phantom_legend_list = []
            setattr(ax, '_phantom_legend_list', _phantom_legend_list)
        if type_ == 'line':
            phantom_actor = plt.Line2D((0, 0), (1, 1),
                                       color=color,
                                       label=label,
                                       alpha=alpha)
        else:
            phantom_actor = plt.Circle((0, 0),
                                       1,
                                       fc=color,
                                       label=label,
                                       alpha=alpha)
        _phantom_legend_list.append(phantom_actor)

    fig = plt.figure(dpi=dpi)

    w, h = shape[1] / dpi, shape[0] / dpi
    fig.set_size_inches(w, h)

    # ax = fig.add_subplot('111')
    ax = fig.add_subplot(1, 1, 1)
    for label, color in label_to_color.items():
        color = kwimage.Color(color).as01()
        append_phantom_legend_label(label, color, type_=mode, ax=ax)

    _phantom_legend_list = getattr(ax, '_phantom_legend_list', None)
    if _phantom_legend_list is None:
        _phantom_legend_list = []
        setattr(ax, '_phantom_legend_list', _phantom_legend_list)
    ax.legend(handles=_phantom_legend_list)
    ax.grid(False)
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
    plt.axis('off')
    legend_img = render_figure_to_image(fig, dpi=dpi, transparent=transparent)
    legend_img = kwimage.convert_colorspace(legend_img,
                                            src_space='bgr',
                                            dst_space='rgb')
    legend_img = crop_border_by_color(legend_img)

    plt.close(fig)
    return legend_img
Ejemplo n.º 7
0
    def plot_kernel3d(i):
        img = weights_flat[i]

        # fig = kwplot.figure(fnum=fnum, pnum=pnum_[i])
        ax = fig.add_subplot(*pnum_[i], projection='3d')
        # ax = fig.gca(projection='3d')

        alpha_ = (filled * alpha)[..., None]
        colors = img

        if not color_axes:
            import kwimage
            # transform grays into colors
            grays = kwimage.atleast_nd(img, 4)
            colors = np.concatenate([grays, grays, grays], axis=3)

        if colorspace and color_axes:
            import kwimage
            # convert into RGB
            for d in range(len(colors)):
                colors[d] = kwimage.convert_colorspace(colors[d],
                                                       src_space=colorspace,
                                                       dst_space='rgb')
        facecolors = np.concatenate([colors, alpha_], axis=3)

        # shuffle dims so height is upwards and depth move away from us.
        dim_labels = ['d', 'h', 'w']
        axes = [2, 0, 1]

        dim_labels = list(ub.take(dim_labels, axes))
        facecolors = facecolors.transpose(*(axes + [3]))
        filled_ = filled.transpose(*axes)
        spatial_axes_ = list(ub.take(spatial_axes, axes))

        # ax.voxels(filled_, facecolors=facecolors, edgecolors=facecolors)
        if False:
            ax.voxels(filled_, facecolors=facecolors, edgecolors='k')
        else:
            # hack to show "occluded" voxels
            # stride = [1, 3, 1]
            stride = [2, 2, 2]
            slices = tuple(slice(None, None, s) for s in stride)
            spatial_axes2 = list(np.array(spatial_axes_) * stride)
            filled2 = np.zeros(spatial_axes2, dtype=np.bool)
            facecolors2 = np.empty(spatial_axes2 + [4], dtype=np.float32)
            filled2[slices] = filled_
            facecolors2[slices] = facecolors
            edgecolors2 = [0, 0, 0, alpha]
            # 'k'
            # edgecolors2 = facecolors2

            # Shrink the gaps, which let you see occluded voxels
            x, y, z = np.indices(np.array(filled2.shape) +
                                 1).astype(float) // 2
            x[0::2, :, :] += 0.05
            y[:, 0::2, :] += 0.05
            z[:, :, 0::2] += 0.05
            x[1::2, :, :] += 0.95
            y[:, 1::2, :] += 0.95
            z[:, :, 1::2] += 0.95

            ax.voxels(x,
                      y,
                      z,
                      filled2,
                      facecolors=facecolors2,
                      edgecolors=edgecolors2)

        for xyz, dlbl in zip(['x', 'y', 'z'], dim_labels):
            getattr(ax, 'set_' + xyz + 'label')(dlbl)

        for xyz in ['x', 'y', 'z']:
            getattr(ax, 'set_' + xyz + 'ticks')([])

        ax.set_aspect('equal')
        if not labels or i < num_plots - 1:
            # show axis only on the last plot
            ax.grid(False)
            plt.axis('off')