Source code for ibeis.viz.viz_nearest_descriptors

# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function, unicode_literals
import utool as ut
from six.moves import range
from plottool import draw_func2 as df2
from plottool.viz_featrow import draw_feat_row
from ibeis.viz import viz_helpers as vh
import plottool as pt  # NOQA
import six  # NOQA
(print, rrr, profile) = ut.inject2(__name__, '[viz_nndesc]', DEBUG=False)


[docs]def get_annotfeat_nn_index(ibs, qaid, qfx, qreq_=None): #raise NotImplementedError('this doesnt work anymore. Need to submit mc4 query with metadata on and then reextract the required params') #from . import match_chips3 as mc3 #ibs._init_query_requestor() if qreq_ is None: daid_list = ibs.get_valid_aids() qreq_ = ibs.new_query_request([qaid], daid_list) qreq_.load_indexer() # TODO: ensure lazy #if isinstance(qfx, six.string_types): special = (qfx == 'special') if special: qfx2_vecs = ibs.get_annot_vecs(qaid) else: qfx = int(qfx) qfx2_vecs = ibs.get_annot_vecs(qaid)[qfx:(qfx + 1)] K = qreq_.qparams.K Knorm = qreq_.qparams.Knorm if ut.VERBOSE: print('Knorm = %r' % (Knorm,)) qfx2_idx, qfx2_dist = qreq_.indexer.knn(qfx2_vecs, 10) if special: import numpy as np # Find a query feature with "good" results qfx2_daid = qreq_.indexer.get_nn_aids(qfx2_idx) qfx2_dnid = ibs.get_annot_nids(qfx2_daid) nid = ibs.get_annot_nids(qaid) #slice_ = slice(None) slice_ = slice(0, K + Knorm) flags = qfx2_dnid.T[slice_].T == nid flags = np.logical_and(flags, qfx2_daid[:, slice_] != qaid) flags_first = flags[:, 0:K] flags_last = flags[:, K:] num_gt_matches = flags_first.sum(axis=1) - flags_last.sum(axis=1) print('num_gt_matches = %r' % (num_gt_matches,)) print(num_gt_matches.max()) has_good_num = num_gt_matches >= num_gt_matches.max() - 1 candidate_qfxs = np.where(has_good_num)[0] cand_nids = qfx2_dnid[candidate_qfxs].T[slice_].T cand_flags = cand_nids == nid cand_dist = qfx2_dist[candidate_qfxs].T[slice_].T cand_dist_gt = cand_dist * cand_flags cand_dist_gf = cand_dist * ~cand_flags cand_score = cand_dist_gt.sum(axis=1) - cand_dist_gf.sum(axis=1) top_candxs = cand_score.argsort() print('cand_nids = %r' % (cand_nids,)) print('top_candxs = %r' % (top_candxs,)) cand_idx = top_candxs[1] #cand_idx = ut.take_percentile(top_candxs, .1)[-1] qfx = candidate_qfxs[cand_idx] print('qfx = %r' % (qfx,)) qfx2_dist = qfx2_dist[qfx:(qfx + 1)] qfx2_idx = qfx2_idx[qfx:(qfx + 1)] qfx2_daid = qreq_.indexer.get_nn_aids(qfx2_idx) qfx2_dfx = qreq_.indexer.get_nn_featxs(qfx2_idx) return qfx, qfx2_daid, qfx2_dfx, qfx2_dist, K, Knorm
[docs]def show_top_featmatches(qreq_, cm_list): """ Args: qreq_ (ibeis.QueryRequest): query request object with hyper-parameters cm_list (list): SeeAlso: python -m ibeis --tf TestResult.draw_feat_scoresep --show --db PZ_MTEST -t best:lnbnn_on=True,lnbnn_normalizer=normlnbnn-test -a default --sephack python -m ibeis --tf TestResult.draw_feat_scoresep --show --db PZ_Master1 -t best:lnbnn_on=True -a timectrl --sephack python -m ibeis --tf TestResult.draw_feat_scoresep --show --db PZ_MTEST -t best:lnbnn_on=True -a default:size=30 --sephack python -m ibeis --tf TestResult.draw_feat_scoresep --show --db PZ_MTEST -t best:K=1,Knorm=5,lnbnn_on=True -a default:size=30 --sephack python -m ibeis --tf TestResult.draw_feat_scoresep --show --db PZ_MTEST -t best:K=1,Knorm=3,lnbnn_on=True -a default --sephack CommandLine: python -m ibeis.viz.viz_nearest_descriptors --exec-show_top_featmatches --show Example: >>> # DISABLE_DOCTEST >>> from ibeis.viz.viz_nearest_descriptors import * # NOQA >>> import ibeis >>> cm_list, qreq_ = ibeis.testdata_cmlist(defaultdb='PZ_MTEST', >>> a=['default:has_none=mother,size=30']) >>> show_top_featmatches(qreq_, cm_list) >>> ut.quit_if_noshow() >>> import plottool as pt >>> ut.show_if_requested() """ # for cm in cm_list: # cm.score_csum(qreq_) import numpy as np import vtool as vt from functools import partial # Stack chipmatches ibs = qreq_.ibs infos = [cm.get_flat_fm_info() for cm in cm_list] flat_metadata = dict([(k, np.concatenate(v)) for k, v in ut.dict_stack2(infos).items()]) fsv_flat = flat_metadata['fsv'] flat_metadata['fs'] = fsv_flat.prod(axis=1) aids1 = flat_metadata['aid1'][:, None] aids2 = flat_metadata['aid2'][:, None] flat_metadata['aid_pairs'] = np.concatenate([aids1, aids2], axis=1) # Take sample of metadata sortx = flat_metadata['fs'].argsort()[::-1] num = len(cm_list) * 3 # num = 10 taker = partial(np.take, indices=sortx[:num], axis=0) flat_metadata_top = ut.map_dict_vals(taker, flat_metadata) aid1s, aid2s, fms = ut.dict_take(flat_metadata_top, ['aid1', 'aid2', 'fm']) annots = {} aids = np.unique(np.hstack((aid1s, aid2s))) annots = {aid: ibs.get_annot_lazy_dict(aid, config2_=qreq_.qparams) for aid in aids} label_lists = ibs.get_aidpair_truths(aid1s, aid2s) == ibs.const.TRUTH_MATCH patch_size = 64 def extract_patches(annots, aid, fxs): """ custom_func(lazydict, key, subkeys) for multigroup_lookup """ annot = annots[aid] kpts = annot['kpts'] rchip = annot['rchip'] kpts_m = kpts.take(fxs, axis=0) warped_patches, warped_subkpts = vt.get_warped_patches(rchip, kpts_m, patch_size=patch_size) return warped_patches data_lists = vt.multigroup_lookup(annots, [aid1s, aid2s], fms.T, extract_patches) import plottool as pt # NOQA pt.ensure_pylab_qt4() import ibeis_cnn inter = ibeis_cnn.draw_results.interact_patches( label_lists, data_lists, flat_metadata_top, chunck_sizes=(2, 4), ibs=ibs, hack_one_per_aid=False, sortby='fs', qreq_=qreq_) inter.show() #@ut.indent_func('[show_neardesc]')
[docs]def show_nearest_descriptors(ibs, qaid, qfx, fnum=None, stride=5, qreq_=None, **kwargs): r""" Args: ibs (ibeis.IBEISController): image analysis api qaid (int): query annotation id qfx (int): query feature index fnum (int): figure number stride (int): consecutive_distance_compare (bool): CommandLine: # Find a good match to inspect python -m ibeis.viz.interact.interact_matches --test-testdata_match_interact --show --db PZ_MTEST --qaid 3 # Now inspect it python -m ibeis.viz.viz_nearest_descriptors --test-show_nearest_descriptors --show --db PZ_MTEST --qaid 3 --qfx 879 python -m ibeis.viz.viz_nearest_descriptors --test-show_nearest_descriptors --show python -m ibeis.viz.viz_nearest_descriptors --test-show_nearest_descriptors --db PZ_MTEST --qaid 3 --qfx 879 --diskshow --save foo.png --dpi=256 SeeAlso: plottool.viz_featrow ~/code/plottool/plottool/viz_featrow.py Example: >>> # DISABLE_DOCTEST >>> from ibeis.viz.viz_nearest_descriptors import * # NOQA >>> import ibeis >>> # build test data >>> qreq_ = ibeis.testdata_qreq_() >>> ibs = ibeis.opendb('PZ_MTEST') >>> qaid = qreq_.qaids[0] >>> qfx = ut.get_argval('--qfx', type_=None, default=879) >>> fnum = None >>> stride = 5 >>> # execute function >>> skip = False >>> result = show_nearest_descriptors(ibs, qaid, qfx, fnum, stride, >>> draw_chip=True, >>> draw_warped=True, >>> draw_unwarped=False, >>> draw_desc=False, qreq_=qreq_) >>> # verify results >>> print(result) >>> pt.show_if_requested() """ import plottool as pt # NOQA consecutive_distance_compare = True draw_chip = kwargs.get('draw_chip', False) draw_desc = kwargs.get('draw_desc', True) draw_warped = kwargs.get('draw_warped', True) draw_unwarped = kwargs.get('draw_unwarped', True) #skip = kwargs.get('skip', True) # Plots the nearest neighbors of a given feature (qaid, qfx) if fnum is None: fnum = df2.next_fnum() try: # Flann NN query (qfx, qfx2_daid, qfx2_dfx, qfx2_dist, K, Knorm) = get_annotfeat_nn_index(ibs, qaid, qfx, qreq_=qreq_) # Adds metadata to a feature match def get_extract_tuple(aid, fx, k=-1): rchip = ibs.get_annot_chips(aid) kp = ibs.get_annot_kpts(aid)[fx] sift = ibs.get_annot_vecs(aid)[fx] if not ut.get_argflag('--texknormplot'): aidstr = vh.get_aidstrs(aid) nidstr = vh.get_nidstrs(ibs.get_annot_nids(aid)) id_str = ' ' + aidstr + ' ' + nidstr + ' fx=%r' % (fx,) else: id_str = nidstr = aidstr = '' info = '' if k == -1: if pt.is_texmode(): info = '\\vspace{1cm}' info += 'Query $\\mathbf{d}_i$' info += '\n\\_' info += '\n\\_' else: if len(id_str) > '': info = 'Query: %s' % (id_str,) else: info = 'Query' type_ = 'Query' elif k < K: type_ = 'Match' if ut.get_argflag('--texknormplot') and pt.is_texmode(): #info = 'Match:\n$k=%r$, $\\frac{||\\mathbf{d}_i - \\mathbf{d}_j||}{Z}=%.3f$' % (k, qfx2_dist[0, k]) info = '\\vspace{1cm}' info += 'Match: $\\mathbf{d}_{j_%r}$\n$\\textrm{dist}=%.3f$' % (k, qfx2_dist[0, k]) info += '\n$s_{\\tt{LNBNN}}=%.3f$' % (qfx2_dist[0, K + Knorm - 1] - qfx2_dist[0, k]) else: info = 'Match:%s\nk=%r, dist=%.3f' % (id_str, k, qfx2_dist[0, k]) info += '\nLNBNN=%.3f' % (qfx2_dist[0, K + Knorm - 1] - qfx2_dist[0, k]) elif k < Knorm + K: type_ = 'Norm' if ut.get_argflag('--texknormplot') and pt.is_texmode(): #info = 'Norm: $j_%r$\ndist=%.3f' % (id_str, k, qfx2_dist[0, k]) info = '\\vspace{1cm}' info += 'Norm: $j_%r$\n$\\textrm{dist}=%.3f$' % (k, qfx2_dist[0, k]) info += '\n\\_' else: info = 'Norm: %s\n$k=%r$, dist=$%.3f$' % (id_str, k, qfx2_dist[0, k]) else: raise Exception('[viz] problem k=%r') return (rchip, kp, sift, fx, aid, info, type_) extracted_list = [] # Remember the query sift feature extracted_list.append(get_extract_tuple(qaid, qfx, -1)) origsift = extracted_list[0][2] skipped = 0 for k in range(K + Knorm): #if qfx2_daid[0, k] == qaid and qfx2_dfx[0, k] == qfx: if qfx2_daid[0, k] == qaid: skipped += 1 continue tup = get_extract_tuple(qfx2_daid[0, k], qfx2_dfx[0, k], k) extracted_list.append(tup) # Draw the _select_ith_match plot nRows = len(extracted_list) if stride is None: stride = nRows # Draw selected feature matches prevsift = None px = 0 # plot offset px_shift = 0 # plot stride shift nExtracted = len(extracted_list) featrow_kw = dict( draw_chip=draw_chip, draw_desc=draw_desc, draw_warped=draw_warped, draw_unwarped=draw_unwarped, ) if ut.get_argflag('--texknormplot'): featrow_kw['ell_color'] = pt.ORANGE pass for listx, tup in enumerate(extracted_list): (rchip, kp, sift, fx, aid, info, type_) = tup if listx % stride == 0: # Create a temporary nRows and fnum in case we are splitting # up nearest neighbors into separate figures with stride _fnum = fnum + listx _nRows = min(nExtracted - listx, stride) px_shift = px df2.figure(fnum=_fnum, docla=True, doclf=True) px_ = px - px_shift px = draw_feat_row(rchip, fx, kp, sift, _fnum, _nRows, px=px_, prevsift=prevsift, origsift=origsift, aid=aid, info=info, type_=type_, **featrow_kw) px += px_shift if prevsift is None or consecutive_distance_compare: prevsift = sift df2.adjust_subplots_safe(hspace=.85, wspace=0, top=.95, bottom=.087, left=.05, right=.95) except Exception as ex: print('[viz] Error in show nearest descriptors') print(ex) raise
if __name__ == '__main__': """ CommandLine: python -m ibeis.viz.viz_nearest_descriptors python -m ibeis.viz.viz_nearest_descriptors --allexamples python -m ibeis.viz.viz_nearest_descriptors --allexamples --noface --nosrc """ import multiprocessing multiprocessing.freeze_support() # for win32 import utool as ut # NOQA ut.doctest_funcs()