Esempio n. 1
0
    def __getitem__(self, index):
        import kwimage

        # Load sample image and category
        sample = self.sampler.load_positive(index, with_annots=False)
        image = kwimage.atleast_3channels(sample['im'])[:, :, 0:3]
        target = sample['tr']

        image = kwimage.ensure_uint255(image)
        if self.augmenter is not None:
            det = self.augmenter.to_deterministic()
            image = det.augment_image(image)

        # Resize to input dimensinos
        if self.input_dims is not None:
            dsize = tuple(self.input_dims[::-1])
            image = kwimage.imresize(image, dsize=dsize, letterbox=True)

        class_id_to_idx = self.sampler.classes.id_to_idx
        cid = target['category_id']
        cidx = class_id_to_idx[cid]

        im_chw = image.transpose(2, 0, 1) / 255.0
        inputs = {
            'rgb': torch.FloatTensor(im_chw),
        }
        labels = {
            'class_idxs': cidx,
        }
        batch = {
            'inputs': inputs,
            'labels': labels,
        }
        return batch
Esempio n. 2
0
    def _draw_batch(harn, batch, decoded, limit=32):
        """
        Example:
            >>> from ggr_matching import *
            >>> harn = setup_harn().initialize()
            >>> batch = harn._demo_batch(0, tag='vali')
            >>> outputs, loss = harn.run_batch(batch)
            >>> decoded = harn._decode(outputs)
            >>> stacked = harn._draw_batch(batch, decoded, limit=42)
            >>> # xdoctest: +REQUIRES(--show)
            >>> import kwplot
            >>> kwplot.autompl()
            >>> kwplot.imshow(stacked, colorspace='rgb', doclf=True)
            >>> kwplot.show_if_requested()
        """
        tostack = []
        fontkw = {'fontScale': 1.0, 'thickness': 2}
        n = min(limit, len(decoded['triple_imgs'][0]))
        dsize = (300, 300)
        for i in range(n):
            ims = [g[i].transpose(1, 2, 0) for g in decoded['triple_imgs']]
            ims = [cv2.resize(g, dsize) for g in ims]
            ims = [kwimage.atleast_3channels(g) for g in ims]
            triple_nxs = [n[i] for n in decoded['triple_nxs']]

            text = 'distAP={:.3g} -- distAN={:.3g} -- {}'.format(
                decoded['distAP'][i],
                decoded['distAN'][i],
                str(triple_nxs),
            )
            color = ('dodgerblue'
                     if decoded['distAP'][i] < decoded['distAN'][i] else
                     'orangered')

            img = kwimage.stack_images(ims,
                                       overlap=-2,
                                       axis=1,
                                       bg_value=(10 / 255, 40 / 255, 30 / 255))
            img = (img * 255).astype(np.uint8)
            img = kwimage.draw_text_on_image(img,
                                             text,
                                             org=(2, img.shape[0] - 2),
                                             color=color,
                                             **fontkw)
            tostack.append(img)

        stacked = kwimage.stack_images_grid(tostack,
                                            overlap=-10,
                                            bg_value=(30, 10, 40),
                                            axis=1,
                                            chunksize=3)
        return stacked
Esempio n. 3
0
    def draw_on(self, image, color='blue', fill=True, border=False, alpha=1.0,
                copy=False):
        """
        Rasterizes a polygon on an image. See `draw` for a vectorized
        matplotlib version.

        Args:
            image (ndarray): image to raster polygon on.
            color (str | tuple): data coercable to a color
            fill (bool, default=True): draw the center mass of the polygon
            border (bool, default=False): draw the border of the polygon
            alpha (float, default=1.0): polygon transparency (setting alpha < 1
                makes this function much slower).
            copy (bool, default=False): if False only copies if necessary

        Example:
            >>> # xdoc: +REQUIRES(module:kwplot)
            >>> from kwimage.structs.polygon import *  # NOQA
            >>> self = Polygon.random(n_holes=1).scale(128)
            >>> image = np.zeros((128, 128), dtype=np.float32)
            >>> image = self.draw_on(image)
            >>> # xdoc: +REQUIRES(--show)
            >>> import kwplot
            >>> kwplot.autompl()
            >>> kwplot.imshow(image, fnum=1)

        Example:
            >>> import kwimage
            >>> color = 'blue'
            >>> self = kwimage.Polygon.random(n_holes=1).scale(128)
            >>> image = np.zeros((128, 128), dtype=np.float32)
            >>> # Test drawong on all channel + dtype combinations
            >>> im3 = np.random.rand(128, 128, 3)
            >>> im_chans = {
            >>>     'im3': im3,
            >>>     'im1': kwimage.convert_colorspace(im3, 'rgb', 'gray'),
            >>>     'im4': kwimage.convert_colorspace(im3, 'rgb', 'rgba'),
            >>> }
            >>> inputs = {}
            >>> for k, im in im_chans.items():
            >>>     inputs[k + '_01'] = (kwimage.ensure_float01(im.copy()), {'alpha': None})
            >>>     inputs[k + '_255'] = (kwimage.ensure_uint255(im.copy()), {'alpha': None})
            >>>     inputs[k + '_01_a'] = (kwimage.ensure_float01(im.copy()), {'alpha': 0.5})
            >>>     inputs[k + '_255_a'] = (kwimage.ensure_uint255(im.copy()), {'alpha': 0.5})
            >>> outputs = {}
            >>> for k, v in inputs.items():
            >>>     im, kw = v
            >>>     outputs[k] = self.draw_on(im, color=color, **kw)
            >>> # xdoc: +REQUIRES(--show)
            >>> import kwplot
            >>> kwplot.figure(fnum=2, doclf=True)
            >>> kwplot.autompl()
            >>> pnum_ = kwplot.PlotNums(nCols=2, nRows=len(inputs))
            >>> for k in inputs.keys():
            >>>     kwplot.imshow(inputs[k][0], fnum=2, pnum=pnum_(), title=k)
            >>>     kwplot.imshow(outputs[k], fnum=2, pnum=pnum_(), title=k)
            >>> kwplot.show_if_requested()
        """
        import kwimage
        # return shape of contours to openCV contours

        dtype_fixer = _generic._consistent_dtype_fixer(image)

        # print('--- A')
        # print('image.dtype = {!r}'.format(image.dtype))
        # print('image.max() = {!r}'.format(image.max()))

        # line_type = cv2.LINE_AA
        line_type = cv2.LINE_8

        cv_contours = self._to_cv_countours()

        if alpha is None or alpha == 1.0:
            # image = kwimage.ensure_uint255(image)
            image = kwimage.atleast_3channels(image, copy=copy)
            rgba = kwimage.Color(color)._forimage(image)
        else:
            image = kwimage.ensure_float01(image)
            image = kwimage.ensure_alpha_channel(image)
            rgba = kwimage.Color(color, alpha=alpha)._forimage(image)

        # print('--- B')
        # print('image.dtype = {!r}'.format(image.dtype))
        # print('image.max() = {!r}'.format(image.max()))
        # print('rgba = {!r}'.format(rgba))

        if fill:
            if alpha is None or alpha == 1.0:
                # Modification happens inplace
                image = cv2.fillPoly(image, cv_contours, rgba, line_type, shift=0)
            else:
                orig = image.copy()
                mask = np.zeros_like(orig)
                mask = cv2.fillPoly(mask, cv_contours, rgba, line_type, shift=0)
                # TODO: could use add weighted
                image = kwimage.overlay_alpha_images(mask, orig)
                rgba = kwimage.Color(rgba)._forimage(image)

        # print('--- C')
        # print('image.dtype = {!r}'.format(image.dtype))
        # print('image.max() = {!r}'.format(image.max()))
        # print('rgba = {!r}'.format(rgba))

        if border or True:
            thickness = 4
            contour_idx = -1
            image = cv2.drawContours(image, cv_contours, contour_idx, rgba,
                                     thickness, line_type)
        # image = kwimage.ensure_float01(image)[..., 0:3]

        # print('--- D')
        # print('image.dtype = {!r}'.format(image.dtype))
        # print('image.max() = {!r}'.format(image.max()))

        image = dtype_fixer(image, copy=False)
        return image
Esempio n. 4
0
def draw_clf_on_image(im, classes, tcx=None, probs=None, pcx=None, border=1):
    """
    Draws classification label on an image.

    Works best with image chips sized between 200x200 and 500x500

    Args:
        im (ndarray): the image
        classes (Sequence | CategoryTree): list of class names
        tcx (int, default=None): true class index if known
        probs (ndarray): predicted class probs for each class
        pcx (int, default=None): predicted class index.
            (if None but probs is specified uses argmax of probs)

    Example:
        >>> # xdoctest: +REQUIRES(module:torch)
        >>> import torch
        >>> import kwarray
        >>> import kwimage
        >>> rng = kwarray.ensure_rng(0)
        >>> im = (rng.rand(300, 300) * 255).astype(np.uint8)
        >>> classes = ['cls_a', 'cls_b', 'cls_c']
        >>> tcx = 1
        >>> probs = rng.rand(len(classes))
        >>> probs[tcx] = 0
        >>> probs = torch.FloatTensor(probs).softmax(dim=0).numpy()
        >>> im1_ = kwimage.draw_clf_on_image(im, classes, tcx, probs)
        >>> probs[tcx] = .9
        >>> probs = torch.FloatTensor(probs).softmax(dim=0).numpy()
        >>> im2_ = kwimage.draw_clf_on_image(im, classes, tcx, probs)
        >>> # xdoctest: +REQUIRES(--show)
        >>> import kwplot
        >>> kwplot.autompl()
        >>> kwplot.imshow(im1_, colorspace='rgb', pnum=(1, 2, 1), fnum=1, doclf=True)
        >>> kwplot.imshow(im2_, colorspace='rgb', pnum=(1, 2, 2), fnum=1)
        >>> kwplot.show_if_requested()
    """
    import kwimage
    im_ = kwimage.atleast_3channels(im)
    w, h = im.shape[0:2][::-1]

    if pcx is None and probs is not None:
        import kwarray
        probs = kwarray.ArrayAPI.numpy(probs)
        pcx = probs.argmax()

    if probs is not None:
        pred_score = None if pcx is None else probs[pcx]
        true_score = None if tcx is None else probs[tcx]

    org1 = np.array((2, h - 5))
    org2 = np.array((2, 5))

    true_label = None
    if tcx is not None:
        true_name = classes[tcx]
        if pcx == tcx:
            true_label = 't:{tcx}:{true_name}'.format(**locals())
        elif probs is None:
            true_label = 't:{tcx}:\n{true_name}'.format(**locals())
        else:
            true_label = 't:{tcx}@{true_score:.2f}:\n{true_name}'.format(
                **locals())

    pred_label = None
    if pcx is not None:
        pred_name = classes[pcx]
        if probs is None:
            pred_label = 'p:{pcx}:\n{pred_name}'.format(**locals())
        else:
            pred_label = 'p:{pcx}@{pred_score:.2f}:\n{pred_name}'.format(
                **locals())

    fontkw = {'fontScale': 1.0, 'thickness': 2}
    color = 'dodgerblue' if pcx == tcx else 'orangered'

    # im_ = draw_text_on_image(im_, pred_label, org=org1 - 2,
    #                          color='white', valign='bottom', **fontkw)
    # im_ = draw_text_on_image(im_, true_label, org=org2 - 2,
    #                          color='white', valign='top', **fontkw)

    if pred_label is not None:
        im_ = draw_text_on_image(im_,
                                 pred_label,
                                 org=org1,
                                 color=color,
                                 border=border,
                                 valign='bottom',
                                 **fontkw)
    if true_label is not None:
        im_ = draw_text_on_image(im_,
                                 true_label,
                                 org=org2,
                                 color='lawngreen',
                                 valign='top',
                                 border=border,
                                 **fontkw)
    return im_
Esempio n. 5
0
    def draw_on(self, image, color='white', radius=None, copy=False):
        """
        CommandLine:
            xdoctest -m ~/code/kwimage/kwimage/structs/points.py Points.draw_on --show

        Example:
            >>> # xdoc: +REQUIRES(module:kwplot)
            >>> from kwimage.structs.points import *  # NOQA
            >>> s = 128
            >>> image = np.zeros((s, s))
            >>> self = Points.random(10).scale(s)
            >>> image = self.draw_on(image)
            >>> # xdoc: +REQUIRES(--show)
            >>> import kwplot
            >>> kwplot.figure(fnum=1, doclf=True)
            >>> kwplot.autompl()
            >>> kwplot.imshow(image)
            >>> self.draw(radius=3, alpha=.5)
            >>> kwplot.show_if_requested()

        Example:
            >>> # xdoc: +REQUIRES(module:kwplot)
            >>> from kwimage.structs.points import *  # NOQA
            >>> s = 128
            >>> image = np.zeros((s, s))
            >>> self = Points.random(10).scale(s)
            >>> image = self.draw_on(image, radius=3, color='distinct')
            >>> # xdoc: +REQUIRES(--show)
            >>> import kwplot
            >>> kwplot.figure(fnum=1, doclf=True)
            >>> kwplot.autompl()
            >>> kwplot.imshow(image)
            >>> self.draw(radius=3, alpha=.5, color='classes')
            >>> kwplot.show_if_requested()

        Example:
            >>> import kwimage
            >>> s = 32
            >>> self = kwimage.Points.random(10).scale(s)
            >>> color = 'blue'
            >>> # Test drawong on all channel + dtype combinations
            >>> im3 = np.zeros((s, s, 3), dtype=np.float32)
            >>> im_chans = {
            >>>     'im3': im3,
            >>>     'im1': kwimage.convert_colorspace(im3, 'rgb', 'gray'),
            >>>     'im4': kwimage.convert_colorspace(im3, 'rgb', 'rgba'),
            >>> }
            >>> inputs = {}
            >>> for k, im in im_chans.items():
            >>>     inputs[k + '_01'] = (kwimage.ensure_float01(im.copy()), {'radius': None})
            >>>     inputs[k + '_255'] = (kwimage.ensure_uint255(im.copy()), {'radius': None})
            >>> outputs = {}
            >>> for k, v in inputs.items():
            >>>     im, kw = v
            >>>     outputs[k] = self.draw_on(im, color=color, **kw)
            >>> # xdoc: +REQUIRES(--show)
            >>> import kwplot
            >>> kwplot.figure(fnum=2, doclf=True)
            >>> kwplot.autompl()
            >>> pnum_ = kwplot.PlotNums(nCols=2, nRows=len(inputs))
            >>> for k in inputs.keys():
            >>>     kwplot.imshow(inputs[k][0], fnum=2, pnum=pnum_(), title=k)
            >>>     kwplot.imshow(outputs[k], fnum=2, pnum=pnum_(), title=k)
            >>> kwplot.show_if_requested()
        """
        import kwimage

        dtype_fixer = _generic._consistent_dtype_fixer(image)

        if radius is None:
            if color == 'distinct':
                raise NotImplementedError
            image = kwimage.atleast_3channels(image)
            image = kwimage.ensure_float01(image, copy=copy)
            # value = kwimage.Color(color).as01()
            value = kwimage.Color(color)._forimage(image)
            image = self.data['xy'].fill(
                image, value, coord_axes=[1, 0], interp='bilinear')
        else:
            import cv2
            image = kwimage.atleast_3channels(image, copy=copy)
            # note: ellipse has a different return type (UMat) and does not
            # work inplace if the input is not contiguous.
            image = np.ascontiguousarray(image)

            xy_pts = self.data['xy'].data.reshape(-1, 2)

            if color == 'distinct':
                colors = kwimage.Color.distinct(len(xy_pts))
            elif color == 'classes':
                # TODO: read colors from categories if they exist
                class_idxs = self.data['class_idxs']
                _keys, _vals = kwarray.group_indices(class_idxs)
                cls_colors = kwimage.Color.distinct(len(self.meta['classes']))
                colors = list(ub.take(cls_colors, class_idxs))
                colors = [kwimage.Color(c)._forimage(image) for c in colors]
                # if image.dtype.kind == 'f':
                #     colors = [kwimage.Color(c).as01() for c in colors]
                # else:
                #     colors = [kwimage.Color(c).as255() for c in colors]
            else:
                value = kwimage.Color(color)._forimage(image)
                colors = [value] * len(xy_pts)
                # image = kwimage.ensure_float01(image)

            for xy, color_ in zip(xy_pts, colors):
                # center = tuple(map(int, xy.tolist()))
                center = tuple(xy.tolist())
                axes = (radius / 2, radius / 2)
                center = tuple(map(int, center))
                axes = tuple(map(int, axes))
                # print('center = {!r}'.format(center))
                # print('axes = {!r}'.format(axes))

                cv2.ellipse(image, center, axes, angle=0.0, startAngle=0.0,
                            endAngle=360.0, color=color_, thickness=-1)

        image = dtype_fixer(image, copy=False)
        return image