Ejemplo n.º 1
0
    def finalize(self, **kwargs):
        import kwimage
        from ndsampler.utils import util_gdal
        final = self.cache.get('final', None)
        if final is None:
            if util_gdal.have_gdal():
                final = util_gdal.LazyGDalFrameFile(self.fpath)
            else:
                # TODO: delay even further with gdal
                final = kwimage.imread(self.fpath)
                final = kwarray.atleast_nd(final, 3)
            dsize = self.meta.get('dsize', None)
            if dsize is not None:
                final = np.asarray(final)
                final = kwimage.imresize(final, dsize=dsize)
            self.cache['final'] = final

        as_xarray = kwargs.get('as_xarray', False)
        if as_xarray:
            # FIXME: might not work with
            import xarray as xr
            channels = self.channels
            coords = {}
            if channels is not None:
                coords['c'] = channels.code_list()
            final = xr.DataArray(final, dims=('y', 'x', 'c'), coords=coords)

        return final
Ejemplo n.º 2
0
def main():
    image_fpath = 'path/to/image.jpg'
    detector_fpath = 'path/to/detector.zip'

    # Determine the database annotation ids.
    dset = kwcoco.CocoDataset.coerce('path/to/kwcoco-dataset/data.kwcoco.json')
    aids: list[int] = list(dset.annots())

    detector = whodis.Detector.load(detector_fpath)

    imdata: np.ndarray = kwimage.imread(image_fpath)
    detections = detector.detect(imdata)

    database = whodis.ReidDataset.from_kwcoco(dset, aids)
    matches = database.query(detections)

    # Do filtering based on some criterion
    decisions = matches.filter(config={
        'method': 'name-score',
        'threshold': 0.3
    })

    # not sure of the details here
    # will need to export edge information, and update the state of whatever
    # the managing datastore is.
    decisions.export()
Ejemplo n.º 3
0
def bench_imread():
    import ubelt as ub
    # fpath = ub.grabdata('http://www.topcoder.com/contest/problem/UrbanMapper3D/JAX_Tile_043_DTM.tif')

    import kwimage
    fpath = kwimage.grab_test_image_fpath('airport')

    # A color-table geotiff
    # https://download.osgeo.org/geotiff/samples/
    # fpath = ub.grabdata('https://download.osgeo.org/geotiff/samples/usgs/c41078a1.tif')

    ti = ub.Timerit(100, bestof=5, verbose=2)

    results = {}

    fpath = '/home/joncrall/data/sample_ptif.ptif'
    fpath = '/home/joncrall/data/sample_cog.cog.tif'

    for timer in ti.reset('gdal-v1'):
        with timer:
            image = _read_gdal_v1(fpath)
    results[ti.label] = image.sum()

    for timer in ti.reset('gdal-v2'):
        with timer:
            image = _read_gdal_v2(fpath)
    results[ti.label] = image.sum()

    for timer in ti.reset('rasterio'):
        with timer:
            image = _read_rasterio(fpath)
    results[ti.label] = image.sum()

    import skimage.io
    """
    pip install tifffile
    pip install imagecodecs

    """
    for timer in ti.reset('skimage'):
        with timer:
            image = skimage.io.imread(fpath)
    results[ti.label] = image.sum()

    import kwimage
    for timer in ti.reset('kwimage'):
        with timer:
            image = kwimage.imread(fpath)
    results[ti.label] = image.sum()

    import cv2
    for timer in ti.reset('cv2'):
        with timer:
            image = cv2.imread(fpath)
    results[ti.label] = image.sum()

    for timer in ti.reset('pil'):
        with timer:
            image = _read_pil(fpath)
    results[ti.label] = image.sum()
Ejemplo n.º 4
0
 def _rectify_image(self, path_or_image):
     if isinstance(path_or_image, six.string_types):
         self.info('Reading {!r}'.format(path_or_image))
         full_rgb = kwimage.imread(path_or_image, space='rgb')
     else:
         full_rgb = path_or_image
     return full_rgb
Ejemplo n.º 5
0
    def validate(self, orig_fpath=None, orig_data=None):
        """
        Check for any corruption issues

        Args:
            orig_fpath (str): if specified and the data seems to be all zero,
                we check if the pixels are close to the pixels in this other
                image. If not the warning becomes an error.

            orig_data (ndarray): alternative to orig_fpath if the data is in
                memory.

        Returns:
            Dict: info about errors, warnings, and details
        """
        info = {
            'errors': [],
            'warnings': [],
            'details': {},
            'fpath': self.cog_fpath,
            'orig_fpath': orig_fpath,
        }
        try:
            from ndsampler.utils.validate_cog import validate as _validate_cog
            warnings, errors, details = _validate_cog(self.cog_fpath)

        except Exception as ex:
            info['errors'].append(repr(ex))
        else:
            info['errors'].extend(errors)
            info['warnings'].extend(warnings)
            info['details'] = details
        try:
            has_data = validate_nonzero_data(self)
            if not has_data:
                if orig_data is None and orig_fpath is not None:
                    import kwimage
                    orig_data = kwimage.imread(orig_fpath)
                if orig_data is None:
                    # All we can do is warn here
                    info['warnings'].append('image appears to be all black')
                else:
                    orig_sum = orig_data.sum()
                    if orig_sum > 0:
                        info['errors'].append(
                            'image is all zeros, but orig_sum = {!r}'.format(
                                orig_sum))
        except Exception as ex:
            info['errors'].append(repr(ex))

        if info['errors']:
            info['status'] = 'fail'
        else:
            info['status'] = 'pass'
        return info
Ejemplo n.º 6
0
def _npy_cache_write(gpath, cache_gpath, config=None):
    # Load all the image data and dump it to npy format
    import kwimage
    raw_data = kwimage.imread(gpath)

    # Even with the file-lock and atomic save there is still a race
    # condition somewhere. Not sure what it is.
    # _semi_atomic_numpy_save(cache_gpath, raw_data)

    # with atomicwrites.atomic_write(cache_gpath, mode='wb', overwrite=True) as file:
    with open(cache_gpath, mode='wb') as file:
        np.save(file, raw_data)
Ejemplo n.º 7
0
    def camvid_load_truth(img):
        # TODO: better way to load per-pixel truth with sampler
        mask_fpath = join(coco_dset.img_root, img['segmentation'])
        rgb_mask = kwimage.imread(mask_fpath, space='rgb')
        r, g, b  = rgb_mask.T.astype(np.int64)
        cid_mask = np.ascontiguousarray(rgb_to_cid(r, g, b).T)

        ignore_idx = 0
        cidx_mask = np.full_like(cid_mask, fill_value=ignore_idx)
        for cx, cid in enumerate(cx_to_cid):
            locs = (cid_mask == cid)
            cidx_mask[locs] = cx
        return cidx_mask
Ejemplo n.º 8
0
def resize_all():
    in_dpath = '/media/joncrall/raid/Pictures/Bezoar'
    out_dpath = '/media/joncrall/raid/Pictures/BezoarSmall'

    IMAGE_EXTENSIONS = (
        '.bmp',
        '.pgm',
        '.jpg',
        '.jpeg',
        '.png',
        '.tif',
        '.tiff',
        '.ntf',
        '.nitf',
        '.ptif',
        '.cog.tiff',
        '.cog.tif',
        '.r0',
        '.r1',
        '.r2',
        '.r3',
        '.r4',
        '.r5',
        '.nsf',
    )
    import os
    from os.path import join, relpath
    import kwimage
    recursive = False

    max_dim = 2000

    tasks = []
    for root, ds, fs in os.walk(in_dpath):
        if not recursive:
            ds[:] = []

        valid_fs = [f for f in fs if f.lower().endswith(IMAGE_EXTENSIONS)]
        valid_fpaths = [join(root, fname) for fname in valid_fs]

        for in_fpath in valid_fpaths:
            out_fpath = join(out_dpath, relpath(in_fpath, in_dpath))
            tasks.append((in_fpath, out_fpath))

    import ubelt as ub
    for in_fpath, out_fpath in ub.ProgIter(tasks):
        in_imdata = kwimage.imread(in_fpath)
        out_imdata = kwimage.imresize(in_imdata, max_dim=max_dim)
        kwimage.imwrite(out_fpath, out_imdata)
Ejemplo n.º 9
0
    def _load_native_channel(self, chan_name, cache=True):
        """
        Load a specific auxiliary channel, optionally caching it
        """
        chan = self.pathinfo['channels'][chan_name]

        if not cache:
            import kwimage
            gpath = chan['path']
            data = kwimage.imread(gpath)
        else:
            cache_key = chan_name
            _channel_memcache = self._channel_memcache
            if _channel_memcache is not None and cache_key in _channel_memcache:
                return _channel_memcache[cache_key]

            gpath = chan['path']
            cache_type = chan['cache_type']
            if cache_type is None:
                import kwimage
                data = kwimage.imread(gpath)
            elif cache_type == 'cog':
                cache_gpath = chan['cache']
                config = self.cache_backend['config']
                hack_use_cli = self.cache_backend['_hack_use_cli']
                data = _ensure_image_cog(gpath, cache_gpath, config,
                                         hack_use_cli)
            elif cache_type == 'npy':
                cache_gpath = chan['cache']
                data = _ensure_image_npy(gpath, cache_gpath)
            else:
                raise KeyError(cache_type)

            if _channel_memcache is not None:
                _channel_memcache[cache_key] = data
        return data
Ejemplo n.º 10
0
def _doctest_check_cog(data, fpath):
    from ndsampler.utils.validate_cog import validate as _validate_cog
    import kwimage
    print('---- CHECK COG ---')
    print('fpath = {!r}'.format(fpath))
    disk_shape = kwimage.imread(fpath).shape
    errors = _validate_cog(fpath)
    warnings, errors, details = _validate_cog(fpath)
    print('disk_shape = {!r}'.format(disk_shape))
    print('details = ' + ub.repr2(details, nl=2))
    print('warnings = ' + ub.repr2(warnings, nl=1))
    print('errors = ' + ub.repr2(errors, nl=1))
    passed = not errors

    assert data.shape == disk_shape
    return passed
Ejemplo n.º 11
0
def draw_true_and_pred_boxes(true_fpath, pred_fpath, gid, viz_fpath):
    """
    How do you generally visualize gt and predicted bounding boxes together?

    Example:
        >>> import kwcoco
        >>> import ubelt as ub
        >>> from os.path import join
        >>> from kwcoco.demo.perterb import perterb_coco
        >>> # Create a working directory
        >>> dpath = ub.ensure_app_cache_dir('kwcoco/examples/draw_true_and_pred_boxes')
        >>> # Lets setup some dummy true data
        >>> true_dset = kwcoco.CocoDataset.demo('shapes2')
        >>> true_dset.fpath = join(dpath, 'true_dset.kwcoco.json')
        >>> true_dset.dump(true_dset.fpath, newlines=True)
        >>> # Lets setup some dummy predicted data
        >>> pred_dset = perterb_coco(true_dset, box_noise=100, rng=421)
        >>> pred_dset.fpath = join(dpath, 'pred_dset.kwcoco.json')
        >>> pred_dset.dump(pred_dset.fpath, newlines=True)
        >>> #
        >>> # We now have our true and predicted data, lets visualize
        >>> true_fpath = true_dset.fpath
        >>> pred_fpath = pred_dset.fpath
        >>> print('dpath = {!r}'.format(dpath))
        >>> print('true_fpath = {!r}'.format(true_fpath))
        >>> print('pred_fpath = {!r}'.format(pred_fpath))
        >>> # Lets choose an image id to visualize and a path to write to
        >>> gid = 1
        >>> viz_fpath = join(dpath, 'viz_{}.jpg'.format(gid))
        >>> # The answer to the question is in the logic of this function
        >>> draw_true_and_pred_boxes(true_fpath, pred_fpath, gid, viz_fpath)
    """
    import kwimage
    import kwcoco
    true_dset = kwcoco.CocoDataset(true_fpath)
    pred_dset = kwcoco.CocoDataset(pred_fpath)

    if __debug__:
        # I hope your image ids are aligned between datasets
        true_img = true_dset.imgs[gid]
        pred_img = pred_dset.imgs[gid]
        assert true_img['file_name'] == pred_img['file_name']

    # Get the true/pred annotation dictionaries from the chosen image
    true_aids = true_dset.index.gid_to_aids[gid]
    pred_aids = pred_dset.index.gid_to_aids[gid]
    true_anns = [true_dset.index.anns[aid] for aid in true_aids]
    pred_anns = [pred_dset.index.anns[aid] for aid in pred_aids]

    # Create Detections from the coco annotation dictionaries
    true_dets = kwimage.Detections.from_coco_annots(true_anns, dset=true_dset)
    pred_dets = kwimage.Detections.from_coco_annots(pred_anns, dset=pred_dset)

    print('true_dets.boxes = {!r}'.format(true_dets.boxes))
    print('pred_dets.boxes = {!r}'.format(pred_dets.boxes))

    # Load the image
    fpath = true_dset.get_image_fpath(gid)
    canvas = kwimage.imread(fpath)

    # Use kwimage.Detections draw_on method to modify the image
    canvas = true_dets.draw_on(canvas, color='green')
    canvas = pred_dets.draw_on(canvas, color='blue')

    kwimage.imwrite(viz_fpath, canvas)
Ejemplo n.º 12
0
    def predict(self, path_or_image):
        self._preload()
        if isinstance(path_or_image, six.string_types):
            print('Reading {!r}'.format(path_or_image))
            full_rgb = kwimage.imread(path_or_image, space='rgb')
        else:
            full_rgb = path_or_image

        # Note, this doesn't handle the case where the image is smaller than
        # the window
        input_dims = full_rgb.shape[0:2]

        try:
            classes = self.model.module.classes
        except AttributeError:
            classes = self.model.classes

        stitchers = {
            'class_energy': nh.util.Stitcher((len(classes),) + tuple(input_dims))
        }
        slider = nh.util.SlidingWindow(input_dims, self.config['window_dims'],
                                       overlap=0, keepbound=True,
                                       allow_overshoot=True)

        slider_dset = PredSlidingWindowDataset(slider, full_rgb)
        slider_loader = torch.utils.data.DataLoader(slider_dset,
                                                    batch_size=self.config['batch_size'],
                                                    num_workers=self.config['workers'],
                                                    shuffle=False,
                                                    pin_memory=True)

        prog = ub.ProgIter(slider_loader, desc='sliding window')

        with torch.no_grad():
            for raw_batch in prog:
                im = self.xpu.move(raw_batch['im'])
                outputs = self.model(im)

                class_energy = outputs['class_energy'].data.cpu().numpy()

                batch_sl_st_dims = raw_batch['sl_st_dims'].data.cpu().long().numpy().tolist()
                batch_sl_dims = [tuple(slice(s, t) for s, t in item)
                                 for item in batch_sl_st_dims]

                for sl_dims, energy in zip(batch_sl_dims, class_energy):
                    slices = (slice(None),) + sl_dims
                    stitchers['class_energy'].add(slices, energy)

            full_class_energy = stitchers['class_energy'].finalize()
            full_class_probs = torch.FloatTensor(full_class_energy).softmax(dim=0)
            full_class_probs = full_class_probs.numpy()
            full_class_idx = full_class_probs.argmax(axis=0)

        pred_heatmap = kwimage.Heatmap(
            class_probs=full_class_probs,
            class_idx=full_class_idx,
            classes=classes,
            datakeys=['class_idx'],
        )

        return pred_heatmap
Ejemplo n.º 13
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.º 14
0
def multiple_items_from_a_dictionary():
    """
    Spotlight:
        ubelt.take

    Modivation:
        Working with Lists of Dictionaries

    Requires:
        kwimage
    """
    ...
    """
    When working with data, a common pattern is to iterate through it, and
    gather information about the work to be done, so a you can make a final
    structured pass through the data.

    In python we might do this by initializing an empty list and appending
    **dictionary of information**, to the list. (or you might yield
    dictionaries of information from a generator instead, either way you have a
    flat list).

    Some people might use lists of tuples instead of Lists of dictionaries, but
    using dictionaries makes it easy to add new information later (and it works
    very will with pandas).
    """
    import ubelt as ub
    import kwimage
    kwimage_test_image_names = [
        'airport', 'amazon', 'astro', 'carl', 'lowcontrast'
    ]
    rows = []
    for test_image in kwimage_test_image_names:
        fpath = ub.Path(kwimage.grab_test_image_fpath(test_image))
        imdata = kwimage.imread(fpath)
        row = {
            'mean': imdata.mean(),
            'std': imdata.std(),
            'sum': imdata.sum(),
            'max': imdata.max(),
            'min': imdata.min(),
        }
        rows.append(row)
    """
    For each row, you might want to grab multiple specific items from it.

    But having a separate assignment on each row wastes a lot of vertical
    space.
    """

    for row in rows:
        mean = row['mean']
        std = row['std']
        sum = row['sum']
        min = row['min']
        max = row['max']
    """
    You might put them one line explicitly, but that wastes a lot of horizontal
    space
    """
    for row in rows:
        mean, std, sum, min, max = row['mean'], row['std'], row['sum'], row[
            'min'], row['max']
    """
    What if we try to be clever? We can use a list comprehension
    """
    for row in rows:
        mean, std, sum, min, max = [
            row[k] for k in ['mean', 'std', 'sum', 'min', 'max']
        ]
    """
    That's not too bad, but we can do better
    """
    for row in rows:
        mean, std, sum, min, max = ub.take(
            row, ['mean', 'std', 'sum', 'min', 'max'])
Ejemplo n.º 15
0
def test_variable_backend():
    """
    CommandLine:
        xdoctest -m $HOME/code/ndsampler/tests/tests_frame_backends.py test_variable_backend
        --debug-validate-cog --debug-load-cog
    """
    try:
        import gdal  # NOQA
    except ImportError:
        import pytest
        pytest.skip('cog requires gdal')
    import ndsampler
    import kwcoco
    import ubelt as ub
    dpath = ub.ensure_app_cache_dir('ndsampler/tests/test_variable_backend')
    ub.delete(dpath)
    ub.ensuredir(dpath)

    fnames = [
        'test_rgb_255.jpg',
        'test_gray_255.jpg',
        'test_rgb_255.png',
        'test_rgba_255.png',
        'test_gray_255.png',
        'test_rgb_01.tif',
        'test_rgb_255.tif',
        'test_rgba_01.tif',
        'test_rgba_255.tif',
        'test_gray_01.tif',
        'test_gray_255.tif',
    ]
    import kwarray
    import kwimage
    fpaths = []
    rng = kwarray.ensure_rng(0)

    h, w = 1200, 1055

    for fname in ub.ProgIter(fnames, desc='create test data'):
        if 'rgb_' in fname:
            data = rng.rand(h, w, 3)
        elif 'rgba_' in fname:
            data = rng.rand(h, w, 4)
        elif 'gray_' in fname:
            data = rng.rand(h, w, 1)

        if '01' in fname:
            pass
        elif '255' in fname:
            data = (data * 255).astype(np.uint8)

        fpath = join(dpath, fname)
        fpaths.append(fpath)
        kwimage.imwrite(fpath, data)

    for fpath in fpaths:
        data = kwimage.imread(fpath)
        print(
            ub.repr2(
                {
                    'fname': basename(fpath),
                    'data.shape': data.shape,
                    'data.dtype': data.dtype,
                },
                nl=0))

    dset = kwcoco.CocoDataset.from_image_paths(fpaths)
    sampler = ndsampler.CocoSampler(dset, backend='cog', workdir=dpath)
    frames = sampler.frames
    # frames.prepare()

    if 1:
        for gid in frames.image_ids:
            print('======== < START IMAGE ID > ===============')
            gpath, cache_gpath = frames._gnames(gid)
            print('gpath = {!r}'.format(gpath))
            print('cache_gpath = {!r}'.format(cache_gpath))

            image = frames.load_image(gid)
            print('image = {!r}'.format(image))
            print('image.shape = {!r}'.format(image.shape))
            print('image.dtype = {!r}'.format(image.dtype))

            subdata = image[0:8, 0:8]
            print('subdata.dtype = {!r}'.format(subdata.dtype))
            print('subdata.shape = {!r}'.format(subdata.shape))
            # info = ub.cmd('gdalinfo ' + cache_gpath, verbose=0)
            # print('GDAL INFO:')
            # print(ub.indent(info['out']))
            # assert info['ret'] == 0

            # dataset = gdal.OpenEx(cache_gpath)
            dataset = gdal.Open(cache_gpath, gdal.GA_ReadOnly)
            md = dataset.GetMetadata('IMAGE_STRUCTURE')
            print('md = {!r}'.format(md))
            # Use dict.get method in case the metadata dict does not have a 'COMPRESSION' key
            compression = md.get('COMPRESSION', 'RAW')
            print('compression = {!r}'.format(compression))

            print('======== < END IMAGE ID > ===============')
Ejemplo n.º 16
0
def detect_cli(config={}):
    """
    CommandLine:
        python -m bioharn.detect_predict --help

    CommandLine:
        python -m bioharn.detect_predict \
            --dataset=~/data/noaa/Habcam_2015_g027250_a00102917_c0001_v2_test.mscoco.json \
            --deployed=/home/joncrall/work/bioharn/fit/runs/bioharn-det-v11-test-cascade/myovdqvi/deploy_MM_CascadeRCNN_myovdqvi_035_MVKVVR.zip \
            --out_dpath=~/work/bioharn/habcam_test_out \
            --draw=100 \
            --input_dims=512,512 \
            --xpu=0 --batch_size=1

    Ignore:
        >>> config = {}
        >>> config['dataset'] = '~/data/noaa/Habcam_2015_g027250_a00102917_c0001_v2_vali.mscoco.json'
        >>> config['deployed'] = '/home/joncrall/work/bioharn/fit/runs/bioharn-det-v11-test-cascade/myovdqvi/deploy_MM_CascadeRCNN_myovdqvi_035_MVKVVR.zip'
        >>> config['out_dpath'] = 'out'
    """
    import kwarray
    import ndsampler
    from os.path import basename, join, exists, isfile, isdir  # NOQA

    config = DetectPredictCLIConfig(config, cmdline=True)
    print('config = {}'.format(ub.repr2(config.asdict())))

    out_dpath = ub.expandpath(config.get('out_dpath'))

    import six
    if isinstance(config['dataset'], six.string_types):
        if config['dataset'].endswith('.json'):
            dataset_fpath = ub.expandpath(config['dataset'])
            coco_dset = ndsampler.CocoDataset(dataset_fpath)
            # Running prediction is much faster if you can build a sampler.
            sampler_backend = {
                'type': 'cog',
                'config': {
                    'compress': 'JPEG',
                },
                '_hack_old_names': False,  # flip to true to use legacy caches
            }
            sampler_backend = None
            print('coco hashid = {}'.format(coco_dset._build_hashid()))
        else:
            sampler_backend = None
            if exists(config['dataset']) and isfile(config['dataset']):
                # Single image case
                image_fpath = ub.expandpath(config['dataset'])
                coco_dset = ndsampler.CocoDataset()
                coco_dset.add_image(image_fpath)
    elif isinstance(config['dataset'], list):
        # Multiple image case
        gpaths = config['dataset']
        gpaths = [ub.expandpath(g) for g in gpaths]
        coco_dset = ndsampler.CocoDataset()
        for gpath in gpaths:
            coco_dset.add_image(gpath)
    else:
        raise TypeError(config['dataset'])

    draw = config.get('draw')
    workdir = ub.expandpath(config.get('workdir'))

    det_outdir = ub.ensuredir((out_dpath, 'pred'))

    pred_config = ub.dict_subset(config, DetectPredictConfig.default)

    print('Create sampler')
    sampler = ndsampler.CocoSampler(coco_dset, workdir=workdir,
                                    backend=sampler_backend)
    print('prepare frames')
    sampler.frames.prepare(workers=config['workers'])

    print('Create predictor')
    predictor = DetectPredictor(pred_config)
    print('Ensure model')
    predictor._ensure_model()

    pred_dataset = coco_dset.dataset.copy()
    pred_dataset['annotations'] = []
    pred_dset = ndsampler.CocoDataset(pred_dataset)

    # self = predictor
    predictor.config['verbose'] = 1
    pred_gen = predictor.predict_sampler(sampler)
    buffered_gen = AsyncBufferedGenerator(pred_gen, size=coco_dset.n_images)

    gid_to_pred = {}
    prog = ub.ProgIter(buffered_gen, total=coco_dset.n_images,
                       desc='buffered detect')
    for img_idx, (gid, dets) in enumerate(prog):
        gid_to_pred[gid] = dets

        for ann in dets.to_coco():
            ann['image_id'] = gid
            try:
                catname = ann['category_name']
                ann['category_id'] = pred_dset._resolve_to_cid(catname)
            except KeyError:
                if 'category_id' not in ann:
                    cid = pred_dset.add_category(catname)
                    ann['category_id'] = cid
            pred_dset.add_annotation(**ann)

        single_img_coco = pred_dset.subset([gid])
        single_pred_dpath = ub.ensuredir((det_outdir, 'single_image'))
        single_pred_fpath = join(single_pred_dpath, 'detections_gid_{:08d}.mscoco.json'.format(gid))
        single_img_coco.dump(single_pred_fpath, newlines=True)

        if draw is True or (draw and img_idx < draw):
            draw_outdir = ub.ensuredir((out_dpath, 'draw'))
            img_fpath = coco_dset.load_image_fpath(gid)
            gname = basename(img_fpath)
            viz_fname = ub.augpath(gname, prefix='detect_', ext='.jpg')
            viz_fpath = join(draw_outdir, viz_fname)

            image = kwimage.imread(img_fpath)

            flags = dets.scores > .2
            flags[kwarray.argmaxima(dets.scores, num=10)] = True
            top_dets = dets.compress(flags)
            toshow = top_dets.draw_on(image, alpha=None)
            # kwplot.imshow(toshow)
            kwimage.imwrite(viz_fpath, toshow, space='rgb')

    pred_fpath = join(det_outdir, 'detections.mscoco.json')
    print('Dump detections to pred_fpath = {!r}'.format(pred_fpath))
    pred_dset.dump(pred_fpath, newlines=True)
Ejemplo n.º 17
0
    def main(cls, cmdline=True, **kw):
        """
        CommandLine:
            xdoctest -m make_coco_from_masks.py MakeCocoFromMasksCLI.main

        Example:
            >>> import ubelt as ub
            >>> cls = MakeCocoFromMasksCLI
            >>> cmdline = False
            >>> dpath = _make_intmask_demodata()
            >>> kw = {'src': join(dpath, '*.png'), 'dst': 'masks.mscoco.json'}
            >>> fpath = cls.main(cmdline, **kw)
            >>> # Check validity
            >>> import kwcoco
            >>> dset = kwcoco.CocoDataset(fpath)
            >>> dset._check_integrity()
            >>> # Ensure we can convert to kwimage and access segmentations
            >>> dset.annots().detections.data['segmentations'][0].data
        """
        import kwcoco
        config = cls.CLIConfig(kw, cmdline=cmdline)
        print('config = {}'.format(ub.repr2(dict(config), nl=2)))
        serialization_method = config['serialization']

        # Initialize an empty COCO dataset
        coco_dset = kwcoco.CocoDataset()

        # Path to each mask object
        mask_fpaths = config['src']
        for mask_fpath in mask_fpaths:
            # I assume each mask corresponds to a single image, but I dont know
            # what those images should be at the moment. TODO: if this is going
            # to be a real script, then we should find a nice way of specifying
            # the correspondences between masks and the images to which they
            # belong. For now, I'm going to use the mask itself as a dummy
            # value.

            img_fpath = mask_fpath
            image_id = coco_dset.add_image(file_name=img_fpath)

            # Parse the mask file, and add each object as a new annotation
            multi_mask = kwimage.imread(mask_fpath)
            # I recall there is a better opencv of splitting these sort of
            # masks up into binary masks, maybe it was a connected-component
            # function? I guess it depends if you want disconnected objects
            # represented as separte annotations or not.  I'm just going to do
            # the naive thing for now.
            obj_idxs = np.setdiff1d(np.unique(multi_mask), [0])
            for obj_idx in obj_idxs:
                bin_data = (multi_mask == obj_idx).astype(np.uint8)

                # Create a kwimage object which has nice `to_coco` methods
                bin_mask = kwimage.Mask(bin_data, format='c_mask')

                # We can either save in our coco file as a raster RLE style
                # mask, or we can use a vector polygon style mask. Either of
                # the resulting coco_sseg objects is a valid value for an
                # annotation's "segmentation" field.
                if serialization_method == 'raster':
                    sseg = bin_mask
                    coco_sseg = sseg.to_coco(style='new')
                elif serialization_method == 'vector':
                    bin_poly = bin_mask.to_multi_polygon()
                    sseg = bin_poly
                    coco_sseg = sseg.to_coco(style='new')

                # Now we add this segmentation to the coco dataset as a new
                # annotation. The annotation needs to know which image it
                # belongs to, and ideally it has a category and a bounding box
                # as well.

                # We can make up a dummy category (note that ensure_category
                # will not fail if there is a duplicate entry but add_category
                # will)
                category_id = coco_dset.ensure_category(
                    'class_{}'.format(obj_idx))

                # We can use the kwimage sseg object to get the bounding box
                # FIXME: apparently the MultiPolygon object doesnt implement
                # `to_boxes`, at the moment, so force an inefficient conversion
                # back to a mask as a hack and use its to_boxes method.
                # Technically, the bounding box should not be required, but its
                # a good idea to always include it.
                bbox = list(
                    sseg.to_mask(
                        dims=multi_mask.shape).to_boxes().to_coco())[0]

                METHOD1 = False
                if METHOD1:
                    # We could just add it diretly like this
                    # FIXME: it should be ok to add an annotation without a
                    # category, but it seems like a recent change in kwcoco has
                    # broken that. That will be fixed in the future.
                    annot_id = coco_dset.add_annotation(
                        image_id=image_id,
                        category_id=category_id,
                        bbox=bbox,
                        segmentation=coco_sseg)
                else:
                    # But lets do it as if we were adding a segmentation to an
                    # existing dataset. In this case we access the
                    # CocoDataset's annotation index structure.
                    #
                    # First add the basic annotation
                    annot_id = coco_dset.add_annotation(
                        image_id=image_id, category_id=category_id, bbox=bbox)
                    # Then use the annotation id to look up its coco-dictionary
                    # representation and simply add the segmentation field
                    ann = coco_dset.anns[annot_id]
                    ann['segmentation'] = coco_sseg

        # You dont have to set the fpath attr, but I tend to like it
        coco_dset.fpath = config['dst']
        print('Writing to fpath = {}'.format(ub.repr2(coco_dset.fpath, nl=1)))
        coco_dset.dump(coco_dset.fpath, newlines=True)
        return coco_dset.fpath
Ejemplo n.º 18
0
def _cog_cache_write(gpath, cache_gpath, config=None):
    """
    CommandLine:
        xdoctest -m ndsampler.abstract_frames _cog_cache_write

    Example:
        >>> # xdoctest: +REQUIRES(module:osgeo)
        >>> import ndsampler
        >>> from ndsampler.abstract_frames import *
        >>> import kwcoco
        >>> workdir = ub.ensure_app_cache_dir('ndsampler')
        >>> dset = kwcoco.CocoDataset.demo()
        >>> imgs = dset.images()
        >>> id_to_name = imgs.lookup('file_name', keepid=True)
        >>> id_to_path = {gid: join(dset.img_root, name)
        >>>               for gid, name in id_to_name.items()}
        >>> self = SimpleFrames(id_to_path, workdir=workdir)
        >>> image_id = ub.peek(id_to_name)
        >>> #gpath = self._lookup_gpath(image_id)

        #### EXIT
        # >>> hashid = self._lookup_hashid(image_id)
        # >>> cog_gname = '{}_{}.cog.tiff'.format(image_id, hashid)
        # >>> cache_gpath = cog_gpath = join(self.cache_dpath, cog_gname)
        # >>> _cog_cache_write(gpath, cache_gpath, {})
    """
    assert config is not None

    # FIXME: if gdal_translate is not installed (because libgdal exists, but
    # gdal-bin doesn't) then this seems to fail without throwing an error when
    # hack_use_cli=1.
    hack_use_cli = config.pop('hack_use_cli', False)

    if DEBUG_COG_ATOMIC_WRITE:
        import multiprocessing
        from multiprocessing import current_process
        from threading import current_thread
        is_main = (current_thread().name == 'MainThread' and
                   current_process().name == 'MainProcess')
        proc = multiprocessing.current_process()
        def _debug(msg):
            msg_ = '[{}, {}, {}] '.format(ub.timestamp(), proc, proc.pid) + msg + '\n'
            if is_main:
                print(msg_)
            with open(cache_gpath + '.atomic.debug', 'a') as f:
                f.write(msg_)
        _debug('attempts aquire'.format())

    if not hack_use_cli:
        # Load all the image data and dump it to cog format
        import kwimage
        if DEBUG_COG_ATOMIC_WRITE:
            _debug('reading data')
        raw_data = kwimage.imread(gpath)
        # raw_data = kwimage.atleast_3channels(raw_data, copy=False)
    # TODO: THERE HAS TO BE A CORRECT WAY TO DO THIS.
    # However, I'm not sure what it is. I extend my appologies to whoever is
    # maintaining this code. Note: mode MUST be 'w'

    with atomicwrites.atomic_write(cache_gpath + '.atomic', mode='w', overwrite=True) as file:
        if DEBUG_COG_ATOMIC_WRITE:
            _debug('begin')
            _debug('gpath = {}'.format(gpath))
            _debug('cache_gpath = {}'.format(cache_gpath))
        try:
            file.write('begin: {}\n'.format(ub.timestamp()))
            file.write('gpath = {}\n'.format(gpath))
            file.write('cache_gpath = {}\n'.format(cache_gpath))
            if not exists(cache_gpath):
                if not hack_use_cli:
                    util_gdal._imwrite_cloud_optimized_geotiff(
                        cache_gpath, raw_data, **config)
                else:
                    # The CLI is experimental and might make this pipeline
                    # faster by avoiding the initial read.
                    util_gdal._cli_convert_cloud_optimized_geotiff(
                        gpath, cache_gpath, **config)
                if DEBUG_COG_ATOMIC_WRITE:
                    _debug('finished write: {}\n'.format(ub.timestamp()))
            else:
                if DEBUG_COG_ATOMIC_WRITE:
                    _debug('ALREADY EXISTS did not write: {}\n'.format(ub.timestamp()))
            file.write('end: {}\n'.format(ub.timestamp()))
        except Exception as ex:
            file.write('FAILED DUE TO EXCEPTION: {}: {}\n'.format(ex, ub.timestamp()))
            if DEBUG_COG_ATOMIC_WRITE:
                _debug('FAILED DUE TO EXCEPTION: {}'.format(ex))
            raise
        finally:
            if DEBUG_COG_ATOMIC_WRITE:
                _debug('finally')

    if RUN_COG_CORRUPTION_CHECKS:
        # CHECK THAT THE DATA WAS WRITTEN CORRECTLY
        file = util_gdal.LazyGDalFrameFile(cache_gpath)
        is_valid = util_gdal.validate_nonzero_data(file)
        if not is_valid:
            if hack_use_cli:
                import kwimage
                raw_data = kwimage.imread(gpath)
            # The check may fail on zero images, so check that
            orig_sum = raw_data.sum()
            # cache_sum = file[:].sum()
            # if DEBUG:
            #     _debug('is_valid = {}'.format(is_valid))
            #     _debug('cache_sum = {}'.format(cache_sum))
            if orig_sum > 0:
                print('FAILED TO WRITE COG FILE')
                print('orig_sum = {!r}'.format(orig_sum))
                # print(kwimage.imread(cache_gpath).sum())
                if DEBUG_COG_ATOMIC_WRITE:
                    _debug('FAILED TO WRITE COG FILE')
                ub.delete(cache_gpath)
                raise CorruptCOG('FAILED TO WRITE COG FILE CORRECTLY')
Ejemplo n.º 19
0
def check_nitfs():
    nitfs = unsafe_grab_nitfs()

    import xdev
    import netharn as nh

    total = 0
    for fpath in nitfs:
        nbytes = nh.util.get_file_info(fpath)['filesize']
        print('nbytes = {!r}'.format(xdev.byte_str(nbytes)))
        total += nbytes
    print(xdev.byte_str(total))

    failed_fpaths = []
    passed_fpaths = []

    for fpath in nitfs:
        import kwimage
        try:
            kwimage.imread(fpath)
            passed_fpaths.append(fpath)
        except Exception:
            failed_fpaths.append(fpath)

    print('passed = {}'.format(len(passed_fpaths)))
    print('failed = {}'.format(len(failed_fpaths)))

    print('CANT HANDLE')
    for fpath in failed_fpaths:
        name = splitext(basename(fpath))[0]
        desc = NITF_DESC[name]
        print(desc)

    for fpath in failed_fpaths:
        print('\n-----')
        print('fpath = {!r}'.format(fpath))
        try:
            kwimage.imread(fpath)
        except Exception:
            pass
        print('\n-----')

    from ndsampler.abstract_frames import _cog_cache_write
    for gpath in passed_fpaths:
        cache_gpath = ub.augpath(gpath, ext='.test.api.cog')
        ub.delete(cache_gpath)
        # config = {'hack_use_cli': True}
        config = {'hack_use_cli': False, 'compress': 'LZW'}
        _cog_cache_write(gpath, cache_gpath, config=config)

    from ndsampler.abstract_frames import _cog_cache_write
    for gpath in passed_fpaths:
        cache_gpath = ub.augpath(gpath, ext='.test.cli.cog')
        ub.delete(cache_gpath)
        # config = {'hack_use_cli': True}
        config = {'hack_use_cli': True, 'compress': 'LZW'}
        _cog_cache_write(gpath, cache_gpath, config=config)

    from ndsampler.abstract_frames import _cog_cache_write
    for gpath in passed_fpaths:
        cache_gpath = ub.augpath(gpath, ext='.test.cli.cog')
        ub.delete(cache_gpath)
        # config = {'hack_use_cli': True}
        kwimage.imread(gpath)
        config = {'hack_use_cli': True, 'compress': 'JPEG'}
        _cog_cache_write(gpath, cache_gpath, config=config)
Ejemplo n.º 20
0
"""
Requirements:
    pip install kwarray kwimage[headless] kwplot ubelt numpy scipy
"""
import kwarray
import kwimage
import kwplot
import ubelt as ub
import numpy as np
from scipy import integrate

fpath = ub.grabdata('https://i.redd.it/ywip9sbwysy71.jpg')
data = kwimage.imread(fpath)

subdata = data[242:-22, 22:300]

img = subdata

inty = integrate.cumtrapz(img, axis=0)
intx = integrate.cumtrapz(img, axis=1)

dery = np.gradient(img, axis=0)
derx = np.gradient(img, axis=1)

der_canvas = kwarray.normalize(kwimage.stack_images([dery, derx], axis=0))
int_canvas = kwarray.normalize(kwimage.stack_images([inty, intx], axis=0))
der_canvas = kwimage.ensure_uint255(der_canvas)
int_canvas = kwimage.ensure_uint255(int_canvas)

der_canvas = kwimage.draw_header_text(der_canvas, 'derivative', color='white')
int_canvas = kwimage.draw_header_text(int_canvas,
Ejemplo n.º 21
0
def time_ondisk_crop(size=512, dim=3, region='small_random', num=24):
    """
    Ignore:
        >>> from bench_subregion_imread import *  # NOQA
        >>> import xdev
        >>> globals().update(xdev.get_func_kwargs(time_ondisk_crop))
    """
    enabled = {
        'in_memory': False,
        'memmap': True,
        'PIL': False,
        'OpenCV': True,
        'VIPS': True,
        'GDAL': True,
        'HDF5': True,
    }

    print('\n---')

    # DATA = 'custom'
    DATA = 'random'

    if DATA == 'random':
        # data = (np.random.rand(500, 500, 3) * 255).astype(np.uint8)
        print('Generate random data, size={}, dim={}, mode={}'.format(
            size, dim, region))
        x, y = np.meshgrid(np.arange(0, size), np.arange(0, size))
        data = np.ascontiguousarray(
            (np.dstack([x] * dim) % 256).astype(np.uint8))
        data = data.squeeze()
    elif DATA == 'custom':
        print('USE CUSTOM data, size={}, dim={}, mode={}'.format(
            size, dim, region))
        assert False
        custom_fpath = '.ptif'
        import kwimage
        data = kwimage.imread(custom_fpath)
    else:
        raise KeyError(DATA)

    print('Make temp directory to prepare data')
    dpath = tempfile.mkdtemp()

    lossy_ext = ('.jpg', '.ptif', '.cog')

    img_fpaths = {
        # 'png': join(dpath, 'foo.png'),
        # 'jpg': join(dpath, 'foo.jpg'),
        # 'tif': join(dpath, 'foo.tif'),
    }
    pil_img = Image.fromarray(data)
    for k, v in img_fpaths.items():
        print('DUMP v = {!r}'.format(v))
        pil_img.save(v)

    img_fpaths['cog'] = join(dpath, 'foo.cog')
    # kwimage.imwrite(img_fpaths['cog'], data, backend='gdal', compress='LZW')
    kwimage.imwrite(img_fpaths['cog'], data, backend='gdal', compress='ZSTD')
    # imwrite_cloud_optimized_geotiff(img_fpaths['cog'], data)

    if DATA == 'custom':
        from os.path import splitext
        import shutil
        ext = splitext(custom_fpath)[1][1:]
        tmp_fpath = join(dpath, 'foo' + ext)
        shutil.copy2(custom_fpath, tmp_fpath)
        img_fpaths.update({
            'custom_' + ext: tmp_fpath,
        })

    mem_fpaths = {}
    if enabled['memmap']:
        mem_fpaths = {
            'npy': join(dpath, 'foo.npy'),
        }
        for key, fpath in mem_fpaths.items():
            print('DUMP fpath = {!r}'.format(fpath))
            np.save(fpath, data)

    h5_fpaths = {}
    if enabled['HDF5']:
        import h5py
        h5_params = {
            # 'basic': {},
            # 'chunks': {'chunks': (32, 32, 1)},
            # 'lzf': {'compression': 'lzf'},
            # 'lzf_chunk32': {'compression': 'lzf', 'chunks': (32, 32, 1)},
            'lzf_chunk128': {
                'compression': 'lzf',
                'chunks': (128, 128, 1)
            },
        }
        for key, kw in h5_params.items():
            print('Dump h5 ' + key)
            fpath = h5_fpaths[key] = join(dpath, key + '.h5')
            with h5py.File(fpath, 'w') as h5_file:
                dset = h5_file.create_dataset('DATA', data.shape, data.dtype,
                                              **kw)
                dset[...] = data

    import netharn as nh
    bytes_on_disk = {}
    for k, v in mem_fpaths.items():
        bytes_on_disk['mem_' + k] = nh.util.get_file_info(v)['filesize']
    for k, v in img_fpaths.items():
        bytes_on_disk['img_' + k] = nh.util.get_file_info(v)['filesize']
    for k, v in h5_fpaths.items():
        bytes_on_disk['hdf5_' + k] = nh.util.get_file_info(v)['filesize']

    mb_on_disk = ub.map_vals(lambda x: str(round(x * 1e-6, 2)) + ' MB',
                             bytes_on_disk)
    print('on-disk memory usage: ' + ub.repr2(mb_on_disk, nl=1))

    result = {}

    def record_result(timer):
        ti = timer.parent
        val = ti.min(), ti.mean(), ti.std()
        result[ti.label] = val

    rng = np.random.RandomState()

    def get_index():
        """ Get a subregion to load """
        if region == 'small_random':
            # Small window size, but random location
            size = (172, 172)
            h, w = size
            a = rng.randint(0, data.shape[0] - h)
            b = rng.randint(0, data.shape[1] - w)
            index = tuple([slice(a, a + h), slice(b, b + w)])
        elif region == 'random':
            a, b = sorted(rng.randint(0, data.shape[0], size=2))
            c, d = sorted(rng.randint(0, data.shape[1], size=2))
            index = tuple([slice(a, b + 1), slice(c, d + 1)])
        elif region == 'corner':
            index = tuple([slice(0, 8), slice(0, 8)])
        else:
            raise KeyError(index)
            # index = region
        if len(data.shape) > 2:
            index = index + tuple([slice(0, 3)])
        area = (index[1].start, index[0].start, index[1].stop, index[0].stop)
        shape = tuple([s.stop - s.start for s in index])
        return index, area, shape

    def TIMERIT(label):
        # Ensure each timer run uses the same random numbers
        rng.seed(0)
        return timerit.Timerit(
            num=num,
            bestof=1,
            label=label,
            # unit='us',
            unit='ms',
        )

    print('Begin benchmarks\n')

    if enabled['in_memory']:
        for timer in TIMERIT('in-memory slice'):
            index, area, shape = get_index()
            want = data[index]
            with timer:
                got = data[index]
        record_result(timer)

    if enabled['memmap']:
        for key, fpath in mem_fpaths.items():
            for timer in TIMERIT('np.memmap load+slice ' + key):
                index, area, shape = get_index()
                want = data[index]
                with timer:
                    file1 = np.memmap(fpath,
                                      dtype=data.dtype.name,
                                      shape=data.shape,
                                      offset=128,
                                      mode='r')
                    got = file1[index]
                assert np.all(got == want)
            record_result(timer)

    if enabled['memmap']:
        for key, fpath in mem_fpaths.items():
            for timer in TIMERIT('np.load load+slice ' + key):
                index, area, shape = get_index()
                want = data[index]
                with timer:
                    file2 = np.load(fpath, mmap_mode='r')
                    got = file2[index]
                assert np.all(got == want)
            record_result(timer)

    if enabled['PIL']:
        for key, fpath in img_fpaths.items():
            for timer in TIMERIT('PIL open+crop (minimal) ' + key):
                index, area, shape = get_index()
                want = data[index]
                with timer:
                    core = Image.open(fpath).crop(area)
            record_result(timer)

    if enabled['PIL']:
        for key, fpath in img_fpaths.items():
            for timer in TIMERIT('PIL open+crop+getdata+asarray ' + key):
                index, area, shape = get_index()
                want = data[index]
                with timer:
                    core = Image.open(fpath).crop(area)
                    got = np.asarray(core.getdata(), dtype=np.uint8)
                    got.shape = shape
            assert fpath.endswith(lossy_ext) or np.all(got == want)
            record_result(timer)

    if enabled['PIL']:
        for key, fpath in img_fpaths.items():
            for timer in TIMERIT('PIL open+asarray+slice ' + key):
                index, area, shape = get_index()
                want = data[index]
                with timer:
                    got = np.asarray(Image.open(fpath))[index]
            assert fpath.endswith(lossy_ext) or np.all(got == want)
            record_result(timer)

    if enabled['OpenCV']:
        for key, fpath in img_fpaths.items():
            for timer in TIMERIT('OpenCV imread+slice ' + key):
                index, area, shape = get_index()
                want = data[index]
                with timer:
                    got = cv2.imread(fpath, flags=cv2.IMREAD_UNCHANGED)[index]
                if len(index) > 2:
                    got = got[:, :, ::-1]
            assert fpath.endswith(lossy_ext) or np.all(got == want)
            record_result(timer)

    if enabled['GDAL']:
        for key, fpath in img_fpaths.items():
            for timer in TIMERIT('GDAL subregion ' + key):
                index, area, shape = get_index()
                want = data[index]
                with timer:
                    got = gdal_subregion_imread(fpath, index)
            assert fpath.endswith(lossy_ext) or np.all(got == want)
            record_result(timer)

    # pip install pyvips
    if enabled['VIPS']:
        import pyvips
        for key, fpath in img_fpaths.items():
            for timer in TIMERIT('VIPS ' + key):
                index, area, shape = get_index()
                want = data[index]
                left, top = area[0:2]
                width, height = shape[0:2][::-1]
                vips_img = pyvips.Image.new_from_file(
                    fpath,
                    # access='sequential',
                    access='random',
                    # memory=False,
                    # fail=True
                )
                with timer:
                    vips_sub = vips_img.crop(left, top, width, height)
                    got = np.ndarray(buffer=vips_sub.write_to_memory(),
                                     dtype=np.uint8,
                                     shape=[
                                         vips_sub.height, vips_sub.width,
                                         vips_sub.bands
                                     ])
            assert fpath.endswith(lossy_ext) or np.all(got == want)
            record_result(timer)

    if enabled['HDF5']:
        for key, fpath in h5_fpaths.items():
            for timer in TIMERIT('HDF5 ' + key):
                with h5py.File(fpath, 'r') as file:
                    dset = file['DATA']
                    index, area, shape = get_index()
                    want = data[index]
                    with timer:
                        got = dset[index]
                assert fpath.endswith(lossy_ext) or np.all(got == want)
            record_result(timer)

    return result
Ejemplo n.º 22
0
def convert_camvid_raw_to_coco(camvid_raw_info):
    """
    Converts the raw camvid format to an MSCOCO based format, ( which lets use
    use kwcoco's COCO backend).

    Example:
        >>> # xdoctest: +REQUIRES(--download)
        >>> camvid_raw_info = grab_raw_camvid()
        >>> # test with a reduced set of data
        >>> del camvid_raw_info['img_paths'][2:]
        >>> del camvid_raw_info['mask_paths'][2:]
        >>> dset = convert_camvid_raw_to_coco(camvid_raw_info)
        >>> # xdoctest: +REQUIRES(--show)
        >>> import kwplot
        >>> plt = kwplot.autoplt()
        >>> kwplot.figure(fnum=1, pnum=(1, 2, 1))
        >>> dset.show_image(gid=1)
        >>> kwplot.figure(fnum=1, pnum=(1, 2, 2))
        >>> dset.show_image(gid=2)
    """
    import re
    import kwimage
    import kwcoco
    print('Converting CamVid to MS-COCO format')

    dset_root, img_paths, label_path, mask_paths = ub.take(
        camvid_raw_info,
        'dset_root, img_paths, label_path, mask_paths'.split(', '))

    img_infos = {
        'img_fname': img_paths,
        'mask_fname': mask_paths,
    }
    keys = list(img_infos.keys())
    next_vals = list(zip(*img_infos.values()))
    image_items = [{k: v for k, v in zip(keys, vals)} for vals in next_vals]

    dataset = {
        'img_root': dset_root,
        'images': [],
        'categories': [],
        'annotations': [],
    }

    lines = ub.readfrom(label_path).split('\n')
    lines = [line for line in lines if line]
    for line in lines:
        color_text, name = re.split('\t+', line)
        r, g, b = map(int, color_text.split(' '))
        color = (r, g, b)

        # Parse the special camvid format
        cid = (r << 16) + (g << 8) + (b << 0)
        cat = {
            'id': cid,
            'name': name,
            'color': color,
        }
        dataset['categories'].append(cat)

    for gid, img_item in enumerate(image_items, start=1):
        img = {
            'id': gid,
            'file_name': img_item['img_fname'],
            # nonstandard image field
            'segmentation': img_item['mask_fname'],
        }
        dataset['images'].append(img)

    dset = kwcoco.CocoDataset(dataset)
    dset.rename_categories({'Void': 'background'})

    assert dset.name_to_cat['background']['id'] == 0
    dset.name_to_cat['background'].setdefault('alias', []).append('Void')

    if False:
        _define_camvid_class_hierarcy(dset)

    if 1:
        # TODO: Binarize CCs (and efficiently encode if possible)
        import numpy as np

        bad_info = []
        once = False

        # Add images
        dset.remove_annotations(list(dset.index.anns.keys()))
        for gid, img in ub.ProgIter(dset.imgs.items(),
                                    desc='parse label masks'):
            mask_fpath = join(dset_root, img['segmentation'])

            rgb_mask = kwimage.imread(mask_fpath, space='rgb')
            r, g, b = rgb_mask.T.astype(np.int64)
            cid_mask = np.ascontiguousarray(rgb_to_cid(r, g, b).T)

            cids = set(np.unique(cid_mask)) - {0}

            for cid in cids:
                if cid not in dset.cats:
                    if gid == 618:
                        # Handle a known issue with image 618
                        c_mask = (cid == cid_mask).astype(np.uint8)
                        total_bad = c_mask.sum()
                        if total_bad < 32:
                            if not once:
                                print(
                                    'gid 618 has a few known bad pixels, ignoring them'
                                )
                                once = True
                            continue
                        else:
                            raise Exception('more bad pixels than expected')
                    else:
                        raise Exception(
                            'UNKNOWN cid = {!r} in gid={!r}'.format(cid, gid))

                    # bad_rgb = cid_to_rgb(cid)
                    # print('bad_rgb = {!r}'.format(bad_rgb))
                    # print('WARNING UNKNOWN cid = {!r} in gid={!r}'.format(cid, gid))
                    # bad_info.append({
                    #     'gid': gid,
                    #     'cid': cid,
                    # })
                else:
                    ann = {
                        'category_id': cid,
                        'image_id': gid
                        # 'segmentation': mask.to_coco()
                    }
                    assert cid in dset.cats
                    c_mask = (cid == cid_mask).astype(np.uint8)
                    mask = kwimage.Mask(c_mask, 'c_mask')

                    box = kwimage.Boxes([mask.get_xywh()], 'xywh')
                    # box = mask.to_boxes()

                    ann['bbox'] = ub.peek(box.to_coco())
                    ann['segmentation'] = mask.to_coco()
                    dset.add_annotation(**ann)

        if 0:
            bad_cids = [i['cid'] for i in bad_info]
            print(sorted([c['color'] for c in dataset['categories']]))
            print(sorted(set([cid_to_rgb(i['cid']) for i in bad_info])))

            gid = 618
            img = dset.imgs[gid]
            mask_fpath = join(dset_root, img['segmentation'])
            rgb_mask = kwimage.imread(mask_fpath, space='rgb')
            r, g, b = rgb_mask.T.astype(np.int64)
            cid_mask = np.ascontiguousarray(rgb_to_cid(r, g, b).T)
            cid_hist = ub.dict_hist(cid_mask.ravel())

            bad_cid_hist = {}
            for cid in bad_cids:
                bad_cid_hist[cid] = cid_hist.pop(cid)

            import kwplot
            kwplot.autompl()
            kwplot.imshow(rgb_mask)

    if 0:
        import kwplot
        plt = kwplot.autoplt()
        plt.clf()
        dset.show_image(1)

        import xdev
        gid_list = list(dset.imgs)
        for gid in xdev.InteractiveIter(gid_list):
            dset.show_image(gid)
            xdev.InteractiveIter.draw()

    dset._build_index()
    dset._build_hashid()
    return dset
Ejemplo n.º 23
0
    def after_initialize(harn):
        STYLE_IMAGE_PATH = ub.grabdata(
            'https://raw.githubusercontent.com/iamRusty/fast-neural-style-pytorch/master/images/mosaic.jpg'
        )

        device = harn.xpu.device
        harn.MSELoss = nn.MSELoss().to(device)

        vgg_path = ub.grabdata(
            'https://web.eecs.umich.edu/~justincj/models/vgg16-00b39a1b.pth')

        # TODO: should be tracked
        harn.vgg = VGG16(**{'vgg_path': vgg_path})
        harn.vgg = harn.xpu.move(harn.vgg)

        def itot(img, max_size=None):
            # Rescale the image
            if (max_size is None):
                itot_t = transforms.Compose([
                    # transforms.ToPILImage(),
                    transforms.ToTensor(),
                    transforms.Lambda(lambda x: x.mul(255))
                ])
            else:
                H, W, C = img.shape
                image_size = tuple(
                    [int((float(max_size) / max([H, W])) * x) for x in [H, W]])
                itot_t = transforms.Compose([
                    transforms.ToPILImage(),
                    transforms.Resize(image_size),
                    transforms.ToTensor(),
                    transforms.Lambda(lambda x: x.mul(255))
                ])

            # Convert image to tensor
            tensor = itot_t(img)

            # Add the batch_size dimension
            tensor = tensor.unsqueeze(dim=0)
            return tensor

        # Get Style Features
        imagenet_neg_mean = torch.tensor([-103.939, -116.779, -123.68],
                                         dtype=torch.float32).reshape(
                                             1, 3, 1, 1).to(device)
        style_image = kwimage.imread(STYLE_IMAGE_PATH)
        style_tensor = itot(style_image).to(device)
        style_tensor = style_tensor.add(imagenet_neg_mean)
        B, C, H, W = style_tensor.shape

        harn.imagenet_neg_mean = imagenet_neg_mean
        harn.style_tensor = style_tensor

        batch_size = harn.script_config['batch_size']
        im = style_tensor.expand([batch_size, C, H, W])

        style_features = harn.vgg(im)
        style_gram = {}
        for key, value in style_features.items():
            style_gram[key] = gram(value)
        harn.style_gram = style_gram