Beispiel #1
0
    def _stream(self, buffer_size=None):
        if buffer_size is None:
            buffer_size = self.buffer_size
        if buffer_size and buffer_size > 1:
            logging.debug('Reading image stream using thread buffer')
            buffer_func = partial(buffered_imread, buffer_size=buffer_size)
        else:
            logging.debug('Reading image stream using serial buffer')
            buffer_func = serial_imread

        idx1_slice = self.aligned_idx1[self.index:]
        idx2_slice = self.aligned_idx2[self.index:]
        frame_ids = self.aligned_frameids[self.index:]

        fpath_gen1 = ub.take(self.image_path_list1, idx1_slice)
        fpath_gen2 = ub.take(self.image_path_list2, idx2_slice)

        img_gen1 = buffer_func(fpath_gen1)
        img_gen2 = buffer_func(fpath_gen2)

        logging.debug('Begin reading buffers')
        for frame_id, img1, img2 in zip(frame_ids, img_gen1, img_gen2):
            yield frame_id, img1, img2
            self.index += 1
        logging.debug('Stream is finished')
Beispiel #2
0
def draw_instance_contours(img, gti, gtl=None, thickness=2, alpha=1, color=None):
    """

    img = util.imread('/home/joncrall/remote/aretha/data/UrbanMapper3D/training/TAM_Tile_003_RGB.tif')
    gti = util.imread(ub.truepath('~/remote/aretha/data/UrbanMapper3D/training/TAM_Tile_003_GTI.tif'))
    gtl = util.imread('/home/joncrall/remote/aretha/data/UrbanMapper3D/training/TAM_Tile_003_GTL.tif')
    thickness = 2
    alpha = 1

    """
    import cv2

    grouped_contours = instance_contours(gti)

    if gtl is not None:
        unknown_labels = set(np.unique(gti[gtl == 65]))
    else:
        unknown_labels = set()

    known_labels = set(grouped_contours.keys()) - unknown_labels

    BGR_GREEN = (0, 255, 0)
    BGR_BLUE = (255, 0, 0)
    img = util.ensure_float01(img)
    base = np.ascontiguousarray((255 * img[:, :, 0:3]).astype(np.uint8))

    # Draw an image to overlay first
    draw_img = np.zeros(base.shape, dtype=np.uint8)

    if color is None:
        color = BGR_GREEN

    known_contours = np.array(list(ub.flatten(list(ub.take(grouped_contours, known_labels)))))
    draw_img = cv2.drawContours(
        image=draw_img, contours=known_contours,
        contourIdx=-1, color=color, thickness=thickness)

    if unknown_labels:
        unknown_contours = np.array(list(ub.flatten(ub.take(grouped_contours, unknown_labels))))
        draw_img = cv2.drawContours(
            image=draw_img, contours=unknown_contours,
            contourIdx=-1, color=BGR_BLUE, thickness=thickness)

    contour_overlay = util.ensure_alpha_channel(draw_img, alpha=0)
    contour_overlay.T[3].T[draw_img.sum(axis=2) > 0] = alpha

    # zero out the edges to avoid visualization errors
    contour_overlay[0:thickness, :, :] = 0
    contour_overlay[-thickness:, :, :] = 0
    contour_overlay[:, 0:thickness, :] = 0
    contour_overlay[:, -thickness:, :] = 0

    # img1 = contour_overlay
    # img2 = base
    # from clab import profiler
    # _ = profiler.profile_onthefly(util.overlay_alpha_images)(contour_overlay, base, keepalpha=False)

    draw_img = util.overlay_alpha_images(contour_overlay, base, keepalpha=False)
    draw_img = np.ascontiguousarray((255 * draw_img[:, :, 0:3]).astype(np.uint8))
    return draw_img
Beispiel #3
0
    def _stream(self, buffer_size=None):
        if buffer_size is None:
            buffer_size = self.buffer_size
        if buffer_size and buffer_size > 1:
            logging.debug('Reading image stream using thread buffer')
            buffer_func = partial(buffered_imread, buffer_size=buffer_size)
        else:
            logging.debug('Reading image stream using serial buffer')
            buffer_func = serial_imread

        idx1_slice = self.aligned_idx1[self.index:]
        idx2_slice = self.aligned_idx2[self.index:]
        frame_ids = self.aligned_frameids[self.index:]

        fpath_gen1 = ub.take(self.image_path_list1, idx1_slice)
        fpath_gen2 = ub.take(self.image_path_list2, idx2_slice)

        img_gen1 = buffer_func(fpath_gen1)
        img_gen2 = buffer_func(fpath_gen2)

        logging.debug('Begin reading buffers')
        for frame_id, img1, img2 in zip(frame_ids, img_gen1, img_gen2):
            yield frame_id, img1, img2
            self.index += 1
        logging.debug('Stream is finished')
Beispiel #4
0
    def get_summary(self, profile_block_list, maxlines=20):
        """
        Args:
            profile_block_list (List[str]):
            maxlines (int):

        Returns:
            str:

        References:
            https://github.com/rkern/line_profiler
        """
        import ubelt as ub
        time_list = [self.get_block_totaltime(block) for block in profile_block_list]
        time_list = [time if time is not None else -1 for time in time_list]

        @ub.memoize
        def readlines(fpath):
            return open(fpath, 'r').readlines()

        blockid_list = [self.get_block_id(block, readlines=readlines)
                        for block in profile_block_list]
        sortx = ub.argsort(time_list)
        sorted_time_list = list(ub.take(time_list, sortx))
        sorted_blockid_list = list(ub.take(blockid_list, sortx))

        aligned_blockid_list = _align_lines(sorted_blockid_list, ':')
        summary_lines = [('%6.2f seconds - ' % time) + line
                         for time, line in
                         zip(sorted_time_list, aligned_blockid_list)]

        summary_text = '\n'.join(summary_lines[-maxlines:])
        return summary_text
Beispiel #5
0
    def get_summary(self, profile_block_list, maxlines=20):
        """
        References:
            https://github.com/rkern/line_profiler
        """
        time_list = [self.get_block_totaltime(block) for block in profile_block_list]
        time_list = [time if time is not None else -1 for time in time_list]
        blockid_list = [self.get_block_id(block) for block in profile_block_list]
        sortx = ub.argsort(time_list)
        sorted_time_list = list(ub.take(time_list, sortx))
        sorted_blockid_list = list(ub.take(blockid_list, sortx))

        import utool as ut
        aligned_blockid_list = ut.util_str.align_lines(sorted_blockid_list, ':')
        summary_lines = [('%6.2f seconds - ' % time) + line
                         for time, line in
                         zip(sorted_time_list, aligned_blockid_list)]
        #summary_header = ut.codeblock(
        #    '''
        #    CLEANED PROFILE OUPUT

        #    The Pystone timings are not from kernprof, so they may include kernprof
        #    overhead, whereas kernprof timings do not (unless the line being
        #    profiled is also decorated with kernrof)

        #    The kernprof times are reported in Timer Units

        #    ''')
        # summary_lines_ = ut.listclip(summary_lines, maxlines, fromback=True)
        summary_text = '\n'.join(summary_lines[-maxlines:])
        return summary_text
Beispiel #6
0
    def subset(self, sub_gids):
        new_dataset = ub.odict([(k, []) for k in self.dataset])
        new_dataset['categories'] = self.dataset['categories']
        new_dataset['info'] = self.dataset['info']
        new_dataset['licenses'] = self.dataset['licenses']

        sub_aids = sorted([aid for gid in sub_gids
                           for aid in self.gid_to_aids[gid]])
        new_dataset['annotations'] = list(ub.take(self.anns, sub_aids))
        new_dataset['images'] = list(ub.take(self.imgs, sub_gids))
        sub_dset = CocoDataset(new_dataset, img_root=self.img_root)
        return sub_dset
Beispiel #7
0
    def take(self, indicies, with_dump=False):

        indicies = list(indicies)

        keys = sorted(self.paths.keys())
        new = Inputs.from_paths(
            **{key: list(ub.take(self.paths[key], indicies))
               for key in keys})
        if with_dump:
            if self.dump_im_names is not None:
                new.dump_im_names = list(ub.take(self.dump_im_names, indicies))
        return new
Beispiel #8
0
    def _to_coco(dmet):
        """
        Convert to a coco representation of truth and predictions
        """
        import ndsampler
        true = ndsampler.CocoDataset()
        pred = ndsampler.CocoDataset()

        for node in dmet.classes:
            # cid = dmet.classes.graph.node[node]['id']
            cid = dmet.classes.index(node)
            supercategory = list(dmet.classes.graph.pred[node])
            if len(supercategory) == 0:
                supercategory = None
            else:
                assert len(supercategory) == 1
                supercategory = supercategory[0]
            true.add_category(node, id=cid, supercategory=supercategory)
            pred.add_category(node, id=cid, supercategory=supercategory)

        for imgname, gid in dmet._imgname_to_gid.items():
            true.add_image(imgname, id=gid)
            pred.add_image(imgname, id=gid)

        idx_to_id = {
            idx: dmet.classes.index(node)
            for idx, node in enumerate(dmet.classes.idx_to_node)
        }

        for gid, pred_dets in dmet.gid_to_pred_dets.items():
            pred_boxes = pred_dets.boxes
            if 'scores' in pred_dets.data:
                pred_scores = pred_dets.scores
            else:
                pred_scores = np.ones(len(pred_dets))
            pred_cids = list(ub.take(idx_to_id, pred_dets.class_idxs))
            pred_xywh = pred_boxes.to_xywh().data.tolist()
            for bbox, cid, score in zip(pred_xywh, pred_cids, pred_scores):
                pred.add_annotation(gid, cid, bbox=bbox, score=score)

        for gid, true_dets in dmet.gid_to_true_dets.items():
            true_boxes = true_dets.boxes
            if 'weights' in true_dets.data:
                true_weights = true_dets.weights
            else:
                true_weights = np.ones(len(true_boxes))
            true_cids = list(ub.take(idx_to_id, true_dets.class_idxs))
            true_xywh = true_boxes.to_xywh().data.tolist()
            for bbox, cid, weight in zip(true_xywh, true_cids, true_weights):
                true.add_annotation(gid, cid, bbox=bbox, weight=weight)

        return pred, true
Beispiel #9
0
    def main(cls, cmdline=True, **kw):
        """
        Example:
            >>> kw = {'src': 'special:shapes8',
            >>>       'dst1': 'train.json', 'dst2': 'test.json'}
            >>> cmdline = False
            >>> cls = CocoSplitCLI
            >>> cls.main(cmdline, **kw)
        """
        import kwcoco
        import kwarray
        from kwcoco.util import util_sklearn

        config = cls.CLIConfig(kw, cmdline=cmdline)
        print('config = {}'.format(ub.repr2(dict(config), nl=1)))

        if config['src'] is None:
            raise Exception('must specify source: {}'.format(config['src']))

        print('reading fpath = {!r}'.format(config['src']))
        dset = kwcoco.CocoDataset.coerce(config['src'])
        annots = dset.annots()
        gids = annots.gids
        cids = annots.cids

        # Balanced category split
        rng = kwarray.ensure_rng(config['rng'])

        shuffle = rng is not None
        self = util_sklearn.StratifiedGroupKFold(n_splits=config['factor'],
                                                 random_state=rng,
                                                 shuffle=shuffle)
        split_idxs = list(self.split(X=gids, y=cids, groups=gids))
        idxs1, idxs2 = split_idxs[0]

        gids1 = sorted(ub.unique(ub.take(gids, idxs1)))
        gids2 = sorted(ub.unique(ub.take(gids, idxs2)))

        dset1 = dset.subset(gids1)
        dset2 = dset.subset(gids2)

        dset1.fpath = config['dst1']
        print('Writing dset1 = {!r}'.format(dset1.fpath))
        dset1.dump(dset1.fpath, newlines=True)

        dset2.fpath = config['dst2']
        print('Writing dset2 = {!r}'.format(dset2.fpath))
        dset2.dump(dset2.fpath, newlines=True)
Beispiel #10
0
    def class_weights(self):
        """
        Ignore:
            >>> from clab.live.urban_train import *
            >>> self = load_task_dataset('urban_mapper_3d')['train']
            >>> self.class_weights()
        """
        # HACK
        class_weights = np.array([0.05496113, 0.67041818, 1.96697962, 0.])
        print('class_weights = {!r}'.format(class_weights))
        print('class_names   = {!r}'.format(self.task.classnames))
        return class_weights

        # Handle class weights
        print('prep class weights')
        gtstats = self.inputs.prepare_gtstats(self.task)
        gtstats = self.inputs.gtstats
        # Take class weights (ensure they are in the same order as labels)
        mfweight_dict = gtstats['mf_weight'].to_dict()
        class_weights = np.array(
            list(ub.take(mfweight_dict, self.task.classnames)))
        class_weights[self.task.ignore_labels] = 0

        if 'inner-building' in self.task.classnames:
            # increase weight of inner building
            class_weights[1] *= 2

        # HACK
        # class_weights[0] = 1.0
        # class_weights[1] = 0.7
        print('class_weights = {!r}'.format(class_weights))
        print('class_names   = {!r}'.format(self.task.classnames))
        return class_weights
Beispiel #11
0
    def _demo_probs(self, num=5, rng=0, nonrandom=3, hackargmax=True):
        """ dummy probabilities for testing """
        import torch
        rng = kwarray.ensure_rng(rng)
        class_energy = torch.FloatTensor(rng.rand(num, len(self)))

        # Setup the first few examples to prefer being classified
        # as a fine grained class to a decreasing degree.
        # The first example is set to have equal energy
        # The i + 2-th example is set to have an extremely high energy.
        start = 0
        nonrandom = min(nonrandom, (num - start))
        if nonrandom > 0:
            path = sorted(ub.take(self.node_to_idx, nx.dag_longest_path(self.graph)))

            class_energy[start] = 1 / len(class_energy[start])
            if hackargmax:
                # HACK: even though we want to test uniform distributions, it makes
                # regression tests difficiult because torch and numpy return a
                # different argmax when the array has more than one max value.
                # add a VERY small epsilon to make max values distinct
                class_energy[start] += torch.linspace(0, .00001, len(class_energy[start]))

            if nonrandom > 1:
                for i in range(nonrandom - 2):
                    class_energy[start + i + 1][path] += 2 ** (i / 4)
                class_energy[start + i + 2][path] += 2 ** 20

        class_probs = self.hierarchical_softmax(class_energy, dim=1)
        return class_probs
Beispiel #12
0
    def build_graph(conn):
        import networkx as nx
        conn.input_nodes = input_nodes = ub.odict()
        conn.topsort = list(nx.topological_sort(conn.graph))

        for node in conn.topsort:
            preds = list(conn.graph.pred[node])
            if preds:
                argxs = []
                for k in preds:
                    argxs.append(conn.graph.edges[(k, node)].get('argx', None))
                def rectify_argxs(argxs):
                    """
                    Ensure the arguments are given in the correct order
                    """
                    given = [a for a in argxs if a is not None]
                    mask = np.array(ub.boolmask(given, len(argxs)))
                    values = np.where(~mask)[0]
                    if len(values) > 0:
                        assert len(values) <= 1
                        missingx = argxs.index(None)
                        argxs[missingx] = values[0]
                    return argxs
                argxs = rectify_argxs(argxs)
                arg_names = list(ub.take(preds, argxs))
                input_nodes[node] = arg_names
            else:
                input_nodes[node] = None
Beispiel #13
0
def suggest_spelling_correction(name, all_names, top=10):
    import xdev
    distances = xdev.edit_distance(name, all_names)
    idxs = ub.argsort(distances)[0:top]
    candidates = list(ub.take(all_names, idxs))
    print('did you mean on of: {}?'.format(ub.repr2(candidates, nl=1)))
    return candidates
Beispiel #14
0
    def killold(pattern, num=4):
        """
        Leaves no more than `num` instances of a program alive.  Ordering is
        determined by most recent usage.

        CommandLine:
            python -m vimtk.xctrl XCtrl.killold gvim 2

        Example:
            >>> # SCRIPT
            >>> XCtrl = xctrl.XCtrl
            >>> pattern = 'gvim'
            >>> num = 2
        """
        import psutil
        num = int(num)
        winid_list = XCtrl.findall_window_ids(pattern)
        winid_list = XCtrl.sort_window_ids(winid_list, 'mru')[num:]

        info = XCtrl.cmd('wmctrl -lxp')
        lines = info['out'].split('\n')
        lines = [' '.join(list(ub.take(line.split(), [0, 2])))
                 for line in lines]
        output_lines = lines
        # output_lines = XCtrl.cmd(
        #     """wmctrl -lxp | awk '{print $1 " " $3}'""",
        #     **cmdkw)['out'].strip().split('\n')
        output_fields = [line.split(' ') for line in output_lines]
        output_fields = [(int(wid, 16), int(pid)) for wid, pid in output_fields]
        pid_list = [pid for wid, pid in output_fields if wid in winid_list]
        for pid in pid_list:
            proc = psutil.Process(pid=pid)
            proc.kill()
Beispiel #15
0
    def _cm_breaking(infr, cm_list=None, review_cfg={}):
        """
            >>> review_cfg = {}
        """
        if cm_list is None:
            cm_list = infr.cm_list
        ranks_top = review_cfg.get('ranks_top', None)
        ranks_bot = review_cfg.get('ranks_bot', None)

        # Construct K-broken graph
        edges = []

        if ranks_bot is None:
            ranks_bot = 0

        for count, cm in enumerate(cm_list):
            score_list = cm.annot_score_list
            rank_list = ub.argsort(score_list)[::-1]
            sortx = ub.argsort(rank_list)

            top_sortx = sortx[:ranks_top]
            bot_sortx = sortx[len(sortx) - ranks_bot:]
            short_sortx = list(ub.unique(top_sortx + bot_sortx))

            daid_list = list(ub.take(cm.daid_list, short_sortx))
            for daid in daid_list:
                u, v = (cm.qaid, daid)
                if v < u:
                    u, v = v, u
                edges.append((u, v))
        return edges
Beispiel #16
0
def draw_perclass_roc(cx_to_info, classes=None, prefix='', fnum=1,
                      fp_axis='count', **kw):
    """
    Args:
        cx_to_info (PerClass_Measures | Dict):

        fp_axis (str): can be count or rate
    """
    import kwplot
    # Sort by descending AP
    cxs = list(cx_to_info.keys())
    priority = np.array([item['auc'] for item in cx_to_info.values()])
    priority[np.isnan(priority)] = -np.inf
    cxs = list(ub.take(cxs, np.argsort(priority)))[::-1]
    xydata = ub.odict()

    with warnings.catch_warnings():
        warnings.filterwarnings('ignore', 'Mean of empty slice', RuntimeWarning)
        mAUC = np.nanmean([item['auc'] for item in cx_to_info.values()])

    if fp_axis == 'count':
        xlabel = 'FP-count'
    elif fp_axis == 'rate':
        xlabel = 'FPR'
    else:
        raise KeyError(fp_axis)

    for cx in cxs:
        info = cx_to_info[cx]

        catname = classes[cx] if isinstance(cx, int) else cx

        try:
            auc = info['trunc_auc']
            tpr = info['trunc_tpr']
            fp_count = info['trunc_fp_count']
            fpr = info['trunc_fpr']
        except KeyError:
            auc = info['auc']
            tpr = info['tpr']
            fp_count = info['fp_count']
            fpr = info['fpr']

        label_suffix = _realpos_label_suffix(info)
        label = 'auc={:0.2f}: {} ({})'.format(auc, catname, label_suffix)

        if fp_axis == 'count':
            xydata[label] = (fp_count, tpr)
        elif fp_axis == 'rate':
            xydata[label] = (fpr, tpr)

    ax = kwplot.multi_plot(
        xydata=xydata, fnum=fnum,
        ylim=(0, 1), xpad=0.01, ypad=0.01,
        xlabel=xlabel, ylabel='TPR',
        title=prefix + 'perclass mAUC={:.4f}'.format(mAUC),
        legend_loc='lower right',
        color='distinct', linestyle='cycle', marker='cycle', **kw
    )
    return ax
Beispiel #17
0
    def take(self, indices, inplace=False):
        """
        Return the elements in the given *positional* indices along an axis.

        Args:
            inplace (bool): NOT PART OF PANDAS API

        Notes:
            assumes axis=0

        Example:
            >>> df_light = DataFrameLight._demodata(num=7)
            >>> indices = [0, 2, 3]
            >>> sub1 = df_light.take(indices)
            >>> # xdoctest: +REQUIRES(module:pandas)
            >>> df_heavy = df_light.pandas()
            >>> sub2 = df_heavy.take(indices)
            >>> assert np.all(sub1 == sub2)
        """
        subset = self if inplace else self.__class__()
        if isinstance(indices, slice):
            for key in self._data.keys():
                subset._data[key] = self._data[key][indices]
        else:
            for key in self._data.keys():
                subset._data[key] = list(ub.take(self._data[key], indices))
        return subset
Beispiel #18
0
    def getImgIds(self, imgIds=[], catIds=[]):
        '''
        Get img ids that satisfy given filter conditions.
        :param imgIds (int array) : get imgs for given ids
        :param catIds (int array) : get imgs with all given cats
        :return: ids (int array)  : integer array of img ids

        Example:
            >>> from kwcoco.compat_dataset import *  # NOQA
            >>> import kwcoco
            >>> self = COCO(kwcoco.CocoDataset.demo('shapes8').dataset)
            >>> self.getImgIds(imgIds=[1, 2])
            >>> self.getImgIds(catIds=[3, 6, 7])
            >>> self.getImgIds(catIds=[3, 6, 7], imgIds=[1, 2])
        '''
        imgIds = imgIds if ub.iterable(imgIds) else [imgIds]
        catIds = catIds if ub.iterable(catIds) else [catIds]

        if not imgIds:
            valid_gids = set(self.imgs.keys())
        else:
            valid_gids = set(imgIds)

        if catIds:
            hascat_gids = set()
            for aids in ub.take(self.index.cid_to_aids, catIds):
                hascat_gids |= set(self.annots(aids).lookup('image_id'))

            valid_gids &= hascat_gids
        return sorted(valid_gids)
Beispiel #19
0
    def cnames(self):
        """
        Get the column of category names

        Returns:
            List[int]
        """
        return [cat['name'] for cat in ub.take(self._dset.cats, self.cids)]
Beispiel #20
0
 def aids(self):
     """
     Example:
         >>> import kwcoco
         >>> self = kwcoco.CocoDataset.demo().images()
         >>> print(ub.repr2(list(map(list, self.aids)), nl=0))
         [[1, 2, 3, 4, 5, 6, 7, 8, 9], [10, 11], []]
     """
     return list(ub.take(self._dset.gid_to_aids, self._ids))
Beispiel #21
0
 def colorize(task, y_img, x_img=None, alpha=.6):
     labels = list(ub.take(task.classname_to_id, task.classnames))
     assert np.all(
         labels == task.labels), ('classname order assumption is invalid')
     label_to_color = np.array(
         list(ub.take(task.class_colors, task.classnames)))
     label_to_color = label_to_color.astype(np.uint8)
     # label_to_color = pd.Series(
     #     list(ub.take(task.class_colors, task.classnames)),
     #     index=list(ub.take(task.classname_to_id, task.classnames)),
     # )
     color_img = label_to_color[y_img.astype(np.int)]
     if x_img is not None:
         # blend the color image on top of the data
         blend = imutil.overlay_colorized(color_img, x_img, alpha=alpha)
         return blend
     else:
         return color_img
Beispiel #22
0
    def show_image(self, index, fnum=None):
        from netharn import util
        hwc, boxes, gt_classes = self._load_item(index, inp_size=None)

        labels = list(ub.take(self.label_names, gt_classes))

        util.figure(doclf=True, fnum=fnum)
        util.imshow(hwc, colorspace='rgb')
        util.draw_boxes(boxes, color='green', box_format='tlbr', labels=labels)
Beispiel #23
0
 def loadCats(self, ids=[]):
     """
     Load cats with the specified ids.
     :param ids (int array)       : integer ids specifying cats
     :return: cats (object array) : loaded cat objects
     """
     if isinstance(ids, int):
         return self.cats[ids]
     return list(ub.take(self.cats, ids))
Beispiel #24
0
 def n_annots(self):
     """
     Example:
         >>> import kwcoco
         >>> self = kwcoco.CocoDataset.demo().images()
         >>> print(ub.repr2(self.n_annots, nl=0))
         [9, 2, 0]
     """
     return list(map(len, ub.take(self._dset.gid_to_aids, self._ids)))
Beispiel #25
0
 def take(self, indices, inplace=False):
     subset = self if inplace else self.__class__()
     if isinstance(indices, slice):
         for key in self._data.keys():
             subset._data[key] = self._data[key][indices]
     else:
         for key in self._data.keys():
             subset._data[key] = list(ub.take(self._data[key], indices))
     return subset
Beispiel #26
0
 def loadAnns(self, ids=[]):
     """
     Load anns with the specified ids.
     :param ids (int array)       : integer ids specifying anns
     :return: anns (object array) : loaded ann objects
     """
     if isinstance(ids, int):
         return self.anns[ids]
     return list(ub.take(self.anns, ids))
Beispiel #27
0
    def _stratified_split(gids, cids, n_splits=2, rng=None):
        """ helper to split while trying to maintain class balance within images """
        rng = kwarray.ensure_rng(rng)
        from ndsampler.utils import util_sklearn
        selector = util_sklearn.StratifiedGroupKFold(n_splits=n_splits,
                                                     random_state=rng,
                                                     shuffle=True)

        # from sklearn import model_selection
        # selector = model_selection.StratifiedKFold(
        #     n_splits=n_splits, random_state=rng, shuffle=True)
        skf_list = list(selector.split(X=gids, y=cids, groups=gids))
        trainx, testx = skf_list[0]

        if 0:
            _train_gids = set(ub.take(gids, trainx))
            _test_gids = set(ub.take(gids, testx))
            print('_train_gids = {!r}'.format(_train_gids))
            print('_test_gids = {!r}'.format(_test_gids))
        return trainx, testx
Beispiel #28
0
    def take(self, idxs):
        """
        Take a subset by index

        Example:
            >>> import kwcoco
            >>> self = kwcoco.CocoDataset.demo().annots()
            >>> assert len(self.take([0, 2, 3])) == 3
        """
        subids = list(ub.take(self._ids, idxs))
        newself = self.__class__(subids, self._dset)
        return newself
Beispiel #29
0
    def subset(self, sub_gids):
        """
        Return a subset of the larger coco dataset by specifying which images
        to port. All annotations in those images will be taken.

        Example:
            >>> dataset = demo_coco_data()
            >>> self = CocoDataset(dataset, tag='demo')
            >>> sub_gids = [1, 3]
            >>> sub_dset = self.subset(sub_gids)
            >>> assert len(self.gid_to_aids) == 3
            >>> assert len(sub_dset.gid_to_aids) == 2

        Example:
            >>> dataset = demo_coco_data()
            >>> self = CocoDataset(dataset, tag='demo')
            >>> sub1 = self.subset([1])
            >>> sub2 = self.subset([2])
            >>> sub3 = self.subset([3])
            >>> others = [sub1, sub2, sub3]
            >>> rejoined = CocoDataset.union(*others)
            >>> assert len(sub1.anns) == 9
            >>> assert len(sub2.anns) == 2
            >>> assert len(sub3.anns) == 0
            >>> assert rejoined.basic_stats() == self.basic_stats()
        """
        new_dataset = ub.odict([(k, []) for k in self.dataset])
        new_dataset['categories'] = self.dataset['categories']
        new_dataset['info'] = self.dataset['info']
        new_dataset['licenses'] = self.dataset['licenses']

        sub_gids = sorted(set(sub_gids))
        sub_aids = sorted(
            [aid for gid in sub_gids for aid in self.gid_to_aids.get(gid, [])])
        new_dataset['annotations'] = list(ub.take(self.anns, sub_aids))
        new_dataset['images'] = list(ub.take(self.imgs, sub_gids))

        sub_dset = CocoDataset(new_dataset, img_root=self.img_root)
        return sub_dset
Beispiel #30
0
    def seeded_objective(**params):
        seed_thresh, mask_thresh, min_seed_size, min_size = ub.take(
            params, 'seed_thresh, mask_thresh, min_seed_size, min_size'.split(', '))
        fscores = []
        for path, path1 in zip(ub.take(prob_paths, subx), ub.take(prob1_paths, subx)):
            gti, uncertain, dsm, bgr = gt_info_from_path(path)

            probs = np.load(path)['arr_0']
            seed_probs = probs[:, :, task.classname_to_id['inner_building']]
            seed = (seed_probs > seed_thresh).astype(np.uint8)

            probs1 = np.load(path1)['arr_0']
            mask_probs = probs1[:, :, 1]
            mask = (mask_probs > mask_thresh).astype(np.uint8)

            pred = seeded_instance_label(seed, mask,
                                         min_seed_size=min_seed_size,
                                         min_size=min_size)
            scores = instance_fscore(gti, uncertain, dsm, pred)
            fscore = scores[0]
            fscores.append(fscore)
        mean_fscore = np.mean(fscores)
        return mean_fscore
Beispiel #31
0
        def func(**new_hyperparams):
            probs = np.load(path)['arr_0']
            probs1 = np.load(path1)['arr_0']
            seed_probs = probs[:, :, task.classname_to_id['inner_building']]
            mask_probs = probs1[:, :, 1]

            seed_thresh, mask_thresh, min_seed_size = ub.take(
                new_hyperparams, ['seed_thresh', 'mask_thresh', 'min_seed_size'])
            seed = (seed_probs > mask_thresh).astype(np.uint8)
            mask = (mask_probs > seed_thresh).astype(np.uint8)
            pred = seeded_instance_label(seed, mask, min_seed_size=min_seed_size)
            scores = instance_fscore(gti, uncertain, dsm, pred)
            fscore = scores[0]
            return fscore
Beispiel #32
0
    def issue(repo, command, sudo=False, dry=False, error='raise', return_out=False):
        """
        issues a command on a repo

        Example:
            >>> # DISABLE_DOCTEST
            >>> repo = dirname(dirname(ub.__file__))
            >>> command = 'git status'
            >>> sudo = False
            >>> result = repocmd(repo, command, sudo)
            >>> print(result)
        """
        WIN32 = sys.platform.startswith('win32')
        if WIN32:
            assert not sudo, 'cant sudo on windows'
        if command == 'short_status':
            return repo.short_status()
        command_list = [command]
        cmdstr = '\n        '.join([cmd_ for cmd_ in command_list])
        if not dry:
            import ubelt as ub
            print('+--- *** repocmd(%s) *** ' % (cmdstr,))
            print('repo=%s' % ub.color_text(repo.dpath, 'yellow'))
        verbose = True
        with repo.chdir_context():
            ret = None
            for count, command in enumerate(command_list):
                if dry:
                    print(command)
                    continue
                if not sudo or WIN32:
                    cmdinfo = ub.cmd(command, verbose=1)
                    out, err, ret = ub.take(cmdinfo, ['out', 'err', 'ret'])
                else:
                    out, err, ret = ub.cmd('sudo ' + command)
                if verbose > 1:
                    print('ret(%d) = %r' % (count, ret,))
                if ret != 0:
                    if error == 'raise':
                        raise Exception('Failed command %r' % (command,))
                    elif error == 'return':
                        return out
                    else:
                        raise ValueError('unknown flag error=%r' % (error,))
                if return_out:
                    return out
        if not dry:
            print('L____')
Beispiel #33
0
def demo(config=None):
    """
    Runs the algorithm end-to-end.
    """
    # dataset = 'test'
    # dataset = 'haul83'

    if config is None:
        import argparse
        parser = argparse.ArgumentParser(description='Standalone camtrawl demo')

        parser.add_argument('--cal', help='path to matlab or numpy stereo calibration file', default='cal.npz')
        parser.add_argument('--left', help='path to directory containing left images', default='left')
        parser.add_argument('--right', help='path to directory containing right images', default='right')
        parser.add_argument('--out', help='output directory', default='./out')
        parser.add_argument('-f', '--overwrite', action='store_true', help='will delete any existing output')
        parser.add_argument('--draw', action='store_true', help='draw visualization of algorithm steps')

        parser.add_argument('--dataset', default=None,
                            help='Developer convenience assumes you have demo '
                                 ' data downloaded and available. If you dont '
                                 ' specify the other args.')

        args = parser.parse_args()
        config = args.__dict__.copy()
        config = FrozenKeyDict(config)

    if config['dataset'] is not None:
        img_path1, img_path2, cal_fpath = demodata_input(dataset=config['dataset'])
        config['left'] = img_path1
        config['right'] = img_path2
        config['cal'] = cal_fpath

    img_path1, img_path2, cal_fpath = ub.take(config, [
        'left', 'right', 'cal'])
    out_dpath = config['out']
    logging.info('Demo Config = {!r}'.format(config))

    ub.ensuredir(out_dpath)

    # ----
    # Choose parameter configurations
    # ----

    # Use GMM based model
    gmm_params = {
    }
    triangulate_params = {
    }

    DRAWING = config['draw']

    # ----
    # Initialize algorithms
    # ----

    detector1 = ctalgo.GMMForegroundObjectDetector(**gmm_params)
    detector2 = ctalgo.GMMForegroundObjectDetector(**gmm_params)
    triangulator = ctalgo.FishStereoMeasurments(**triangulate_params)

    try:
        import pyfiglet
        print(pyfiglet.figlet_format('CAMTRAWL', font='cybermedium'))
    except ImportError:
        logging.debug('pyfiglet is not installed')
        print('========')
        print('CAMTRAWL')
        print('========')
    logging.info('Detector1 Config: ' + ub.repr2(detector1.config, nl=1))
    logging.info('Detector2 Config: ' + ub.repr2(detector2.config, nl=1))
    logging.info('Triangulate Config: ' + ub.repr2(triangulator.config, nl=1))
    logging.info('DRAWING = {!r}'.format(DRAWING))

    cal = ctalgo.StereoCalibration.from_file(cal_fpath)

    stream = StereoFrameStream(img_path1, img_path2)
    stream.preload()

    # HACK IN A BEGIN FRAME
    if len(stream) > 2200:
        stream.seek(2200)

    # ----
    # Run the algorithm
    # ----

    # n_frames = 2000
    # stream.aligned_frameids = stream.aligned_frameids[:stream.index]

    measure_fpath = join(out_dpath, 'measurements.csv')
    if exists(measure_fpath):
        if config['overwrite']:
            ub.delete(measure_fpath)
        else:
            raise IOError('Measurement path already exists')
    output_file = open(measure_fpath, 'a')

    if DRAWING:
        drawing_dpath = join(out_dpath, 'visual')
        if exists(drawing_dpath):
            if config['overwrite']:
                ub.delete(drawing_dpath)
            else:
                raise IOError('Output path already exists')
        ub.ensuredir(drawing_dpath)

    headers = ['current_frame', 'fishlen', 'range', 'error', 'dz', 'box_pts1',
               'box_pts2']
    output_file.write(','.join(headers) + '\n')
    output_file.flush()

    measurements = []

    logger.info('begin camtrawl iteration')

    import tqdm
    # prog = ub.ProgIter(iter(stream), total=len(stream), desc='camtrawl demo',
    #                    clearline=False, freq=1, adjust=False)
    prog = tqdm.tqdm(iter(stream), total=len(stream), desc='camtrawl demo',
                     leave=True)

    def csv_repr(d):
        if isinstance(d, np.ndarray):
            d = d.tolist()
        s = repr(d)
        return s.replace('\n', '').replace(',', ';').replace(' ', '')

    for frame_num, (frame_id, img1, img2) in enumerate(prog):
        logger.debug('frame_num = {!r}'.format(frame_num))

        detections1 = list(detector1.detect(img1))
        detections2 = list(detector2.detect(img2))
        masks1 = detector1._masks
        masks2 = detector2._masks

        any_detected = len(detections1) > 0 or len(detections2) > 0

        if any_detected:
            assignment, assign_data, cand_errors = triangulator.find_matches(
                cal, detections1, detections2)
            # Append assignments to the measurements
            for data in assign_data:
                data['current_frame'] = int(frame_id)
                measurements.append(data)
                line = ','.join([csv_repr(d) for d in ub.take(data, headers)])
                output_file.write(line + '\n')
                output_file.flush()
        else:
            cand_errors = None
            assignment, assign_data = None, None

        if DRAWING >= 2 or (DRAWING and any_detected):
            DRAWING = 3
            stacked = DrawHelper.draw_stereo_detections(img1, detections1, masks1,
                                                        img2, detections2, masks2,
                                                        assignment, assign_data,
                                                        cand_errors)
            if cv2.__version__.startswith('2'):
                cv2.putText(stacked,
                            text='frame #{}, id={}'.format(frame_num,
                                                           frame_id),
                            org=(10, 50),
                            fontFace=cv2.FONT_HERSHEY_SIMPLEX,
                            fontScale=1, color=(255, 0, 0),
                            thickness=2, lineType=cv2.cv.CV_AA)
            else:
                stacked = cv2.putText(stacked,
                                      text='frame #{}, id={}'.format(frame_num,
                                                                     frame_id),
                                      org=(10, 50),
                                      fontFace=cv2.FONT_HERSHEY_SIMPLEX,
                                      fontScale=1, color=(255, 0, 0),
                                      thickness=2, lineType=cv2.LINE_AA)
            cv2.imwrite(drawing_dpath + '/mask{}_draw.png'.format(frame_id), stacked)
    output_file.close()

    n_total = len(measurements)
    logger.info('n_total = {!r}'.format(n_total))
    if n_total:
        all_errors = np.array([d['error'] for d in measurements])
        all_lengths = np.array([d['fishlen'] for d in measurements])
        logger.info('ave_error = {:.2f} +- {:.2f}'.format(all_errors.mean(), all_errors.std()))
        logger.info('ave_lengths = {:.2f} +- {:.2f} '.format(all_lengths.mean(), all_lengths.std()))
    return measurements
Beispiel #34
0
    def _step(self):
        logger.debug(' ----- ' + self.__class__.__name__ + ' step')
        self.prog.step()

        if self.cal is None:
            self.cal = True
            logger.debug(' ----- ' + self.__class__.__name__ + ' grab cam1')
            # grab camera only if we dont have one yet
            camera1 = self.grab_input_using_trait('camera' + '1')
            logger.debug(' ----- ' + self.__class__.__name__ + ' grab cam2')
            camera2 = self.grab_input_using_trait('camera' + '2')

            def _cal_from_vital(vital_camera):
                vital_intrinsics = vital_camera.intrinsics
                cam_dict = {
                    'extrinsic': {
                        'om': vital_camera.rotation.rodrigues().ravel(),
                        'T': vital_camera.translation.ravel(),
                    },
                    'intrinsic': {
                        'cc': vital_intrinsics.principle_point.ravel(),
                        'fc': [vital_intrinsics.focal_length, vital_intrinsics.focal_length / vital_intrinsics.aspect_ratio],
                        'alpha_c': vital_intrinsics.skew,
                        'kc': vital_intrinsics.dist_coeffs.ravel(),
                    }
                }
                return cam_dict

            logger.debug(' ----- ' + self.__class__.__name__ + ' parse cameras')
            self.cal = ctalgo.StereoCalibration({
                'left': _cal_from_vital(camera1),
                'right': _cal_from_vital(camera2),
            })
            logger.debug(' ----- ' + self.__class__.__name__ + ' no more need for cameras')

        image_file_name1 = self.grab_input_using_trait('image_file_name1')  # .get_datum()
        image_file_name2 = self.grab_input_using_trait('image_file_name2')  # .get_datum()

        def _parse_frameid(fname):
            return int(os.path.basename(fname).split('_')[0])

        frame_id1 = _parse_frameid(image_file_name1)
        frame_id2 = _parse_frameid(image_file_name2)
        assert frame_id1 == frame_id2
        frame_id = frame_id1

        # frame_id1 = self.grab_input_using_trait('frame_id' + '1')
        # frame_id2 = self.grab_input_using_trait('frame_id' + '2')
        detection_set1 = self.grab_input_using_trait('detected_object_set' + '1')
        detection_set2 = self.grab_input_using_trait('detected_object_set' + '2')

        # Convert back to the format the algorithm understands
        def _detections_from_vital(detection_set):
            for vital_det in detection_set:
                bbox = vital_det.bounding_box()
                coords = [bbox.min_x(), bbox.min_y(),
                          bbox.max_x(), bbox.max_y()]
                mask = vital_det.mask.asarray()
                ct_bbox = ctalgo.BoundingBox(coords)
                ct_det = ctalgo.DetectedObject(ct_bbox, mask)
                yield ct_det
        detections1 = list(_detections_from_vital(detection_set1))
        detections2 = list(_detections_from_vital(detection_set2))

        assignment, assign_data, cand_errors = self.triangulator.find_matches(
            self.cal, detections1, detections2)

        logger.debug(' ----- ' + self.__class__.__name__ + ' found {} matches'.format(len(assign_data)))

        def csv_repr(d):
            if isinstance(d, np.ndarray):
                d = d.tolist()
            s = repr(d)
            return s.replace('\n', '').replace(',', ';').replace(' ', '')

        # Append assignments to the measurements
        for data in assign_data:
            data['current_frame'] = frame_id
            line = ','.join([csv_repr(d) for d in ub.take(data, self.headers)])
            self.output_file.write(line + '\n')

        if assign_data:
            self.output_file.flush()

        # push dummy image object (same as input) to output port
        # self.push_to_port_using_trait('out_image', vital.types.ImageContainer(in_img))
        self._base_step()