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')
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
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
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
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
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
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
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)
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
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
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
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
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()
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
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
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
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)
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)]
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))
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
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)
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))
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)))
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
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))
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
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
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
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
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
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____')
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
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()