def plot_keypoint_scales(hs, fnum=1): print('[dev] plot_keypoint_scales()') cx2_kpts = hs.feats.cx2_kpts cx2_nFeats = map(len, cx2_kpts) kpts = np.vstack(cx2_kpts) print('[dev] --- LaTeX --- ') _printopts = np.get_printoptions() np.set_printoptions(precision=3) print(pytex.latex_scalar(r'\# keypoints, ', len(kpts))) print(pytex.latex_mystats(r'\# keypoints per image', cx2_nFeats)) acd = kpts[:, 2:5].T scales = np.sqrt(acd[0] * acd[2]) scales = np.array(sorted(scales)) print(pytex.latex_mystats(r'keypoint scale', scales)) np.set_printoptions(**_printopts) print('[dev] ---/LaTeX --- ') # df2.figure(fnum=fnum, docla=True, title='sorted scales') df2.plot(scales) df2.adjust_subplots_safe() #ax = df2.gca() #ax.set_yscale('log') #ax.set_xscale('log') # fnum += 1 df2.figure(fnum=fnum, docla=True, title='hist scales') df2.show_histogram(scales, bins=20) df2.adjust_subplots_safe() #ax = df2.gca() #ax.set_yscale('log') #ax.set_xscale('log') return fnum
def show_image(back, gx, sel_cxs=[], figtitle='Image View', **kwargs): fnum = FNUMS['image'] did_exist = df2.plt.fignum_exists(fnum) df2.figure(fnum=fnum, docla=True, doclf=True) interact.interact_image(back.hs, gx, sel_cxs, back.select_cx, fnum=fnum, figtitle=figtitle) if not did_exist: back.layout_figures()
def show_single_query(back, res, cx, **kwargs): # Define callback for show_analysis fnum = FNUMS['inspect'] did_exist = df2.plt.fignum_exists(fnum) df2.figure(fnum=fnum, docla=True, doclf=True) interact.interact_chipres(back.hs, res, cx=cx, fnum=fnum) if not did_exist: back.layout_figures()
def viz_localmax(signal1d): #signal1d = np.array(hist) from hsviz import draw_func2 as df2 signal1d = np.array(signal1d) maxpos = np.array(localmax(signal1d)) x_data = range(len(signal1d)) y_data = signal1d df2.figure('localmax vizualization') df2.plot(x_data, y_data) df2.plot(maxpos, signal1d[maxpos], 'ro') df2.update()
def show_chip(back, cx, **kwargs): fnum = FNUMS['chip'] did_exist = df2.plt.fignum_exists(fnum) df2.figure(fnum=fnum, docla=True, doclf=True) INTERACTIVE_CHIPS = True # This should always be True if INTERACTIVE_CHIPS: interact_fn = interact.interact_chip interact_fn(back.hs, cx, fnum=fnum, figtitle='Chip View') else: viz.show_chip(back.hs, cx, fnum=fnum, figtitle='Chip View') if not did_exist: back.layout_figures()
def top_matching_features(res, axnum=None, match_type=''): cx2_fs = res.cx2_fs_V cx_fx_fs_list = [] for cx in xrange(len(cx2_fs)): fx2_fs = cx2_fs[cx] for fx in xrange(len(fx2_fs)): fs = fx2_fs[fx] cx_fx_fs_list.append((cx, fx, fs)) cx_fx_fs_sorted = np.array(sorted(cx_fx_fs_list, key=lambda x: x[2])[::-1]) sorted_score = cx_fx_fs_sorted[:, 2] df2.figure(0) df2.plot(sorted_score)
def viz_chipgraph(hs, graph, fnum=1, with_images=False): # Adapated from # https://gist.github.com/shobhit/3236373 print('[encounter] drawing chip graph') df2.figure(fnum=fnum, pnum=(1, 1, 1)) ax = df2.gca() #pos = netx.spring_layout(graph) pos = netx.graphviz_layout(graph) netx.draw(graph, pos=pos, ax=ax) if with_images: cx_list = graph.nodes() pos_list = [pos[cx] for cx in cx_list] thumb_list = hs.get_thumb(cx_list, 16, 16) draw_images_at_positions(thumb_list, pos_list)
def dump_orgres_matches(allres, orgres_type): orgres = allres.__dict__[orgres_type] hs = allres.hs qcx2_res = allres.qcx2_res # loop over each query / result of interest for qcx, cx, score, rank in orgres.iter(): query_gname, _ = os.path.splitext(hs.tables.gx2_gname[hs.tables.cx2_gx[qcx]]) result_gname, _ = os.path.splitext(hs.tables.gx2_gname[hs.tables.cx2_gx[cx]]) res = qcx2_res[qcx] df2.figure(fnum=1, plotnum=121) df2.show_matches_annote_res(res, hs, cx, SV=False, fnum=1, plotnum=121) df2.show_matches_annote_res(res, hs, cx, SV=True, fnum=1, plotnum=122) big_title = 'score=%.2f_rank=%d_q=%s_r=%s' % (score, rank, query_gname, result_gname) df2.set_figtitle(big_title) viz.__dump_or_browse(allres, orgres_type + '_matches' + allres.title_suffix)
def show_query_result(back, res, tx=None, **kwargs): if tx is not None: fnum = FNUMS['inspect'] did_exist = df2.plt.fignum_exists(fnum) # Interact with the tx\th top index res.interact_top_chipres(back.hs, tx) else: fnum = FNUMS['res'] did_exist = df2.plt.fignum_exists(fnum) df2.figure(fnum=fnum, docla=True, doclf=True) if back.hs.prefs.display_cfg.showanalysis: # Define callback for show_analysis res.show_analysis(back.hs, fnum=fnum, figtitle=' Analysis View') else: res.show_top(back.hs, fnum=fnum, figtitle='Query View ') if not did_exist: back.layout_figures()
def dump_orgres_matches(allres, orgres_type): orgres = allres.__dict__[orgres_type] hs = allres.hs qcx2_res = allres.qcx2_res # loop over each query / result of interest for qcx, cx, score, rank in orgres.iter(): query_gname, _ = os.path.splitext( hs.tables.gx2_gname[hs.tables.cx2_gx[qcx]]) result_gname, _ = os.path.splitext( hs.tables.gx2_gname[hs.tables.cx2_gx[cx]]) res = qcx2_res[qcx] df2.figure(fnum=1, plotnum=121) df2.show_matches_annote_res(res, hs, cx, SV=False, fnum=1, plotnum=121) df2.show_matches_annote_res(res, hs, cx, SV=True, fnum=1, plotnum=122) big_title = 'score=%.2f_rank=%d_q=%s_r=%s' % (score, rank, query_gname, result_gname) df2.set_figtitle(big_title) viz.__dump_or_browse(allres, orgres_type + '_matches' + allres.title_suffix)
def dump_feature_pair_analysis(allres): print('[rr2] Doing: feature pair analysis') # TODO: Measure score consistency over a spatial area. # Measures entropy of matching vs nonmatching descriptors # Measures scale of m vs nm desc hs = allres.hs qcx2_res = allres.qcx2_res import scipy def _hist_prob_x(desc, bw_factor): # Choose number of bins based on the bandwidth bin_range = (0, 256) # assuming input is uint8 bins = bin_range[1] // bw_factor bw_factor = bin_range[1] / bins # Compute the probabilty mass function, each w.r.t a single descriptor hist_params = dict(bins=bins, range=bin_range, density=True) hist_func = np.histogram desc_pmf = [hist_func(d, **hist_params)[0] for d in desc] # Compute the probability that you saw what you saw # TODO: could use linear interpolation for a bit more robustness here bin_vals = [ np.array(np.floor(d / bw_factor), dtype=np.uint8) for d in desc ] hist_prob_x = [pmf[vals] for pmf, vals in zip(desc_pmf, bin_vals)] return hist_prob_x def _gkde_prob_x(desc, bw_factor): # Estimate the probabilty density function, each w.r.t a single descriptor gkde_func = scipy.stats.gaussian_kde desc_pdf = [gkde_func(d, bw_factor) for d in desc] gkde_prob_x = [pdf(d) for pdf, d in zip(desc_pdf, desc)] return gkde_prob_x def descriptor_entropy(desc, bw_factor=4): 'computes the shannon entropy of each descriptor in desc' # Compute shannon entropy = -sum(p(x)*log(p(x))) prob_x = _hist_prob_x(desc, bw_factor) entropy = [-(px * np.log2(px)).sum() for px in prob_x] return entropy # Load features if we need to if hs.feats.cx2_desc.size == 0: print(' * forcing load of descriptors') hs.load_features() cx2_desc = hs.feats.cx2_desc cx2_kpts = hs.feats.cx2_kpts def measure_feat_pairs(allres, orgtype='top_true'): print('Measure ' + orgtype + ' pairs') orgres = allres.__dict__[orgtype] entropy_list = [] scale_list = [] score_list = [] lbl = 'Measuring ' + orgtype + ' pair ' fmt_str = helpers.make_progress_fmt_str(len(orgres), lbl) rank_skips = [] gt_skips = [] for ix, (qcx, cx, score, rank) in enumerate(orgres.iter()): helpers.print_(fmt_str % (ix + 1, )) # Skip low ranks if rank > 5: rank_skips.append(qcx) continue other_cxs = hs.get_other_indexed_cxs(qcx) # Skip no groundtruth if len(other_cxs) == 0: gt_skips.append(qcx) continue res = qcx2_res[qcx] # Get matching feature indexes fm = res.cx2_fm[cx] # Get their scores fs = res.cx2_fs[cx] # Get matching descriptors printDBG('\nfm.shape=%r' % (fm.shape, )) desc1 = cx2_desc[qcx][fm[:, 0]] desc2 = cx2_desc[cx][fm[:, 1]] # Get matching keypoints kpts1 = cx2_kpts[qcx][fm[:, 0]] kpts2 = cx2_kpts[cx][fm[:, 1]] # Get their scale scale1_m = sv2.keypoint_scale(kpts1) scale2_m = sv2.keypoint_scale(kpts2) # Get their entropy entropy1 = descriptor_entropy(desc1, bw_factor=1) entropy2 = descriptor_entropy(desc2, bw_factor=1) # Append to results entropy_tup = np.array(zip(entropy1, entropy2)) scale_tup = np.array(zip(scale1_m, scale2_m)) entropy_tup = entropy_tup.reshape(len(entropy_tup), 2) scale_tup = scale_tup.reshape(len(scale_tup), 2) entropy_list.append(entropy_tup) scale_list.append(scale_tup) score_list.append(fs) print('Skipped %d total.' % (len(rank_skips) + len(gt_skips), )) print('Skipped %d for rank > 5, %d for no gt' % ( len(rank_skips), len(gt_skips), )) print(np.unique(map(len, entropy_list))) def evstack(tup): return np.vstack(tup) if len(tup) > 0 else np.empty((0, 2)) def ehstack(tup): return np.hstack(tup) if len(tup) > 0 else np.empty((0, 2)) entropy_pairs = evstack(entropy_list) scale_pairs = evstack(scale_list) scores = ehstack(score_list) print('\n * Measured %d pairs' % len(entropy_pairs)) return entropy_pairs, scale_pairs, scores tt_entropy, tt_scale, tt_scores = measure_feat_pairs(allres, 'top_true') tf_entropy, tf_scale, tf_scores = measure_feat_pairs(allres, 'top_false') # Measure ratios def measure_ratio(arr): return arr[:, 0] / arr[:, 1] if len(arr) > 0 else np.array([]) tt_entropy_ratio = measure_ratio(tt_entropy) tf_entropy_ratio = measure_ratio(tf_entropy) tt_scale_ratio = measure_ratio(tt_scale) tf_scale_ratio = measure_ratio(tf_scale) title_suffix = allres.title_suffix # Entropy vs Score df2.figure(fnum=1, docla=True) df2.figure(fnum=1, plotnum=(2, 2, 1)) df2.plot2(tt_entropy[:, 0], tt_scores, 'gx', 'entropy1', 'score', 'Top True') df2.figure(fnum=1, plotnum=(2, 2, 2)) df2.plot2(tf_entropy[:, 0], tf_scores, 'rx', 'entropy1', 'score', 'Top False') df2.figure(fnum=1, plotnum=(2, 2, 3)) df2.plot2(tt_entropy[:, 1], tt_scores, 'gx', 'entropy2', 'score', 'Top True') df2.figure(fnum=1, plotnum=(2, 2, 4)) df2.plot2(tf_entropy[:, 1], tf_scores, 'rx', 'entropy2', 'score', 'Top False') df2.set_figtitle('Entropy vs Score -- ' + title_suffix) viz.__dump_or_browse(allres, 'pair_analysis') # Scale vs Score df2.figure(fnum=2, plotnum=(2, 2, 1), docla=True) df2.plot2(tt_scale[:, 0], tt_scores, 'gx', 'scale1', 'score', 'Top True') df2.figure(fnum=2, plotnum=(2, 2, 2)) df2.plot2(tf_scale[:, 0], tf_scores, 'rx', 'scale1', 'score', 'Top False') df2.figure(fnum=2, plotnum=(2, 2, 3)) df2.plot2(tt_scale[:, 1], tt_scores, 'gx', 'scale2', 'score', 'Top True') df2.figure(fnum=2, plotnum=(2, 2, 4)) df2.plot2(tf_scale[:, 1], tf_scores, 'rx', 'scale2', 'score', 'Top False') df2.set_figtitle('Scale vs Score -- ' + title_suffix) viz.__dump_or_browse(allres, 'pair_analysis') # Entropy Ratio vs Score df2.figure(fnum=3, plotnum=(1, 2, 1), docla=True) df2.plot2(tt_entropy_ratio, tt_scores, 'gx', 'entropy-ratio', 'score', 'Top True') df2.figure(fnum=3, plotnum=(1, 2, 2)) df2.plot2(tf_entropy_ratio, tf_scores, 'rx', 'entropy-ratio', 'score', 'Top False') df2.set_figtitle('Entropy Ratio vs Score -- ' + title_suffix) viz.__dump_or_browse(allres, 'pair_analysis') # Scale Ratio vs Score df2.figure(fnum=4, plotnum=(1, 2, 1), docla=True) df2.plot2(tt_scale_ratio, tt_scores, 'gx', 'scale-ratio', 'score', 'Top True') df2.figure(fnum=4, plotnum=(1, 2, 2)) df2.plot2(tf_scale_ratio, tf_scores, 'rx', 'scale-ratio', 'score', 'Top False') df2.set_figtitle('Entropy Ratio vs Score -- ' + title_suffix) viz.__dump_or_browse(allres, 'pair_analysis')
def show_nx(back, nx, sel_cxs=[], **kwargs): # Define callback for show_analysis fnum = FNUMS['name'] df2.figure(fnum=fnum, docla=True, doclf=True) interact.interact_name(back.hs, nx, sel_cxs, back.select_cx, fnum=fnum)
def show_splash(back, fnum, view='Nice', **kwargs): if df2.plt.fignum_exists(fnum): df2.figure(fnum=fnum, docla=True, doclf=True) viz.show_splash(fnum=fnum) df2.set_figtitle('%s View' % view)
print('[back] database (cid=%r)' % db_cid) print('[back] database (cx = %r)' % db_cx) try: query_res = hs.query(query_cx) except Exception as ex: # TODO Catch actually exceptions here print('[back] ex = %r' % ex) raise #-----function: def show_single_query(back, res, cx, **kwargs): FNUMS = dict(image=1, chip=2, res=3, inspect=4, special=5, name=6) viz.register_FNUMS(FNUMS) fnum = FNUMS['inspect'] did_exist = df2.plt.fignum_exists(fnum) df2.figure(fnum=fnum, docla=True, doclf=True) #------- function: interact.interact_chipres(back.hs, res, cx=cx, fnum=fnum) annote_ptr = [0] pnum=(1, 1, 1) xywh2_ptr = [None] #-------function: def _chipmatch_view(pnum=(1, 1, 1), **kwargs): mode = annote_ptr[0] draw_ell = mode >= 1 draw_lines = mode == 2 annote_ptr[0] = (annote_ptr[0] + 1) % 3 df2.figure(fnum=fnum, docla=True, doclf=True) # TODO RENAME This to remove res and rectify with show_chipres tup = res_show_chipres(query_res, hs, db_cx, fnum=fnum, pnum=pnum,
def dump_feature_pair_analysis(allres): print('[rr2] Doing: feature pair analysis') # TODO: Measure score consistency over a spatial area. # Measures entropy of matching vs nonmatching descriptors # Measures scale of m vs nm desc hs = allres.hs qcx2_res = allres.qcx2_res import scipy def _hist_prob_x(desc, bw_factor): # Choose number of bins based on the bandwidth bin_range = (0, 256) # assuming input is uint8 bins = bin_range[1] // bw_factor bw_factor = bin_range[1] / bins # Compute the probabilty mass function, each w.r.t a single descriptor hist_params = dict(bins=bins, range=bin_range, density=True) hist_func = np.histogram desc_pmf = [hist_func(d, **hist_params)[0] for d in desc] # Compute the probability that you saw what you saw # TODO: could use linear interpolation for a bit more robustness here bin_vals = [np.array(np.floor(d / bw_factor), dtype=np.uint8) for d in desc] hist_prob_x = [pmf[vals] for pmf, vals in zip(desc_pmf, bin_vals)] return hist_prob_x def _gkde_prob_x(desc, bw_factor): # Estimate the probabilty density function, each w.r.t a single descriptor gkde_func = scipy.stats.gaussian_kde desc_pdf = [gkde_func(d, bw_factor) for d in desc] gkde_prob_x = [pdf(d) for pdf, d in zip(desc_pdf, desc)] return gkde_prob_x def descriptor_entropy(desc, bw_factor=4): 'computes the shannon entropy of each descriptor in desc' # Compute shannon entropy = -sum(p(x)*log(p(x))) prob_x = _hist_prob_x(desc, bw_factor) entropy = [-(px * np.log2(px)).sum() for px in prob_x] return entropy # Load features if we need to if hs.feats.cx2_desc.size == 0: print(' * forcing load of descriptors') hs.load_features() cx2_desc = hs.feats.cx2_desc cx2_kpts = hs.feats.cx2_kpts def measure_feat_pairs(allres, orgtype='top_true'): print('Measure ' + orgtype + ' pairs') orgres = allres.__dict__[orgtype] entropy_list = [] scale_list = [] score_list = [] lbl = 'Measuring ' + orgtype + ' pair ' fmt_str = helpers.make_progress_fmt_str(len(orgres), lbl) rank_skips = [] gt_skips = [] for ix, (qcx, cx, score, rank) in enumerate(orgres.iter()): helpers.print_(fmt_str % (ix + 1,)) # Skip low ranks if rank > 5: rank_skips.append(qcx) continue other_cxs = hs.get_other_indexed_cxs(qcx) # Skip no groundtruth if len(other_cxs) == 0: gt_skips.append(qcx) continue res = qcx2_res[qcx] # Get matching feature indexes fm = res.cx2_fm[cx] # Get their scores fs = res.cx2_fs[cx] # Get matching descriptors printDBG('\nfm.shape=%r' % (fm.shape,)) desc1 = cx2_desc[qcx][fm[:, 0]] desc2 = cx2_desc[cx][fm[:, 1]] # Get matching keypoints kpts1 = cx2_kpts[qcx][fm[:, 0]] kpts2 = cx2_kpts[cx][fm[:, 1]] # Get their scale scale1_m = sv2.keypoint_scale(kpts1) scale2_m = sv2.keypoint_scale(kpts2) # Get their entropy entropy1 = descriptor_entropy(desc1, bw_factor=1) entropy2 = descriptor_entropy(desc2, bw_factor=1) # Append to results entropy_tup = np.array(zip(entropy1, entropy2)) scale_tup = np.array(zip(scale1_m, scale2_m)) entropy_tup = entropy_tup.reshape(len(entropy_tup), 2) scale_tup = scale_tup.reshape(len(scale_tup), 2) entropy_list.append(entropy_tup) scale_list.append(scale_tup) score_list.append(fs) print('Skipped %d total.' % (len(rank_skips) + len(gt_skips),)) print('Skipped %d for rank > 5, %d for no gt' % (len(rank_skips), len(gt_skips),)) print(np.unique(map(len, entropy_list))) def evstack(tup): return np.vstack(tup) if len(tup) > 0 else np.empty((0, 2)) def ehstack(tup): return np.hstack(tup) if len(tup) > 0 else np.empty((0, 2)) entropy_pairs = evstack(entropy_list) scale_pairs = evstack(scale_list) scores = ehstack(score_list) print('\n * Measured %d pairs' % len(entropy_pairs)) return entropy_pairs, scale_pairs, scores tt_entropy, tt_scale, tt_scores = measure_feat_pairs(allres, 'top_true') tf_entropy, tf_scale, tf_scores = measure_feat_pairs(allres, 'top_false') # Measure ratios def measure_ratio(arr): return arr[:, 0] / arr[:, 1] if len(arr) > 0 else np.array([]) tt_entropy_ratio = measure_ratio(tt_entropy) tf_entropy_ratio = measure_ratio(tf_entropy) tt_scale_ratio = measure_ratio(tt_scale) tf_scale_ratio = measure_ratio(tf_scale) title_suffix = allres.title_suffix # Entropy vs Score df2.figure(fnum=1, docla=True) df2.figure(fnum=1, plotnum=(2, 2, 1)) df2.plot2(tt_entropy[:, 0], tt_scores, 'gx', 'entropy1', 'score', 'Top True') df2.figure(fnum=1, plotnum=(2, 2, 2)) df2.plot2(tf_entropy[:, 0], tf_scores, 'rx', 'entropy1', 'score', 'Top False') df2.figure(fnum=1, plotnum=(2, 2, 3)) df2.plot2(tt_entropy[:, 1], tt_scores, 'gx', 'entropy2', 'score', 'Top True') df2.figure(fnum=1, plotnum=(2, 2, 4)) df2.plot2(tf_entropy[:, 1], tf_scores, 'rx', 'entropy2', 'score', 'Top False') df2.set_figtitle('Entropy vs Score -- ' + title_suffix) viz.__dump_or_browse(allres, 'pair_analysis') # Scale vs Score df2.figure(fnum=2, plotnum=(2, 2, 1), docla=True) df2.plot2(tt_scale[:, 0], tt_scores, 'gx', 'scale1', 'score', 'Top True') df2.figure(fnum=2, plotnum=(2, 2, 2)) df2.plot2(tf_scale[:, 0], tf_scores, 'rx', 'scale1', 'score', 'Top False') df2.figure(fnum=2, plotnum=(2, 2, 3)) df2.plot2(tt_scale[:, 1], tt_scores, 'gx', 'scale2', 'score', 'Top True') df2.figure(fnum=2, plotnum=(2, 2, 4)) df2.plot2(tf_scale[:, 1], tf_scores, 'rx', 'scale2', 'score', 'Top False') df2.set_figtitle('Scale vs Score -- ' + title_suffix) viz.__dump_or_browse(allres, 'pair_analysis') # Entropy Ratio vs Score df2.figure(fnum=3, plotnum=(1, 2, 1), docla=True) df2.plot2(tt_entropy_ratio, tt_scores, 'gx', 'entropy-ratio', 'score', 'Top True') df2.figure(fnum=3, plotnum=(1, 2, 2)) df2.plot2(tf_entropy_ratio, tf_scores, 'rx', 'entropy-ratio', 'score', 'Top False') df2.set_figtitle('Entropy Ratio vs Score -- ' + title_suffix) viz.__dump_or_browse(allres, 'pair_analysis') # Scale Ratio vs Score df2.figure(fnum=4, plotnum=(1, 2, 1), docla=True) df2.plot2(tt_scale_ratio, tt_scores, 'gx', 'scale-ratio', 'score', 'Top True') df2.figure(fnum=4, plotnum=(1, 2, 2)) df2.plot2(tf_scale_ratio, tf_scores, 'rx', 'scale-ratio', 'score', 'Top False') df2.set_figtitle('Entropy Ratio vs Score -- ' + title_suffix) viz.__dump_or_browse(allres, 'pair_analysis')