# -*- coding: utf-8 -*-
"""
special pipeline for vsone specific functions
Current Issues:
* getting feature distinctiveness is too slow, we can either try a different
model, or precompute feature distinctiveness.
- we can reduce the size of the vsone shortlist
TODOLIST:
* Unconstrained is a terrible name. It is constrianed by the ratio
* Precompute distinctivness
#* keep feature matches from vsmany (allow fm_B)
#* Each keypoint gets
# - foregroundness
# - global distinctivness (databasewide) LNBNN
# - local distinctivness (imagewide) RATIO
# - regional match quality (descriptor based) COS
* Asymetric weight scoring
* FIX BUGS IN score_chipmatch_nsum FIRST THING TOMORROW.
dict keys / vals are being messed up. very inoccuous
Visualization to "prove" that vsone works
TestCases:
PZ_Master0 - aids 1801, 4792 - near-miss
TestFuncs:
>>> # VsMany Only
python -m ibeis.algo.hots.vsone_pipeline --test-show_post_vsmany_vser --show
>>> # VsOne Only
python -m ibeis.algo.hots.vsone_pipeline --test-vsone_reranking --show --no-vsmany_coeff
>>> # VsOne + VsMany
python -m ibeis.algo.hots.vsone_pipeline --test-vsone_reranking --show
>>> # Rerank Vsone Test Harness
python -c "import utool as ut; ut.write_modscript_alias('Tvs1RR.sh', 'dev.py', '--allgt --db PZ_MTEST --index 1:40:2')" # NOQA
sh Tvs1RR.sh -t custom:rrvsone_on=True custom custom:rrvsone_on=True
sh Tvs1RR.sh -t custom custom:rrvsone_on=True --print-scorediff-mat-stats
sh Tvs1RR.sh -t custom:rrvsone_on=True custom:rrvsone_on=True, --print-confusion-stats --print-scorediff-mat-stats
--print-scorediff-mat-stats --print-confusion-stats
"""
from __future__ import absolute_import, division, print_function, unicode_literals
import six # NOQA
import numpy as np
import vtool as vt
from ibeis.algo.hots import hstypes
from ibeis.algo.hots import chip_match
from ibeis.algo.hots import scoring
import functools
from vtool import matching
from ibeis.algo.hots import _pipeline_helpers as plh # NOQA
import utool as ut
from six.moves import zip, range, reduce # NOQA
print, rrr, profile = ut.inject2(__name__, '[vsonepipe]')
#from collections import namedtuple
[docs]def show_post_vsmany_vser():
r""" TESTFUNC just show the input data
CommandLine:
python -m ibeis.algo.hots.vsone_pipeline --test-show_post_vsmany_vser --show --homog
python -m ibeis.algo.hots.vsone_pipeline --test-show_post_vsmany_vser --show --csum --homog
Example:
>>> from ibeis.algo.hots.vsone_pipeline import * # NOQA
>>> show_post_vsmany_vser()
"""
import plottool as pt
ibs, qreq_, cm_list_SVER, qaid_list = plh.testdata_pre_vsonerr()
# HACK TO PRESCORE
prepare_vsmany_chipmatch(qreq_, cm_list_SVER)
show_all_ranked_matches(qreq_, cm_list_SVER, figtitle='vsmany post sver')
pt.show_if_requested()
[docs]def get_normalized_score_column(fsv, colx, min_, max_, power):
fs = fsv.T[colx].T.copy()
fs = fs if min_ == 0 and max_ == 1 else vt.clipnorm(fs, min_, max_, out=fs)
fs = fs if power == 1 else np.power(fs, power, out=fs)
return fs
[docs]def prepare_vsmany_chipmatch(qreq_, cm_list_SVER):
""" gets normalized vsmany priors
Example:
>>> # SLOW_DOCTEST
>>> # (IMPORTANT)
>>> from ibeis.algo.hots.vsone_pipeline import * # NOQA
>>> ibs, qreq_, cm_list_SVER, qaid_list = plh.testdata_pre_vsonerr()
>>> prepare_vsmany_chipmatch(qreq_, cm_list_SVER)
"""
# Hack: populate aid2 score field in cmtup_old using prescore
# grab normalized lnbnn scores
fs_lnbnn_min = qreq_.qparams.fs_lnbnn_min
fs_lnbnn_max = qreq_.qparams.fs_lnbnn_max
fs_lnbnn_power = qreq_.qparams.fs_lnbnn_power
_args = (fs_lnbnn_min, fs_lnbnn_max, fs_lnbnn_power)
for cm in cm_list_SVER:
lnbnn_index = cm.fsv_col_lbls.index('lnbnn')
vsmany_fs_list = [
get_normalized_score_column(vsmany_fsv, lnbnn_index, *_args)
for vsmany_fsv in cm.fsv_list]
cm.fsv_list = matching.ensure_fsv_list(vsmany_fs_list)
cm.fs_list = vsmany_fs_list
#@profile
[docs]def vsone_reranking(qreq_, cm_list_SVER, verbose=False):
r"""
Driver function
CommandLine:
python -m ibeis.algo.hots.vsone_pipeline --test-vsone_reranking --show
python -m ibeis.algo.hots.vsone_pipeline --test-vsone_reranking --show
python -m ibeis.algo.hots.vsone_pipeline --test-vsone_reranking
utprof.py -m ibeis.algo.hots.vsone_pipeline --test-vsone_reranking
Example:
>>> # SLOW_DOCTEST
>>> # (IMPORTANT)
>>> from ibeis.algo.hots.vsone_pipeline import * # NOQA
>>> ibs, qreq_, cm_list_SVER, qaid_list = plh.testdata_pre_vsonerr()
>>> print(qreq_.qparams.rrvsone_cfgstr)
>>> # cm_list_SVER = ut.dict_subset(cm_list_SVER, [6])
>>> cm_list_VSONE = vsone_reranking(qreq_, cm_list_SVER)
>>> #cm_list = cm_list_VSONE
>>> ut.quit_if_noshow()
>>> import plottool as pt
>>> figtitle = 'FIXME USE SUBSET OF CFGDICT' # ut.dict_str(rrvsone_cfgdict, newlines=False)
>>> show_all_ranked_matches(qreq_, cm_list_VSONE, figtitle=figtitle)
>>> pt.show_if_requested()
"""
config = qreq_.qparams
# Filter down to a shortlist
nNameShortlist = qreq_.qparams.nNameShortlistVsone
nAnnotPerName = qreq_.qparams.nAnnotPerNameVsone
scoring.score_chipmatch_list(qreq_, cm_list_SVER, 'nsum')
prepare_vsmany_chipmatch(qreq_, cm_list_SVER)
cm_shortlist = scoring.make_chipmatch_shortlists(qreq_, cm_list_SVER,
nNameShortlist,
nAnnotPerName)
# Execute vsone reranking
_prog = functools.partial(ut.ProgressIter, nTotal=len(cm_shortlist),
lbl='VSONE RERANKING', freq=1)
cm_list_VSONE = [
single_vsone_rerank(qreq_, prior_cm, config)
for prior_cm in _prog(cm_shortlist)
]
return cm_list_VSONE
[docs]def unsupervised_similarity(ibs, aids):
"""
http://repository.upenn.edu/cgi/viewcontent.cgi?article=1101&context=cis_papers
Ignore:
>>> from ibeis.algo.hots.vsone_pipeline import * # NOQA
>>> import ibeis
>>> #ibs, aids = ibeis.testdata_aids('wd_peter2', 'timectrl:pername=2,view=left,view_ext=1,exclude_reference=True')
>>> ibs, aids = ibeis.testdata_aids('wd_peter2', 'timectrl:pername=2,view=left,view_ext=0,exclude_reference=True')
>>> ibs, aids = ibeis.testdata_aids('PZ_MTEST', 'timectrl:pername=4,view=left,view_ext=0,exclude_reference=True')
"""
ut.ensure_pylab_qt4()
# qreq_ = ibs.new_query_request(aids, aids, cfgdict=dict(affine_invariance=False))
# qreq_ = ibs.new_query_request(aids, aids, cfgdict=dict())
qreq_ = ibs.new_query_request(aids, aids, cfgdict=dict(affine_invariance=True, augment_queryside_hack=True))
qconfig2_ = qreq_.get_external_query_config2()
dconfig2_ = qreq_.get_external_query_config2()
qaid, daid = aids[2:4]
# [0:8]
aids = aids
#aids = aids[0:6]
nids = np.array(ibs.get_annot_nids(aids))
pair_dict = ut.ddict(dict)
#score_mat = np.full((len(aids), len(aids)), np.inf)
idx_list = list(ut.self_prodx(range(len(aids))))
#idx_list = list(ut.iprod(range(len(aids)), range(len(aids))))
cfgdict = {'ratio_thresh': 1.0, 'sver_xy_thresh': .001, 'scale_thresh': 1.5}
cfgdict = {'ratio_thresh': 1.0, 'sver_xy_thresh': .001, 'scale_thresh': 1.5, 'symmetric': False}
verbose = None
qx, dx = idx_list[0]
for qx, dx in ut.ProgressIter(idx_list):
qaid, daid = ut.take(aids, [qx, dx])
metadata = ibs.get_annot_pair_lazy_dict(qaid, daid, qconfig2_, dconfig2_)
flann_params = {'algorithm': 'kdtree', 'trees': 8}
# truth = (nids[qx] == nids[dx])
metadata['annot1']['flann'] = vt.flann_cache(metadata['annot1']['vecs'], flann_params=flann_params)
# metadata['flann2'] = vt.flann_cache(metadata['vecs2'], flann_params=flann_params)
match = vt.vsone_matching2(metadata, cfgdict=cfgdict, verbose=verbose)
pair_dict[(qx, dx)] = match
from skimage.future import graph
g = graph.rag.RAG()
score_mat = np.zeros((len(aids), len(aids)))
# Populate weight matrix off-diagonal
for qx, dx in ut.ProgressIter(idx_list):
qaid, daid = ut.take(aids, [qx, dx])
match = pair_dict[(qx, dx)]
print(match)
score = match.matches['TOP+SV'].fs.sum()
score_mat[qx, dx] = score
g.add_edge(qx, dx, weight=score)
(nids[qx] == nids[dx])
# Populate weight matrix on-diagonal
W = score_mat
D = np.diag(W.sum(axis=0)) # NOQA
from plottool.interactions import ExpandableInteraction
import plottool as pt
import networkx as nx
if False:
pos = nx.circular_layout(g)
pt.figure()
nx.draw(g, pos)
nx.draw_networkx_edge_labels(g, pos, font_size=10)
if True:
# NORMALIZED CUT STUFF
# https://github.com/IAS-ZHAW/machine_learning_scripts/blob/master/mlscripts/ml/normalized_min_cut.py
#labels = np.arange(len(aids))
#graph.cut_normalized(labels, g)
m_adjacency = np.array(nx.to_numpy_matrix(g))
D = np.diag(np.sum(m_adjacency, 0))
D_half_inv = np.diag(1.0 / np.sqrt(np.sum(m_adjacency, 0)))
M = np.dot(D_half_inv, np.dot((D - m_adjacency), D_half_inv))
(w, v) = np.linalg.eig(M)
#find index of second smallest eigenvalue
index = np.argsort(w)[1]
v_partition = v[:, index]
v_partition = np.sign(v_partition)
import ibeis
flags = v_partition > 0
cluster_aids = ut.compress(aids, flags)
ibeis.viz.viz_chip.show_many_chips(ibs, cluster_aids)
remain_aids = ut.compress(aids, ut.not_list(flags))
for i in range(len(set(nids))):
remain_m = m_adjacency.compress(~flags, axis=0).compress(~flags, axis=1)
D = np.diag(np.sum(remain_m, 0))
D_half_inv = np.diag(1.0 / np.sqrt(np.sum(remain_m, 0)))
M = np.dot(D_half_inv, np.dot((D - remain_m), D_half_inv))
(w, v) = np.linalg.eig(M)
#find index of second smallest eigenvalue
index = np.argsort(w)[1]
v_partition = v[:, index]
v_partition = np.sign(v_partition)
flags = v_partition > 0
cluster_aids = ut.compress(remain_aids, flags)
ibeis.viz.viz_chip.show_many_chips(ibs, cluster_aids)
remain_aids = ut.compress(remain_aids, ut.not_list(flags))
pass
#diag_idx = np.diag_indices_from(score_mat)
#score_mat[diag_idx] = score_mat.sum(axis=0)
pos = np.meshgrid(np.arange(len(aids)), np.arange(len(aids)))
gt_scores = score_mat[nids[pos[1]] == nids[pos[0]]]
min_gt_score = gt_scores.min()
fnum = 1
#_pnumiter = pt.make_pnum_nextgen(nSubplots=score_mat.size)
nRows, nCols = pt.get_square_row_cols(score_mat.size, fix=True)
ut.ensure_pylab_qt4()
inter = ExpandableInteraction(fnum, nRows=nRows, nCols=nCols)
# Show matches in off-diagonal
for qx, dx in ut.ProgressIter(idx_list):
match = pair_dict[(qx, dx)]
score = score_mat[qx, dx]
match_inter = match.make_interaction(mode=1, title='%.2f' % (score,),
truth=(nids[qx] == nids[dx]))
if score >= min_gt_score:
inter.append_plot(match_inter, px=(qx, dx))
#inter.append_plot(ut.partial(pt.imshow_null, msg=(('qx=%r, dx=%r') % (qx, dx))), px=(qx, dx))
# Show chips in diagonal
for qx in range(len(aids)):
qaid = aids[qx]
chip = ibs.get_annot_chips(qaid)
inter.append_plot(ut.partial(pt.imshow, chip), px=(qx, qx))
inter.start()
#vt.show_matching_dict(matches, metadata, 'RAT')
#pt.plot_score_histograms([fx2_to_dist.T[0]])
#import plottool as pt
#pt.plot_score_histograms([m.matches['TOP+SV'][1]])
sym_score_mat = np.maximum(score_mat, score_mat.T)
#gt_scores = sym_score_mat[nids[pos[1]] == nids[pos[0]]]
#gf_scores = sym_score_mat[nids[pos[1]] != nids[pos[0]]]
cost_matrix = sym_score_mat - 50
labels = vt.unsupervised_multicut_labeling(cost_matrix)
print('labels = %r' % (labels,))
import hdbscan
alg = hdbscan.HDBSCAN(metric='precomputed', min_cluster_size=1, p=1, gen_min_span_tree=1, min_samples=2)
alg.fit_predict((1 / score_mat))
#import pandas
#score_mat = pandas.DataFrame(pairs).as_matrix()
#nids = np.array(nids)
#[np.array(idx_list)]
#score_mat[]
#for qx, dx in ut.ProgressIter(idx_list):
# match = pair_dict[(qx, dx)]
# match.show()
pass
[docs]def vsone_single2(ibs, qaid, daid, qconfig2_, dconfig2_, use_ibscache, verbose):
metadata_ = ut.LazyDict()
annot1 = metadata_['annot1'] = ut.LazyDict()
annot2 = metadata_['annot2'] = ut.LazyDict()
annot1['rchip_fpath'] = ibs.get_annot_chip_fpath([qaid], config2_=qconfig2_)[0]
annot2['rchip_fpath'] = ibs.get_annot_chip_fpath([daid], config2_=qconfig2_)[0]
cfgdict = {}
if use_ibscache:
hack_multi_config = False
if hack_multi_config:
cfgdict = {'refine_method': 'affine'}
data_config_list = query_config_list = [
ibs.new_query_params(affine_invariance=True),
ibs.new_query_params(affine_invariance=False),
]
kpts1 = np.vstack([ibs.get_annot_kpts(qaid, config2_=config2_)
for config2_ in query_config_list])
vecs1 = np.vstack([ibs.get_annot_vecs(qaid, config2_=config2_)
for config2_ in query_config_list])
kpts2 = np.vstack([ibs.get_annot_kpts(daid, config2_=config2_)
for config2_ in data_config_list])
vecs2 = np.vstack([ibs.get_annot_vecs(daid, config2_=config2_)
for config2_ in data_config_list])
dlen_sqrd2 = ibs.get_annot_chip_dlensqrd([daid],
config2_=dconfig2_)[0]
annot1['kpts'] = kpts1
annot1['vecs'] = vecs1
annot2['kpts'] = kpts2
annot2['vecs'] = vecs2
annot2['dlen_sqrd'] = dlen_sqrd2
else:
annot1['kpts'] = ibs.get_annot_kpts(qaid, config2_=qconfig2_)
annot1['vecs'] = ibs.get_annot_vecs(qaid, config2_=qconfig2_)
annot2['kpts'] = ibs.get_annot_kpts(daid, config2_=dconfig2_)
annot2['vecs'] = ibs.get_annot_vecs(daid, config2_=dconfig2_)
annot2['dlen_sqrd'] = ibs.get_annot_chip_dlensqrd([daid], config2_=dconfig2_)[0]
matches, metadata = vt.vsone_matching(metadata_, cfgdict=cfgdict, verbose=verbose)
assert metadata is metadata_
return matches, metadata
[docs]def vsone_single(qaid, daid, qreq_, use_ibscache=False, verbose=None):
r"""
Args:
qaid (int): query annotation id
daid (?):
qreq_ (QueryRequest): query request object with hyper-parameters
CommandLine:
python -m ibeis.algo.hots.vsone_pipeline --exec-vsone_single --show
python -m ibeis.algo.hots.vsone_pipeline --test-vsone_single
python -m ibeis.algo.hots.vsone_pipeline --test-vsone_single --nocache
python -m ibeis.algo.hots.vsone_pipeline --test-vsone_single --nocache --show
python -m ibeis.algo.hots.vsone_pipeline --test-vsone_single --show -t default:AI=False
SeeAlso:
python -m ibeis.algo.hots.vsone_pipeline --exec-extract_aligned_parts:1 --show -t default:AI=False # see x 11
Example:
>>> # DISABLE_DOCTEST
>>> from ibeis.algo.hots.vsone_pipeline import * # NOQA
>>> import ibeis
>>> ibs = ibeis.opendb(defaultdb='PZ_FlankHack')
>>> pcfgdict = ibeis.main_helpers.testdata_pipecfg()
>>> qaid, daid = ibs.get_name_aids(ibs.get_valid_nids()[0:1])[0][0:2]
>>> qreq_ = ibs.new_query_request([qaid], [daid], cfgdict=pcfgdict)
>>> use_ibscache = not ut.get_argflag('--noibscache')
>>> matches, metadata = vsone_single(qaid, daid, qreq_, use_ibscache)
>>> H1 = metadata['H_RAT']
>>> ut.quit_if_noshow()
>>> vt.matching.show_matching_dict(matches, metadata, mode=1)
>>> ut.show_if_requested()
"""
ibs = qreq_.ibs
qconfig2_ = qreq_.get_external_query_config2()
dconfig2_ = qreq_.get_external_query_config2()
return vsone_single2(ibs, qaid, daid, qconfig2_, dconfig2_, use_ibscache, verbose)
[docs]def vsone_name_independant_hack(ibs, nids, qreq_=None):
r"""
show grid of aids with matches inside and between names
Args:
ibs (IBEISController): ibeis controller object
nid (?):
qreq_ (QueryRequest): query request object with hyper-parameters(default = None)
CommandLine:
python -m ibeis.algo.hots.vsone_pipeline --exec-vsone_name_independant_hack --db PZ_MTEST --show
python -m ibeis.algo.hots.vsone_pipeline --exec-vsone_name_independant_hack --db PZ_Master1 --show --nids=5099,5181
Example:
>>> # DISABLE_DOCTEST
>>> from ibeis.algo.hots.vsone_pipeline import * # NOQA
>>> import ibeis
>>> # TODO: testdata_qparams?
>>> qreq_ = ibeis.testdata_qreq_(defaultdb='testdb1')
>>> nids = ut.get_argval('--nids', type_=list, default=[1])
>>> ibs = qreq_.ibs
>>> result = vsone_name_independant_hack(qreq_.ibs, nids, qreq_)
>>> print(result)
>>> ut.show_if_requested()
"""
from plottool.interactions import ExpandableInteraction
import plottool as pt
import ibeis.viz
fnum = pt.ensure_fnum(None)
inter = ExpandableInteraction(fnum)
aids = ut.flatten(ibs.get_name_aids(nids))
print('len(aids) = %r' % (len(aids),))
idxs = range(len(aids))
def wrap_show_func(func, *args, **kwargs):
def _show_func_wrap(fnum=None, pnum=None):
return func(*args, fnum=fnum, pnum=pnum, **kwargs)
return _show_func_wrap
# TODO: append an optional alternate ishow function
#for idx1, idx2 in ut.upper_diag_self_prodx(idxs):
for idx1, idx2 in ut.self_prodx(idxs):
aid1 = aids[idx1]
aid2 = aids[idx2]
#vsone_independant_pair_hack(ibs, aid1, aid2, qreq_)
cfgdict = dict(codename='vsone', fg_on=False)
cfgdict.update(**qreq_.get_external_data_config2().hesaff_params)
vsone_qreq_ = ibs.new_query_request([aid1], [aid2], cfgdict=cfgdict)
cm_vsone = ibs.query_chips(qreq_=vsone_qreq_)[0]
cm_vsone = cm_vsone.extend_results(vsone_qreq_)
#cm_vsone.ishow_single_annotmatch(vsone_qreq_, aid2=aid2, fnum=fnum, pnum=(len(aids), len(aids), (idx1 * len(aids) + idx2) + 1))
#cm_vsone.show_single_annotmatch(vsone_qreq_, aid2=aid2, fnum=fnum, pnum=(len(aids), len(aids), (idx1 * len(aids) + idx2) + 1))
pnum = (len(aids), len(aids), (idx1 * len(aids) + idx2) + 1)
show_func = wrap_show_func(cm_vsone.show_single_annotmatch, vsone_qreq_, aid2=aid2, draw_lbl=False, show_name_score=True)
ishow_func = wrap_show_func(cm_vsone.ishow_single_annotmatch, vsone_qreq_, aid2=aid2, draw_lbl=False, noupdate=True)
inter.append_plot(show_func, pnum=pnum, ishow_func=ishow_func)
#inter.append_plot(cm_vsone.ishow_single_annotmatch(vsone_qreq_, aid2=aid2, draw_lbl=False, noupdate=True), pnum=pnum)
#, pnum=pnum)
#cm_vsone.show_single_annotmatch(vsone_qreq_, daid=aid2, draw_lbl=False,
# fnum=fnum, pnum=pnum)
for idx in idxs:
aid = aids[idx]
pnum = (len(aids), len(aids), (idx * len(aids) + idx) + 1)
inter.append_plot(wrap_show_func(ibeis.viz.show_chip, ibs, aid, qreq_=qreq_, draw_lbl=False, nokpts=True), pnum=pnum)
#ibeis.viz.show_chip(ibs, aid, qreq_=qreq_,
# draw_lbl=False, nokpts=True,
# fnum=fnum, pnum=pnum)
inter.show_page()
[docs]def vsone_independant_pair_hack(ibs, aid1, aid2, qreq_=None):
r""" simple hack convinience func
Uses vsmany qreq to build a "similar" vsone qreq
TODO:
in the context menu let me change preferences for running vsone
Args:
ibs (IBEISController): ibeis controller object
aid1 (int): annotation id
aid2 (int): annotation id
qreq_ (QueryRequest): query request object with hyper-parameters(default = None)
CommandLine:
python -m ibeis.algo.hots.vsone_pipeline --exec-vsone_independant_pair_hack --show --db PZ_MTEST
python -m ibeis.algo.hots.vsone_pipeline --exec-vsone_independant_pair_hack --show --qaid=1 --daid=4
--cmd
Example:
>>> # DISABLE_DOCTEST
>>> from ibeis.algo.hots.vsone_pipeline import * # NOQA
>>> import ibeis
>>> qreq_ = ibeis.testdata_qreq_(defaultdb='testdb1')
>>> aid1 = ut.get_argval('--qaid', default=1)
>>> aid2 = ut.get_argval('--daid', default=2)
>>> result = vsone_independant_pair_hack(qreq_.ibs, aid1, aid2, qreq_)
>>> print(result)
>>> ibs = qreq_.ibs
>>> ut.show_if_requested()
"""
cfgdict = dict(codename='vsone', fg_on=False)
# FIXME: update this cfgdict a little better
if qreq_ is not None:
cfgdict.update(**qreq_.get_external_data_config2().hesaff_params)
vsone_qreq_ = ibs.new_query_request([aid1], [aid2], cfgdict=cfgdict)
cm_vsone = ibs.query_chips(qreq_=vsone_qreq_)[0]
cm_vsone = cm_vsone.extend_results(vsone_qreq_)
#cm_vsone = chip_match.ChipMatch.from_qres(vsone_qres)
#cm_vsone.ishow_analysis(vsone_qreq_)
cm_vsone.ishow_single_annotmatch(vsone_qreq_, aid2=aid2)
#qres_vsone.ishow_analysis(ibs=ibs)
#rchip_fpath1, rchip_fpath2 = ibs.get_annot_chip_fpath([aid1, aid2])
#matches, metadata = vt.matching.vsone_image_fpath_matching(rchip_fpath1, rchip_fpath2)
#vt.matching.show_matching_dict(matches, metadata)
[docs]def vsone_independant(qreq_):
r"""
Args:
qreq_ (QueryRequest): query request object with hyper-parameters
CommandLine:
./dev.py -t custom --db PZ_Master0 --allgt --species=zebra_plains
python -m ibeis.algo.hots.vsone_pipeline --test-vsone_independant --show
python -m ibeis.control.manual_annot_funcs --test-get_annot_groundtruth:0 --db=PZ_Master0 --aids=117 --exec-mode # NOQA
python -m ibeis.algo.hots.vsone_pipeline --test-vsone_independant --qaid_list=97 --daid_list=all --db PZ_Master0 --species=zebra_plains
python -m ibeis.viz.viz_name --test-show_multiple_chips --show --db PZ_Master0 --aids=118,117
python -m ibeis.algo.hots.pipeline --test-request_ibeis_query_L0:0 --show --db PZ_Master0 --qaid_list=97 --daid-list=4813,4815
--daid_list=all
Example:
>>> # DISABLE_DOCTEST
>>> from ibeis.algo.hots import _pipeline_helpers as plh
>>> cfgdict = dict(pipeline_root='vsone', codename='vsone', fg_on=False)
>>> p = 'default' + ut.get_cfg_lbl(cfgdict)
>>> ibs, qreq_ = ibeis.testdata_qreq_(p=p, qaid_override=[1], qaid_override=[2, 5])
>>> result = vsone_independant(qreq_)
>>> print(result)
"""
# test script
ibs = qreq_.ibs
# ./dev.py --db lewa_grevys --cmd
# Get matches that have some property (scenerymatch)
# HACK TEST SCRIPT
#def get_scenery_match_aid_pairs(ibs):
# import utool as ut
# annotmatch_rowids = ibs._get_all_annotmatch_rowids()
# flags = ibs.get_annotmatch_is_scenerymatch(annotmatch_rowids)
# annotmatch_rowids_ = ut.compress(annotmatch_rowids, flags)
# aid1_list = ibs.get_annotmatch_aid1(annotmatch_rowids_)
# aid2_list = ibs.get_annotmatch_aid2(annotmatch_rowids_)
# aid_pair_list = list(zip(aid1_list, aid2_list))
# return aid_pair_list
#aid_pair_list = get_scenery_match_aid_pairs(ibs)
#aid1, aid2 = aid_pair_list[0]
qaids = qreq_.get_internal_qaids()
daids = qreq_.get_internal_daids()
import vtool as vt
info_list = []
#for aid1, aid2 in ut.ProgressIter(aid_pair_list):
for aid1 in qaids:
for aid2 in daids:
rchip_fpath1, rchip_fpath2 = ibs.get_annot_chip_fpath([aid1, aid2])
matches, metadata = vt.matching.vsone_image_fpath_matching(rchip_fpath1, rchip_fpath2)
info_list.append((matches, metadata))
print('So Far')
print(sum([matches['RAT+SV'][0].shape[0] for (matches, metadata) in info_list])) # NOQA
# nnp_master had 15621 background examples
for matches, metadata in info_list:
vt.matching.show_matching_dict(matches, metadata)
[docs]def marge_matches_lists(fmfs_A, fmfs_B):
if fmfs_A is None:
return fmfs_B
fm_A_list, fsv_A_list = fmfs_A
fm_B_list, fsv_B_list = fmfs_B
fm_merge_list = []
fsv_merge_list = []
fsv_A_list = matching.ensure_fsv_list(fsv_A_list)
fsv_B_list = matching.ensure_fsv_list(fsv_B_list)
for fm_A, fm_B, fsv_A, fsv_B in zip(fm_A_list, fm_B_list, fsv_A_list, fsv_B_list):
fm_merged, fs_merged = matching.marge_matches(fm_A, fm_B, fsv_A, fsv_B)
fm_merge_list.append(fm_merged)
fsv_merge_list.append(fs_merged)
fmfs_merge = fm_merge_list, fsv_merge_list
return fmfs_merge
[docs]def get_selectivity_score_list(qreq_, qaid, daid_list, fm_list, cos_power):
vecs1 = qreq_.ibs.get_annot_vecs(qaid, config2_=qreq_.get_external_query_config2())
vecs2_list = qreq_.ibs.get_annot_vecs(daid_list, config2_=qreq_.get_external_data_config2())
vecs1_m_iter = (vecs1.take(fm.T[0], axis=0) for fm in fm_list)
vecs2_m_iter = (vecs2.take(fm.T[1], axis=0) for fm, vecs2 in zip(fm_list, vecs2_list))
# Rescore constrained using selectivity function
fs_list = [scoring.sift_selectivity_score(vecs1_m, vecs2_m, cos_power)
for vecs1_m, vecs2_m in zip(vecs1_m_iter, vecs2_m_iter)]
return fs_list
@profile
[docs]def sver_fmfs_merge(qreq_, qaid, daid_list, fmfs_merge, config={}):
from vtool import spatial_verification as sver
# params
# TODO: rectify with sver_single_chipmatch
# TODO paramaterize better
xy_thresh = config.get('xy_thresh') * 1.5
scale_thresh = config.get('scale_thresh') * 2
ori_thresh = config.get('ori_thresh') * 2
min_nInliers = config.get('min_nInliers')
# input data
fm_list, fs_list = fmfs_merge
fsv_list = matching.ensure_fsv_list(fs_list)
kpts1 = qreq_.ibs.get_annot_kpts(qaid, config2_=qreq_.get_external_query_config2())
kpts2_list = qreq_.ibs.get_annot_kpts(daid_list, config2_=qreq_.get_external_data_config2())
chip2_dlen_sqrd_list = qreq_.ibs.get_annot_chip_dlensqrd(
daid_list, config2_=qreq_.get_external_data_config2())
# chip diagonal length
res_list = []
# homog_inliers
for kpts2, chip2_dlen_sqrd, fm, fsv in zip(kpts2_list, chip2_dlen_sqrd_list, fm_list, fsv_list):
match_weights = np.ones(len(fm))
sv_tup = sver.spatially_verify_kpts(
kpts1, kpts2, fm, xy_thresh, scale_thresh, ori_thresh,
chip2_dlen_sqrd, min_nInliers,
returnAff=False, match_weights=match_weights)
if sv_tup is not None:
(homog_inliers, homog_errors, H, aff_inliers, aff_errors, Aff) = sv_tup
fm_SV = fm.take(homog_inliers, axis=0)
fsv_SV = fsv.take(homog_inliers, axis=0)
else:
fm_SV = np.empty((0, 2), dtype=hstypes.FM_DTYPE)
fsv_SV = np.empty((0, fsv.shape[1]))
H = np.eye(3)
res_list.append((fm_SV, fsv_SV, H))
fm_list_SV = ut.get_list_column(res_list, 0)
fsv_list_SV = ut.get_list_column(res_list, 1)
H_list = ut.get_list_column(res_list, 2)
fmfs_merge_SV = (fm_list_SV, fsv_list_SV)
return fmfs_merge_SV, H_list
@profile
[docs]def refine_matches(qreq_, prior_cm, config={}):
r"""
CommandLine:
python -m ibeis.algo.hots.vsone_pipeline --test-refine_matches --show
python -m ibeis.algo.hots.vsone_pipeline --test-refine_matches --show --homog
python -m ibeis.algo.hots.vsone_pipeline --test-refine_matches --show --homog --sver_unconstrained
python -m ibeis.algo.hots.vsone_pipeline --test-refine_matches --show --homog --sver_constrained&
python -m ibeis.algo.hots.vsone_pipeline --test-refine_matches --show --homog --sver_constrained --sver_unconstrained&
# CONTROLLED EXAMPLES
python -m ibeis.algo.hots.vsone_pipeline --exec-refine_matches --show --qaid 1801 --controlled_daids --db PZ_Master0 --sv_on=False --present
# WITH DEV HARNESS
python dev.py -t custom:rrvsone_on=True --allgt --index 0:40 --db PZ_MTEST --print-confusion-stats --print-scorediff-mat-stats
python dev.py -t custom:rrvsone_on=True custom --allgt --index 0:40 --db PZ_MTEST --print-confusion-stats --print-scorediff-mat-stats
python dev.py -t custom:rrvsone_on=True,constrained_coeff=0 custom --qaid 12 --db PZ_MTEST \
--print-confusion-stats --print-scorediff-mat-stats --show --va
python dev.py -t custom:rrvsone_on=True,constrained_coeff=0,maskscore_mode=kpts --qaid 12 --db PZ_MTEST \
--print-confusion-stats --print-scorediff-mat-stats --show --va
python dev.py -t custom:rrvsone_on=True,maskscore_mode=kpts --qaid 12 --db PZ_MTEST \
--print-confusion-stats --print-scorediff-mat-stats --show --va
use_kptscov_scoring
Example1:
>>> # SLOW_DOCTEST
>>> # (IMPORTANT)
>>> from ibeis.algo.hots.vsone_pipeline import * # NOQA
>>> ibs, qreq_, prior_cm = plh.testdata_matching('PZ_MTEST')
>>> config = qreq_.qparams
>>> unscored_cm = refine_matches(qreq_, prior_cm, config)
>>> unscored_cm.print_csv(ibs=ibs)
>>> prior_cm.print_csv(ibs=ibs)
>>> ut.quit_if_noshow()
>>> prior_cm.show_ranked_matches(qreq_, figtitle=qreq_.qparams.query_cfgstr)
>>> ut.show_if_requested()
"""
# THIS CAUSES THE ISSUE
#prior_cm.fs_list = prior_cm.fsv_list
#return prior_cm
if qreq_.ibs.get_annot_num_feats(prior_cm.qaid, config2_=qreq_.qparams) == 0:
num_daids = len(prior_cm.daid_list)
empty_unscored_cm = chip_match.ChipMatch.from_unscored(
prior_cm, ut.alloc_lists(num_daids), ut.alloc_lists(num_daids),
ut.alloc_lists(num_daids))
return empty_unscored_cm
prior_coeff = config.get('prior_coeff')
unconstrained_coeff = config.get('unconstrained_coeff')
constrained_coeff = config.get('constrained_coeff')
sver_unconstrained = config.get('sver_unconstrained')
sver_constrained = config.get('sver_constrained')
# TODO: Param
scr_cos_power = 3.0
#
qaid = prior_cm.qaid
daid_list = prior_cm.daid_list
fm_prior_list = prior_cm.fm_list
fsv_prior_list = prior_cm.fsv_list
H_prior_list = prior_cm.H_list
H_list = H_prior_list
assert unconstrained_coeff is not None, '%r' % (unconstrained_coeff,)
col_coeff_list = []
fmfs_merge = None
if prior_coeff != 0:
# Merge into result
col_coeff_list.append(prior_coeff)
fmfs_prior = (fm_prior_list, fsv_prior_list)
fmfs_merge = marge_matches_lists(fmfs_merge, fmfs_prior)
if unconstrained_coeff != 0:
col_coeff_list.append(unconstrained_coeff)
unc_match_results = compute_query_unconstrained_matches(qreq_, qaid, daid_list, config)
fm_unc_list, fs_unc_list, fm_norm_unc_list = unc_match_results
# Merge into result
fmfs_unc = (fm_unc_list, fs_unc_list)
fmfs_merge = marge_matches_lists(fmfs_merge, fmfs_unc)
# We have the option of spatially verifying the merged results from the
# prior and the new unconstrained matches.
if sver_unconstrained:
fmfs_merge, H_list = sver_fmfs_merge(qreq_, qaid, daid_list, fmfs_merge, config)
if constrained_coeff != 0:
scr_match_results = compute_query_constrained_matches(qreq_, qaid,
daid_list,
H_list, config)
fm_scr_list, fs_scr_list, fm_norm_scr_list = scr_match_results
fs_scr_list = get_selectivity_score_list(qreq_, qaid, daid_list, fm_scr_list, scr_cos_power)
# Merge into result
fmfs_scr = (fm_scr_list, fs_scr_list)
fmfs_merge = marge_matches_lists(fmfs_merge, fmfs_scr)
col_coeff_list.append(constrained_coeff)
# Another optional round of spatial verification
if sver_constrained:
fmfs_merge, H_list = sver_fmfs_merge(qreq_, qaid, daid_list, fmfs_merge, config)
coeffs = np.array(col_coeff_list)
assert np.isclose(coeffs.sum(), 1.0), 'must sum to 1 coeffs = %r' % (coeffs)
# merge different match types
fm_list, fsv_list = fmfs_merge
# apply linear combination
fs_list = [(np.nan_to_num(fsv) * coeffs[None, :]).sum(axis=1) for fsv in fsv_list]
unscored_cm = chip_match.ChipMatch.from_unscored(prior_cm, fm_list, fs_list, H_list)
return unscored_cm
@profile
[docs]def single_vsone_rerank(qreq_, prior_cm, config={}):
r"""
Runs a single vsone-pair (query, daid_list)
CommandLine:
python -m ibeis.algo.hots.vsone_pipeline --test-single_vsone_rerank
python -m ibeis.algo.hots.vsone_pipeline --test-single_vsone_rerank --show
python -m ibeis.algo.hots.vsone_pipeline --test-single_vsone_rerank --show --qaid 18
python -m ibeis.algo.hots.vsone_pipeline --test-single_vsone_rerank --show --qaid 18
python -m ibeis.algo.hots.vsone_pipeline --test-single_vsone_rerank --show --qaid 1801 --db PZ_Master0 --controlled --verb-testdata
python -m ibeis.algo.hots.vsone_pipeline --test-single_vsone_rerank --show --qaid 1801 --controlled_daids --db PZ_Master0 --verb-testdata
python -m ibeis.algo.hots.vsone_pipeline --exec-single_vsone_rerank --show --qaid 1801 --controlled_daids --db PZ_Master0 --verb-testdata
python -m ibeis.algo.hots.vsone_pipeline --exec-single_vsone_rerank --show --qaid 1801 --controlled_daids --db PZ_Master0 --verb-testdata --sv_on=False --present
python -m ibeis.algo.hots.vsone_pipeline --exec-single_vsone_rerank --show --qaid 1801 --controlled_daids --db PZ_Master0 --verb-testdata --sv_on=False --present --affine-invariance=False
python -m ibeis.algo.hots.vsone_pipeline --exec-single_vsone_rerank --show --qaid 1801 --controlled_daids --db PZ_Master0 --verb-testdata --sv_on=False --present --affine-invariance=False --rotation-invariant=True
Example1:
>>> # SLOW_DOCTEST
>>> # (IMPORTANT)
>>> import plottool as pt
>>> from ibeis.algo.hots.vsone_pipeline import * # NOQA
>>> ibs, qreq_, prior_cm = plh.testdata_matching('PZ_MTEST')
>>> config = qreq_.qparams
>>> rerank_cm = single_vsone_rerank(qreq_, prior_cm, config)
>>> #rerank_cm.print_rawinfostr()
>>> rerank_cm.print_csv()
>>> print(rerank_cm.score_list)
>>> ut.quit_if_noshow()
>>> prior_cm.score_nsum(qreq_)
>>> prior_cm.show_ranked_matches(qreq_, fnum=1, figtitle='prior')
>>> rerank_cm.show_ranked_matches(qreq_, fnum=2, figtitle='rerank')
>>> pt.show_if_requested()
"""
#print('==================')
unscored_cm = refine_matches(qreq_, prior_cm, config)
if qreq_.qparams.covscore_on:
unscored_cm.score_coverage(qreq_)
else:
# Apply score weights
data_baseline_weight_list = scoring.get_annot_kpts_baseline_weights(
qreq_.ibs, unscored_cm.daid_list,
config2_=qreq_.get_external_data_config2(), config=config)
query_baseline_weight = scoring.get_annot_kpts_baseline_weights(
qreq_.ibs, [unscored_cm.qaid],
config2_=qreq_.get_external_query_config2(), config=config)[0]
qfx_list = [fm.T[0] for fm in unscored_cm.fm_list]
dfx_list = [fm.T[1] for fm in unscored_cm.fm_list]
qfweight_list = [query_baseline_weight.take(qfx) for qfx in qfx_list]
dfweight_list = [data_baseline_weight.take(dfx)
for dfx, data_baseline_weight in zip(dfx_list, data_baseline_weight_list)]
fweight_list = [np.sqrt(qfweight * dfweight) for qfweight, dfweight in
zip(qfweight_list, dfweight_list)]
# hack in the distinctivness and fgweights
unscored_cm.fs_list = [
fs * fweight
for fs, fweight in zip(unscored_cm.fs_list, fweight_list)]
unscored_cm.fsv_list = matching.ensure_fsv_list(unscored_cm.fs_list)
#queryside_weights =
#dfweights_list =
# hack
unscored_cm.score_nsum(qreq_)
# Convert our one score to a score vector here
rerank_cm = unscored_cm
rerank_cm.fsv_list = matching.ensure_fsv_list(rerank_cm.fs_list)
return rerank_cm
[docs]def quick_vsone_flann(flann_cachedir, qvecs):
flann_params = {
'algorithm': 'kdtree',
'trees': 8
}
use_cache = save = True
flann = vt.flann_cache(qvecs, flann_cachedir, flann_params=flann_params,
quiet=True, verbose=False, use_cache=use_cache, save=save)
return flann
@profile
[docs]def compute_query_unconstrained_matches(qreq_, qaid, daid_list, config):
r"""
CommandLine:
python -m ibeis.algo.hots.vsone_pipeline --test-compute_query_unconstrained_matches --show
python -m ibeis.algo.hots.vsone_pipeline --test-compute_query_unconstrained_matches --show --shownorm
python -m ibeis.algo.hots.vsone_pipeline --test-compute_query_unconstrained_matches --show --shownorm --homog
Example1:
>>> # SLOW_DOCTEST
>>> # (IMPORTANT)
>>> from ibeis.algo.hots.vsone_pipeline import * # NOQA
>>> ibs, qreq_, prior_cm = plh.testdata_matching()
>>> config = qreq_.qparams
>>> qaid, daid_list, H_list = ut.dict_take(prior_cm, ['qaid', 'daid_list', 'H_list'])
>>> match_results = compute_query_unconstrained_matches(qreq_, qaid, daid_list, config)
>>> fm_RAT_list, fs_RAT_list, fm_norm_RAT_list = match_results
>>> ut.quit_if_noshow()
>>> import plottool as pt
>>> idx = ut.listfind(ibs.get_annot_nids(daid_list).tolist(), ibs.get_annot_nids(qaid))
>>> args = (ibs, qaid, daid_list, fm_RAT_list, fs_RAT_list, fm_norm_RAT_list, H_list)
>>> show_single_match(*args, index=idx)
>>> pt.set_title('unconstrained')
>>> pt.show_if_requested()
"""
unc_ratio_thresh = config['unc_ratio_thresh']
#, .625)
qvecs = qreq_.ibs.get_annot_vecs(qaid, config2_=qreq_.get_external_query_config2())
dvecs_list = qreq_.ibs.get_annot_vecs(daid_list, config2_=qreq_.get_external_data_config2())
#print(len(qvecs))
flann = quick_vsone_flann(qreq_.ibs.get_flann_cachedir(), qvecs)
rat_kwargs = {
'unc_ratio_thresh' : unc_ratio_thresh,
'fm_dtype' : hstypes.FM_DTYPE,
'fs_dtype' : hstypes.FS_DTYPE,
}
#print('rat_kwargs = ' + ut.dict_str(rat_kwargs))
scrtup_list = [
matching.unconstrained_ratio_match(
flann, vecs2, **rat_kwargs)
for vecs2 in ut.ProgIter(dvecs_list, lbl='unconstrained matching', adjust=True, time_thresh=7)
]
fm_RAT_list = ut.get_list_column(scrtup_list, 0)
fs_RAT_list = ut.get_list_column(scrtup_list, 1)
fm_norm_RAT_list = ut.get_list_column(scrtup_list, 2)
match_results = fm_RAT_list, fs_RAT_list, fm_norm_RAT_list
return match_results
@profile
[docs]def compute_query_constrained_matches(qreq_, qaid, daid_list, H_list, config):
r"""
CommandLine:
python -m ibeis.algo.hots.vsone_pipeline --test-compute_query_constrained_matches --show
python -m ibeis.algo.hots.vsone_pipeline --test-compute_query_constrained_matches --show --shownorm
python -m ibeis.algo.hots.vsone_pipeline --test-compute_query_constrained_matches --show --shownorm --homog
python -m ibeis.algo.hots.vsone_pipeline --test-compute_query_constrained_matches --show --homog
python -m ibeis.algo.hots.vsone_pipeline --test-compute_query_constrained_matches --show --homog --index 2
Example1:
>>> # SLOW_DOCTEST
>>> # (IMPORTANT)
>>> from ibeis.algo.hots.vsone_pipeline import * # NOQA
>>> ibs, qreq_, prior_cm = plh.testdata_matching()
>>> config = qreq_.qparams
>>> print(config.query_cfgstr)
>>> qaid, daid_list, H_list = ut.dict_take(prior_cm, ['qaid', 'daid_list', 'H_list'])
>>> match_results = compute_query_constrained_matches(qreq_, qaid, daid_list, H_list, config)
>>> fm_SCR_list, fs_SCR_list, fm_norm_SCR_list = match_results
>>> ut.quit_if_noshow()
>>> import plottool as pt
>>> idx = ut.listfind(ibs.get_annot_nids(daid_list), ibs.get_annot_nids(qaid))
>>> index = ut.get_argval('--index', int, idx)
>>> args = (ibs, qaid, daid_list, fm_SCR_list, fs_SCR_list, fm_norm_SCR_list, H_list)
>>> show_single_match(*args, index=index)
>>> pt.set_title('constrained')
>>> pt.show_if_requested()
"""
scr_ratio_thresh = config.get('scr_ratio_thresh', .1)
scr_K = config.get('scr_K', 7)
scr_match_xy_thresh = config.get('scr_match_xy_thresh', .05)
scr_norm_xy_min = config.get('scr_norm_xy_min', 0.1)
scr_norm_xy_max = config.get('scr_norm_xy_max', 1.0)
scr_norm_xy_bounds = (scr_norm_xy_min, scr_norm_xy_max)
vecs1 = qreq_.ibs.get_annot_vecs(qaid, config2_=qreq_.get_external_query_config2())
kpts1 = qreq_.ibs.get_annot_kpts(qaid, config2_=qreq_.get_external_query_config2())
vecs2_list = qreq_.ibs.get_annot_vecs(daid_list, config2_=qreq_.get_external_data_config2())
kpts2_list = qreq_.ibs.get_annot_kpts(daid_list, config2_=qreq_.get_external_data_config2())
chip2_dlen_sqrd_list = qreq_.ibs.get_annot_chip_dlensqrd(
daid_list, config2_=qreq_.get_external_data_config2()) # chip diagonal length
# build flann for query vectors
flann = quick_vsone_flann(qreq_.ibs.get_flann_cachedir(), vecs1)
# match database chips to query chip
scr_kwargs = {
'scr_K' : scr_K,
'match_xy_thresh' : scr_match_xy_thresh,
'norm_xy_bounds' : scr_norm_xy_bounds,
'scr_ratio_thresh' : scr_ratio_thresh,
'fm_dtype' : hstypes.FM_DTYPE,
'fs_dtype' : hstypes.FS_DTYPE,
}
print('scr_kwargs = ' + ut.dict_str(scr_kwargs))
# Homographys in H_list map image1 space into image2 space
scrtup_list = [
matching.spatially_constrained_ratio_match(
flann, vecs2, kpts1, kpts2, H, chip2_dlen_sqrd, **scr_kwargs)
for vecs2, kpts2, chip2_dlen_sqrd, H in
zip(vecs2_list, kpts2_list, chip2_dlen_sqrd_list, H_list)]
fm_SCR_list = ut.get_list_column(scrtup_list, 0)
fs_SCR_list = ut.get_list_column(scrtup_list, 1)
fm_norm_SCR_list = ut.get_list_column(scrtup_list, 2)
match_results = fm_SCR_list, fs_SCR_list, fm_norm_SCR_list
return match_results
# -----------------------------
# GRIDSEARCH
# -----------------------------
COVKPTS_DEFAULT = vt.coverage_kpts.COVKPTS_DEFAULT
COVGRID_DEFAULT = vt.coverage_grid.COVGRID_DEFAULT
OTHER_RRVSONE_PARAMS = ut.ParamInfoList('OTHERRRVSONE', [
#ut.ParamInfo('fs_lnbnn_min', .0001),
#ut.ParamInfo('fs_lnbnn_max', .05),
#ut.ParamInfo('fs_lnbnn_power', 1.0),
ut.ParamInfo('fs_lnbnn_min', 0.0, hideif=0.0),
ut.ParamInfo('fs_lnbnn_max', 1.0, hideif=1.0),
ut.ParamInfo('fs_lnbnn_power', 1.0, hideif=1.0),
ut.ParamInfoBool('covscore_on', False, hideif=lambda cfg: True),
ut.ParamInfo('dcvs_on', False, hideif=False),
])
SHORTLIST_DEFAULTS = ut.ParamInfoList('SLIST', [
ut.ParamInfo('nNameShortlistVsone', 20, 'nNm='),
ut.ParamInfo('nAnnotPerNameVsone', 3, 'nApN='),
])
# matching types
COEFF_DEFAULTS = ut.ParamInfoList('COEFF', [
ut.ParamInfo('prior_coeff', .6, 'prior_coeff='),
ut.ParamInfo('unconstrained_coeff', .4, 'unc_coeff='),
ut.ParamInfo('constrained_coeff', 0.0, 'scr_coeff=', hideif=0.0),
ut.ParamInfo('sver_unconstrained', True, 'sver_unc=',
hideif=lambda cfg: cfg['unconstrained_coeff'] <= 0),
ut.ParamInfo('sver_constrained', False, 'sver_scr=',
hideif=lambda cfg: cfg['constrained_coeff'] <= 0),
ut.ParamInfo('maskscore_mode', 'grid', 'cov=',
hideif=lambda cfg: not cfg['covscore_on']),
]
)
UNC_DEFAULTS = ut.ParamInfoList('UNC', [
ut.ParamInfo('unc_ratio_thresh', .8, 'uncRat=', varyvals=[.625, .82, .9, 1.0, .8]),
])
[docs]def scr_constraint_func(cfg):
if cfg['scr_norm_xy_min'] >= cfg['scr_norm_xy_max']:
return False
SCR_DEFAULTS = ut.ParamInfoList('SCR', [
ut.ParamInfo('scr_match_xy_thresh', .15, 'xy=',
varyvals=[.05, 1.0, .1], varyslice=slice(0, 2)),
ut.ParamInfo('scr_norm_xy_min', 0.1, '',
varyvals=[0, .1, .2], varyslice=slice(0, 2)),
ut.ParamInfo('scr_norm_xy_max', 1.0, '',
varyvals=[1, .3], varyslice=slice(0, 2)),
ut.ParamInfo('scr_ratio_thresh', .95, 'scrRat=',
varyvals=[.625, .3, .9, 0.0, 1.0], varyslice=slice(0, 1)),
ut.ParamInfo('scr_K', 7, 'scK',
varyvals=[7, 2], varyslice=slice(0, 2)),
],
scr_constraint_func,
hideif=lambda cfg: cfg['constrained_coeff'] <= 0)
[docs]def gridsearch_single_vsone_rerank():
r"""
CommandLine:
python -m ibeis.algo.hots.vsone_pipeline --test-gridsearch_single_vsone_rerank --show
python -m ibeis.algo.hots.vsone_pipeline --test-gridsearch_single_vsone_rerank --show --testindex 2
Example:
>>> # DISABLE_DOCTEST
>>> from ibeis.algo.hots.vsone_pipeline import * # NOQA
>>> import plottool as pt
>>> gridsearch_single_vsone_rerank()
>>> pt.show_if_requested()
"""
import plottool as pt
ibs, qreq_, prior_cm = plh.testdata_matching()
config = qreq_.qparams
fnum = pt.ensure_fnum(None)
# Make configuration for every parameter setting
cfgdict_ = dict(prescore_method='nsum', score_method='nsum', sver_output_weighting=True)
cfgdict_['rrvsone_on'] = True
# HACK TO GET THE DATA WE WANT WITHOUT UNNCESSARY COMPUTATION
# Get pipeline testdata for this configuration
p = 'default' + ut.get_cfg_lbl(cfgdict_)
import ibeis
ibs, qreq_ = ibeis.testdata_qreq_(defaultdb='PZ_MTEST', p=p, a=['default:qsize=1,mingt=2'])
qaid_list = qreq_.get_external_qaids().tolist()
qaid = qaid_list[0]
daid_list = qreq_.ibs.get_annot_groundtruth(qaid)[0:1]
#
cfgdict_list, cfglbl_list = COEFF_DEFAULTS.get_gridsearch_input(defaultslice=slice(0, 10))
assert len(cfgdict_list) > 0
#config = qreq_.qparams
cfgresult_list = [
single_vsone_rerank(qreq_, prior_cm, config)
for cfgdict in ut.ProgressIter(cfgdict_list, lbl='rerank')
]
# which result to look at
index = ut.get_argval('--testindex', int, 0)
score_list = [scrtup[1][index].sum() for scrtup in cfgresult_list]
#score_list = [scrtup[1][0].sum() / len(scrtup[1][0]) for scrtup in cfgresult_list]
showfunc = functools.partial(show_single_match, ibs, qaid, daid_list, index=index)
def onclick_func(fm_list, fs_list, fm_norm_list):
from ibeis.viz.interact import interact_matches
aid2 = daid_list[index]
cm = chip_match.ChipMatch(qaid=qaid, daid_list=daid_list,
fm_list=fm_list, fsv_list=fs_list)
cm.fs_list = fs_list
interact_matches.MatchInteraction(ibs, cm, aid2=aid2, fnum=None)
ut.interact_gridsearch_result_images(
showfunc, cfgdict_list, cfglbl_list,
cfgresult_list, score_list=score_list, fnum=fnum,
figtitle='constrained ratio match', unpack=True,
max_plots=25, scorelbl='sumscore', onclick_func=onclick_func)
pt.iup()
[docs]def gridsearch_constrained_matches():
r"""
Search spatially constrained matches
CommandLine:
python -m ibeis.algo.hots.vsone_pipeline --test-gridsearch_constrained_matches --show
python -m ibeis.algo.hots.vsone_pipeline --test-gridsearch_constrained_matches --show --qaid 41
python -m ibeis.algo.hots.vsone_pipeline --test-gridsearch_constrained_matches --show --testindex 2
Example:
>>> # DISABLE_DOCTEST
>>> import plottool as pt
>>> from ibeis.algo.hots.vsone_pipeline import * # NOQA
>>> gridsearch_constrained_matches()
>>> pt.show_if_requested()
"""
import plottool as pt
fnum = pt.ensure_fnum(None)
# Make configuration for every parameter setting
cfgdict_list, cfglbl_list = SCR_DEFAULTS.get_gridsearch_input(defaultslice=slice(0, 10))
#fname = None # 'easy1.png'
ibs, qreq_, prior_cm = plh.testdata_matching()
qaid = prior_cm.qaid
daid_list = prior_cm.daid_list
H_list = prior_cm.H_list
#config = qreq_.qparams
cfgresult_list = [
compute_query_constrained_matches(qreq_, qaid, daid_list, H_list, cfgdict)
for cfgdict in ut.ProgressIter(cfgdict_list, lbl='scr match')
]
# which result to look at
index = ut.get_argval('--testindex', int, 0)
score_list = [scrtup[1][index].sum() for scrtup in cfgresult_list]
#score_list = [scrtup[1][0].sum() / len(scrtup[1][0]) for scrtup in cfgresult_list]
showfunc = functools.partial(show_single_match, ibs, qaid, daid_list,
H_list=H_list, index=index)
def onclick_func(fm_list, fs_list, fm_norm_list):
from ibeis.viz.interact import interact_matches
aid2 = daid_list[index]
cm = chip_match.ChipMatch(qaid=qaid, daid_list=daid_list,
fm_list=fm_list, fsv_list=fs_list)
cm.fs_list = fs_list
interact_matches.MatchInteraction(ibs, cm, aid2=aid2, fnum=None)
ut.interact_gridsearch_result_images(
showfunc, cfgdict_list, cfglbl_list,
cfgresult_list, score_list=score_list, fnum=fnum,
figtitle='constrained ratio match', unpack=True,
max_plots=25, scorelbl='sumscore', onclick_func=onclick_func)
#if use_separate_norm:
# ut.interact_gridsearch_result_images(
# functools.partial(show_single_match, use_separate_norm=True),
# cfgdict_list, cfglbl_list,
# cfgresult_list, fnum=fnum + 1, figtitle='constrained ratio match', unpack=True,
# max_plots=25, scorelbl='sumscore')
pt.iup()
[docs]def gridsearch_unconstrained_matches():
r"""
Search unconstrained ratio test vsone match
This still works
CommandLine:
python -m ibeis.algo.hots.vsone_pipeline --test-gridsearch_unconstrained_matches --show
python -m ibeis.algo.hots.vsone_pipeline --test-gridsearch_unconstrained_matches --show --qaid 27
python -m ibeis.algo.hots.vsone_pipeline --test-gridsearch_unconstrained_matches --show --qaid 41 --daid_list 39
python -m ibeis.algo.hots.vsone_pipeline --test-gridsearch_unconstrained_matches --show --qaid 40 --daid_list 39
python -m ibeis.algo.hots.vsone_pipeline --test-gridsearch_unconstrained_matches --show --testindex 2
python -m ibeis.algo.hots.vsone_pipeline --test-gridsearch_unconstrained_matches --show --qaid 117 --daid_list 118 --db PZ_Master0
python -m ibeis.algo.hots.vsone_pipeline --test-gridsearch_unconstrained_matches --show --qaid 117 --daid_list 118 --db PZ_Master0 --rotation_invariance
Example:
>>> # DISABLE_DOCTEST
>>> from ibeis.algo.hots.vsone_pipeline import * # NOQA
>>> import plottool as pt
>>> gridsearch_unconstrained_matches()
>>> pt.show_if_requested()
"""
import ibeis
import plottool as pt
fnum = pt.ensure_fnum(None)
# Make configuration for every parameter setting
cfgdict_ = dict(prescore_method='nsum', score_method='nsum', sver_output_weighting=True)
cfgdict_['rrvsone_on'] = True
# HACK TO GET THE DATA WE WANT WITHOUT UNNCESSARY COMPUTATION
# Get pipeline testdata for this configuration
p = 'default' + ut.get_cfg_lbl(cfgdict_)
ibs, qreq_ = ibeis.testdata_qreq_(defaultdb='PZ_MTEST', p=p, a=['default:qsize=1,mingt=2,dsize=1'])
qaid_list = qreq_.get_external_qaids().tolist()
qaid = qaid_list[0]
daid_list = qreq_.get_external_query_groundtruth(qaid)[0:1]
#
cfgdict_list, cfglbl_list = UNC_DEFAULTS.get_gridsearch_input(defaultslice=slice(0, 10))
assert len(cfgdict_list) > 0
#config = qreq_.qparams
cfgresult_list = [
compute_query_unconstrained_matches(qreq_, qaid, daid_list, cfgdict)
for cfgdict in ut.ProgressIter(cfgdict_list, lbl='scr match')
]
# which result to look at
index = ut.get_argval('--testindex', int, 0)
score_list = [scrtup[1][index].sum() for scrtup in cfgresult_list]
#score_list = [scrtup[1][0].sum() / len(scrtup[1][0]) for scrtup in cfgresult_list]
showfunc = functools.partial(show_single_match, ibs, qaid, daid_list, index=index)
def onclick_func(fm_list, fs_list, fm_norm_list):
from ibeis.viz.interact import interact_matches
aid2 = daid_list[index]
cm = chip_match.ChipMatch(qaid=qaid, daid_list=daid_list,
fm_list=fm_list, fsv_list=fs_list)
cm.fs_list = fs_list
interact_matches.MatchInteraction(ibs, cm, aid2=aid2, fnum=None)
ut.interact_gridsearch_result_images(
showfunc, cfgdict_list, cfglbl_list,
cfgresult_list, score_list=score_list, fnum=fnum,
figtitle='constrained ratio match', unpack=True,
max_plots=25, scorelbl='sumscore', onclick_func=onclick_func)
pt.iup()
# -----------------------------
# VISUALIZATIONS
# -----------------------------
[docs]def show_single_match(ibs, qaid, daid_list, fm_list, fs_list,
fm_norm_list=None, H_list=None, index=None, **kwargs):
use_sameaxis_norm = ut.get_argflag('--shownorm')
fs = fs_list[index]
fm = fm_list[index]
if use_sameaxis_norm:
fm_norm = fm_norm_list[index]
else:
fm_norm = None
kwargs['darken'] = .7
daid = daid_list[index]
if H_list is None:
H1 = None
else:
H1 = H_list[index]
#H1 = None # uncomment to see warping
show_matches(ibs, qaid, daid, fm, fs=fs, H1=H1, fm_norm=fm_norm, **kwargs)
[docs]def show_matches(ibs, qaid, daid, fm, fs=None, fm_norm=None,
H1=None, fnum=None, pnum=None, **kwargs):
from ibeis.viz import viz_matches
if not ut.get_argflag('--homog'):
H1 = None
viz_matches.show_matches2(ibs, qaid, daid, fm=fm, fs=fs, fm_norm=fm_norm, ori=True,
H1=H1, fnum=fnum, pnum=pnum, show_name=False, **kwargs)
#else:
# from ibeis.viz.interact import interact_matches
# cm = chip_match.ChipMatch(qaid, [daid], [fm], [fs])
# interact_matches.MatchInteraction(ibs, cm, fnum=None, aid2=daid)
#pt.set_title('score = %.3f' % (score,))
[docs]def show_ranked_matches(ibs, cm, fnum=None):
import plottool as pt
qaid = cm.qaid
if fnum is None:
fnum = pt.next_fnum()
CLIP_TOP = 6
top_idx_list = ut.listclip(cm.argsort(), CLIP_TOP)
nRows, nCols = pt.get_square_row_cols(len(top_idx_list), fix=True)
next_pnum = pt.make_pnum_nextgen(nRows, nCols)
for idx in top_idx_list:
daid = cm.daid_list[idx]
fm = cm.fm_list[idx]
fsv = cm.fsv_list[idx]
fs = fsv.prod(axis=1)
H1 = cm.H_list[idx]
pnum = next_pnum()
#with ut.EmbedOnException():
show_matches(ibs, qaid, daid, fm=fm, fs=fs, H1=H1, fnum=fnum, pnum=pnum)
score = None if cm.score_list is None else cm.score_list[idx]
if score is not None:
pt.set_title('score = %.3f' % (score,))
else:
pt.set_title('score = %r' % (score,))
[docs]def show_all_ranked_matches(qreq_, cm_list, fnum_offset=0, figtitle=''):
""" helper """
import plottool as pt
for fnum_, cm in enumerate(cm_list):
#cm.foo()
fnum = fnum_ + fnum_offset
if True:
#cm.show_ranked_matches(qreq_, fnum=fnum)
cm.show_analysis(qreq_, fnum=fnum)
else:
show_ranked_matches(qreq_.ibs, cm, fnum)
#pt.figure(fnum=fnum, doclf=True, docla=True)
pt.set_figtitle('qaid=%r %s' % (cm.qaid, figtitle))
if __name__ == '__main__':
"""
CommandLine:
python -m ibeis.algo.hots.vsone_pipeline
python -m ibeis.algo.hots.vsone_pipeline --allexamples
python -m ibeis.algo.hots.vsone_pipeline --allexamples --noface --nosrc
"""
import multiprocessing
multiprocessing.freeze_support() # for win32
import utool as ut # NOQA
ut.doctest_funcs()