Example #1
0
def draw_feat_row(chip,
                  fx,
                  kp,
                  sift,
                  fnum,
                  nRows,
                  nCols=None,
                  px=None,
                  prevsift=None,
                  origsift=None,
                  aid=None,
                  info='',
                  type_=None,
                  shape_labels=False,
                  vecfield=False,
                  multicolored_arms=False,
                  draw_chip=False,
                  draw_warped=True,
                  draw_unwarped=True,
                  draw_desc=True,
                  rect=True,
                  ori=True,
                  pts=False,
                  **kwargs):
    """
    draw_feat_row

    SeeAlso:
        wbia.viz.viz_nearest_descriptors
        ~/code/wbia/wbia/viz/viz_nearest_descriptors.py

    CommandLine:

        # Use this to find the fx you want to visualize
        python -m wbia.plottool.interact_keypoints --test-ishow_keypoints --show --fname zebra.png

        # Use this to visualize the featrow
        python -m wbia.plottool.viz_featrow --test-draw_feat_row --show
        python -m wbia.plottool.viz_featrow --test-draw_feat_row --show --fname zebra.png --fx=121 --feat-all --no-sift
        python -m wbia.plottool.viz_featrow --test-draw_feat_row --dpath figures --save ~/latex/crall-candidacy-2015/figures/viz_featrow.jpg

    Example:
        >>> # DISABLE_DOCTEST
        >>> from wbia.plottool.viz_featrow import *  # NOQA
        >>> import wbia.plottool as pt
        >>> # build test data
        >>> kpts, vecs, imgBGR = pt.viz_keypoints.testdata_kpts()
        >>> chip = imgBGR
        >>> print('There are %d features' % (len(vecs)))
        >>> fx = ut.get_argval('--fx', type_=int, default=0)
        >>> kp = kpts[fx]
        >>> sift = vecs[fx]
        >>> fnum = 1
        >>> nRows = 1
        >>> nCols = 2
        >>> px = 0
        >>> if True:
        >>>     from wbia.scripts.thesis import TMP_RC
        >>>     import matplotlib as mpl
        >>>     mpl.rcParams.update(TMP_RC)
        >>> hack = ut.get_argflag('--feat-all')
        >>> sift = sift if not ut.get_argflag('--no-sift') else None
        >>> draw_desc = sift is not None
        >>> kw = dict(
        >>>     prevsift=None, origsift=None, aid=None, info='', type_=None,
        >>>     shape_labels=False, vecfield=False, multicolored_arms=True,
        >>>     draw_chip=hack, draw_unwarped=hack, draw_warped=True, draw_desc=draw_desc
        >>> )
        >>> # execute function
        >>> result = draw_feat_row(chip, fx, kp, sift, fnum, nRows, nCols, px,
        >>>                           rect=False, ori=False, pts=False, **kw)
        >>> # verify results
        >>> print(result)
        >>> pt.show_if_requested()
    """
    import numpy as np
    import vtool as vt

    # should not need ncols here

    if nCols is not None:
        if ut.VERBOSE:
            print('Warning nCols is no longer needed')
    # assert nCols_ == nCols
    nCols = draw_chip + draw_unwarped + draw_warped + draw_desc

    pnum_ = df2.make_pnum_nextgen(nRows, nCols, start=px)

    # pnum_ = df2.get_pnum_func(nRows, nCols, base=1)
    # countgen = itertools.count(1)

    # pnumgen_ = df2.make_pnum_nextgen(nRows, nCols, base=1)

    def _draw_patch(**kwargs):
        return df2.draw_keypoint_patch(chip,
                                       kp,
                                       sift,
                                       rect=rect,
                                       ori=ori,
                                       pts=pts,
                                       ori_color=custom_constants.DEEP_PINK,
                                       multicolored_arms=multicolored_arms,
                                       **kwargs)

    # Feature strings
    xy_str, shape_str, scale, ori_str = ph.kp_info(kp)

    if draw_chip:
        pnum = pnum_()
        df2.imshow(chip, fnum=fnum, pnum=pnum)
        kpts_kw = dict(ell_linewidth=1, ell_alpha=1.0)
        kpts_kw.update(kwargs)
        df2.draw_kpts2([kp], **kpts_kw)

    if draw_unwarped:
        # Draw the unwarped selected feature
        # ax = _draw_patch(fnum=fnum, pnum=pnum_(px + six.next(countgen)))
        # pnum = pnum_(px + six.next(countgen)
        pnum = pnum_()
        ax = _draw_patch(fnum=fnum, pnum=pnum)
        ph.set_plotdat(ax, 'viztype', 'unwarped')
        ph.set_plotdat(ax, 'aid', aid)
        ph.set_plotdat(ax, 'fx', fx)
        if shape_labels:
            unwarped_lbl = 'affine feature invV =\n' + shape_str + '\n' + ori_str
            custom_figure.set_xlabel(unwarped_lbl, ax)

    if draw_warped:
        # Draw the warped selected feature
        # ax = _draw_patch(fnum=fnum, pnum=pnum_(px + six.next(countgen)), warped=True)
        pnum = pnum_()
        ax = _draw_patch(fnum=fnum, pnum=pnum, warped=True, **kwargs)
        ph.set_plotdat(ax, 'viztype', 'warped')
        ph.set_plotdat(ax, 'aid', aid)
        ph.set_plotdat(ax, 'fx', fx)
        if shape_labels:
            warped_lbl = ('warped feature\n' + 'fx=%r scale=%.1f\n' + '%s') % (
                fx,
                scale,
                xy_str,
            )
        else:
            warped_lbl = ''
        warped_lbl += info
        custom_figure.set_xlabel(warped_lbl, ax)

    if draw_desc:
        border_color = {
            'None': None,
            'query': None,
            'match': custom_constants.BLUE,
            'norm': custom_constants.ORANGE,
        }.get(str(type_).lower(), None)
        if border_color is not None:
            df2.draw_border(ax, color=border_color)

        # Draw the SIFT representation
        # pnum = pnum_(px + six.next(countgen))
        pnum = pnum_()
        sift_as_vecfield = ph.SIFT_OR_VECFIELD or vecfield
        if sift_as_vecfield:
            custom_figure.figure(fnum=fnum, pnum=pnum)
            df2.draw_keypoint_gradient_orientations(chip, kp, sift=sift)
        else:
            if sift.dtype.type == np.uint8:
                # sigtitle =  'sift histogram' if (px % 3) == 0 else ''
                # ax = df2.plot_sift_signature(sift, sigtitle, fnum=fnum, pnum=pnum)
                ax = df2.plot_sift_signature(sift, fnum=fnum, pnum=pnum)
            else:
                # sigtitle =  'descriptor vector' if (px % 3) == 0 else ''
                ax = df2.plot_descriptor_signature(sift, fnum=fnum, pnum=pnum)
            ax._hs_viztype = 'histogram'
        # dist_list = ['L1', 'L2', 'hist_isect', 'emd']
        # dist_list = ['L2', 'hist_isect']
        # dist_list = ['L2']
        # dist_list = ['bar_L2_sift', 'cos_sift']
        # dist_list = ['L2_sift', 'bar_cos_sift']
        dist_list = ['L2_sift']
        dist_str_list = []
        if origsift is not None:
            distmap_orig = vt.compute_distances(sift, origsift, dist_list)
            dist_str_list.append('query_dist: ' + ', '.join([
                '(%s, %s)' % (key, formatdist(val))
                for key, val in six.iteritems(distmap_orig)
            ]))
        if prevsift is not None:
            distmap_prev = vt.compute_distances(sift, prevsift, dist_list)
            dist_str_list.append('prev_dist: ' + ', '.join([
                '(%s, %s)' % (key, formatdist(val))
                for key, val in six.iteritems(distmap_prev)
            ]))
        dist_str = '\n'.join(dist_str_list)
        custom_figure.set_xlabel(dist_str)
    return px + nCols
Example #2
0
def get_training_desc_dist(cm, qreq_, fsv_col_lbls=[], namemode=True,
                           top_percent=None, data_annots=None,
                           query_annots=None, num=None):
    r"""
    computes custom distances on prematched descriptors

    SeeAlso:
        python -m ibeis --tf learn_featscore_normalizer --show --disttype=ratio

        python -m ibeis --tf learn_featscore_normalizer --show --disttype=normdist -a timectrl -t default:K=1 --db PZ_Master1 --save pzmaster_normdist.png
        python -m ibeis --tf learn_featscore_normalizer --show --disttype=normdist -a timectrl -t default:K=1 --db PZ_MTEST --save pzmtest_normdist.png
        python -m ibeis --tf learn_featscore_normalizer --show --disttype=normdist -a timectrl -t default:K=1 --db GZ_ALL

        python -m ibeis --tf learn_featscore_normalizer --show --disttype=L2_sift -a timectrl -t default:K=1 --db PZ_MTEST
        python -m ibeis --tf learn_featscore_normalizer --show --disttype=L2_sift -a timectrl -t default:K=1 --db PZ_Master1

        python -m ibeis --tf compare_featscores --show --disttype=L2_sift,normdist -a timectrl -t default:K=1 --db GZ_ALL

    CommandLine:
        python -m ibeis.algo.hots.scorenorm --exec-get_training_desc_dist
        python -m ibeis.algo.hots.scorenorm --exec-get_training_desc_dist:1

    Example:
        >>> # ENABLE_DOCTEST
        >>> from ibeis.algo.hots.scorenorm import *  # NOQA
        >>> import ibeis
        >>> cm, qreq_ = ibeis.testdata_cm(defaultdb='PZ_MTEST')
        >>> fsv_col_lbls = ['ratio', 'lnbnn', 'L2_sift']
        >>> namemode = False
        >>> (tp_fsv, tn_fsv) = get_training_desc_dist(cm, qreq_, fsv_col_lbls,
        >>>                                           namemode=namemode)
        >>> result = ut.repr2((tp_fsv.T, tn_fsv.T), nl=1)
        >>> print(result)

    Example1:
        >>> # ENABLE_DOCTEST
        >>> from ibeis.algo.hots.scorenorm import *  # NOQA
        >>> import ibeis
        >>> cm, qreq_ = ibeis.testdata_cm(defaultdb='PZ_MTEST')
        >>> fsv_col_lbls = cm.fsv_col_lbls
        >>> num = None
        >>> namemode = False
        >>> top_percent = None
        >>> data_annots = None
        >>> (tp_fsv1, tn_fsv1) = get_training_fsv(cm, namemode=namemode,
        >>>                                       top_percent=top_percent)
        >>> (tp_fsv, tn_fsv) = get_training_desc_dist(cm, qreq_, fsv_col_lbls,
        >>>                                           namemode=namemode,
        >>>                                           top_percent=top_percent)
        >>> vt.asserteq(tp_fsv1, tp_fsv)
        >>> vt.asserteq(tn_fsv1, tn_fsv)
    """
    if namemode:
        tp_idxs, tn_idxs = get_topname_training_idxs(cm, num=num)
    else:
        tp_idxs, tn_idxs = get_topannot_training_idxs(cm, num=num)

    if top_percent is not None:
        cm_orig = cm
        cm_orig.assert_self(qreq_, verbose=False)

        # Keep only the top scoring half of the feature matches
        tophalf_indicies = [
            ut.take_percentile(fs.argsort()[::-1], top_percent)
            for fs in cm.get_fsv_prod_list()
        ]
        cm = cm_orig.take_feature_matches(tophalf_indicies, keepscores=True)

        assert np.all(cm_orig.daid_list.take(tp_idxs) == cm.daid_list.take(tp_idxs))
        assert np.all(cm_orig.daid_list.take(tn_idxs) == cm.daid_list.take(tn_idxs))

        cm.assert_self(qreq_, verbose=False)

    ibs = qreq_.ibs
    query_config2_ = qreq_.extern_query_config2
    data_config2_ = qreq_.extern_data_config2
    special_xs, dist_xs = vt.index_partition(fsv_col_lbls, ['fg', 'ratio', 'lnbnn', 'normdist'])
    dist_lbls = ut.take(fsv_col_lbls, dist_xs)
    special_lbls = ut.take(fsv_col_lbls, special_xs)

    qaid = cm.qaid
    # cm.assert_self(qreq_=qreq_)

    fsv_list = []
    for idxs in [tp_idxs, tn_idxs]:
        daid_list = cm.daid_list.take(idxs)

        # Matching indices in query / databas images
        qfxs_list = ut.take(cm.qfxs_list, idxs)
        dfxs_list = ut.take(cm.dfxs_list, idxs)

        need_norm = len(ut.setintersect_ordered(['ratio', 'lnbnn', 'normdist'], special_lbls)) > 0
        #need_norm |= 'parzen' in special_lbls
        #need_norm |= 'norm_parzen' in special_lbls
        need_dists = len(dist_xs) > 0

        if need_dists or need_norm:
            qaid_list = [qaid] * len(qfxs_list)
            qvecs_flat_m = np.vstack(ibs.get_annot_vecs_subset(qaid_list, qfxs_list, config2_=query_config2_))
            dvecs_flat_m = np.vstack(ibs.get_annot_vecs_subset(daid_list, dfxs_list, config2_=data_config2_))

        if need_norm:
            assert any(x is not None for x in  cm.filtnorm_aids), 'no normalizer known'
            naids_list = ut.take(cm.naids_list, idxs)
            nfxs_list  = ut.take(cm.nfxs_list, idxs)
            nvecs_flat = ibs.lookup_annot_vecs_subset(naids_list, nfxs_list, config2_=data_config2_,
                                                      annots=data_annots)
            #import utool
            #with utool.embed_on_exception_context:
            #nvecs_flat_m = np.vstack(ut.compress(nvecs_flat, nvecs_flat))
            _nvecs_flat_m = ut.compress(nvecs_flat, nvecs_flat)
            nvecs_flat_m = vt.safe_vstack(_nvecs_flat_m, qvecs_flat_m.shape, qvecs_flat_m.dtype)

            vdist = vt.L2_sift(qvecs_flat_m, dvecs_flat_m)
            ndist = vt.L2_sift(qvecs_flat_m, nvecs_flat_m)

            #assert np.all(vdist <= ndist)
            #import utool
            #utool.embed()

            #vdist = vt.L2_sift_sqrd(qvecs_flat_m, dvecs_flat_m)
            #ndist = vt.L2_sift_sqrd(qvecs_flat_m, nvecs_flat_m)

            #vdist = vt.L2_root_sift(qvecs_flat_m, dvecs_flat_m)
            #ndist = vt.L2_root_sift(qvecs_flat_m, nvecs_flat_m)

            #x = cm.fsv_list[0][0:5].T[0]
            #y = (ndist - vdist)[0:5]

        if len(special_xs) > 0:
            special_dist_list = []
            # assert special_lbls[0] == 'fg'
            if 'fg' in special_lbls:
                # hack for fgweights (could get them directly from fsv)
                qfgweights_flat_m = np.hstack(ibs.get_annot_fgweights_subset([qaid] * len(qfxs_list), qfxs_list, config2_=query_config2_))
                dfgweights_flat_m = np.hstack(ibs.get_annot_fgweights_subset(daid_list, dfxs_list, config2_=data_config2_))
                fgweights = np.sqrt(qfgweights_flat_m * dfgweights_flat_m)
                special_dist_list.append(fgweights)

            if 'ratio' in special_lbls:
                # Integrating ratio test
                ratio_dist = (vdist / ndist)
                special_dist_list.append(ratio_dist)

            if 'lnbnn' in special_lbls:
                lnbnn_dist = ndist - vdist
                special_dist_list.append(lnbnn_dist)

            #if 'parzen' in special_lbls:
            #    parzen = vt.gauss_parzen_est(vdist, sigma=.38)
            #    special_dist_list.append(parzen)

            #if 'norm_parzen' in special_lbls:
            #    parzen = vt.gauss_parzen_est(ndist, sigma=.38)
            #    special_dist_list.append(parzen)

            if 'normdist' in special_lbls:
                special_dist_list.append(ndist)

            special_dists = np.vstack(special_dist_list).T
        else:
            special_dists = np.empty((0, 0))

        if len(dist_xs) > 0:
            # Get descriptors
            # Compute descriptor distnaces
            _dists = vt.compute_distances(qvecs_flat_m, dvecs_flat_m, dist_lbls)
            dists = np.vstack(_dists.values()).T
        else:
            dists = np.empty((0, 0))

        fsv = vt.rebuild_partition(special_dists.T, dists.T,
                                      special_xs, dist_xs)
        fsv = np.array(fsv).T
        fsv_list.append(fsv)
    tp_fsv, tn_fsv = fsv_list
    return tp_fsv, tn_fsv
Example #3
0
def draw_feat_row(
    chip,
    fx,
    kp,
    sift,
    fnum,
    nRows,
    nCols=None,
    px=None,
    prevsift=None,
    origsift=None,
    aid=None,
    info="",
    type_=None,
    shape_labels=False,
    vecfield=False,
    multicolored_arms=False,
    draw_chip=False,
    draw_warped=True,
    draw_unwarped=True,
    draw_desc=True,
    rect=True,
    ori=True,
    pts=False,
    **kwargs
):
    """
    draw_feat_row

    SeeAlso:
        ibeis.viz.viz_nearest_descriptors
        ~/code/ibeis/ibeis/viz/viz_nearest_descriptors.py

    CommandLine:

        # Use this to find the fx you want to visualize
        python -m plottool.interact_keypoints --test-ishow_keypoints --show --fname zebra.png

        # Use this to visualize the featrow
        python -m plottool.viz_featrow --test-draw_feat_row --show
        python -m plottool.viz_featrow --test-draw_feat_row --show --fname zebra.png --fx=121 --feat-all --no-sift
        python -m plottool.viz_featrow --test-draw_feat_row --dpath figures --save ~/latex/crall-candidacy-2015/figures/viz_featrow.jpg

    Example:
        >>> # DISABLE_DOCTEST
        >>> from plottool.viz_featrow import *  # NOQA
        >>> import plottool as pt
        >>> # build test data
        >>> kpts, vecs, imgBGR = pt.viz_keypoints.testdata_kpts()
        >>> chip = imgBGR
        >>> print('There are %d features' % (len(vecs)))
        >>> fx = ut.get_argval('--fx', type_=int, default=0)
        >>> kp = kpts[fx]
        >>> sift = vecs[fx]
        >>> fnum = 1
        >>> nRows = 1
        >>> nCols = 2
        >>> px = 0
        >>> hack = ut.get_argflag('--feat-all')
        >>> sift = sift if not ut.get_argflag('--no-sift') else None
        >>> draw_desc = sift is not None
        >>> kw = dict(
        >>>     prevsift=None, origsift=None, aid=None, info='', type_=None,
        >>>     shape_labels=False, vecfield=False, multicolored_arms=True,
        >>>     draw_chip=hack, draw_unwarped=hack, draw_warped=True, draw_desc=draw_desc
        >>> )
        >>> # execute function
        >>> result = draw_feat_row(chip, fx, kp, sift, fnum, nRows, nCols, px,
        >>>                           rect=False, ori=False, pts=False, **kw)
        >>> # verify results
        >>> print(result)
        >>> pt.show_if_requested()
    """
    import numpy as np
    import vtool as vt

    # should not need ncols here

    if nCols is not None:
        if ut.VERBOSE:
            print("Warning nCols is no longer needed")
    # assert nCols_ == nCols
    nCols = draw_chip + draw_unwarped + draw_warped + draw_desc

    pnum_ = df2.make_pnum_nextgen(nRows, nCols, start=px)

    # pnum_ = df2.get_pnum_func(nRows, nCols, base=1)
    # countgen = itertools.count(1)

    # pnumgen_ = df2.make_pnum_nextgen(nRows, nCols, base=1)

    def _draw_patch(**kwargs):
        return df2.draw_keypoint_patch(
            chip,
            kp,
            sift,
            rect=rect,
            ori=ori,
            pts=pts,
            ori_color=custom_constants.DEEP_PINK,
            multicolored_arms=multicolored_arms,
            **kwargs
        )

    # Feature strings
    xy_str, shape_str, scale, ori_str = ph.kp_info(kp)

    if draw_chip:
        pnum = pnum_()
        df2.imshow(chip, fnum=fnum, pnum=pnum)
        kpts_kw = dict(ell_linewidth=5, ell_alpha=1.0)
        kpts_kw.update(kwargs)
        df2.draw_kpts2([kp], **kpts_kw)

    if draw_unwarped:
        # Draw the unwarped selected feature
        # ax = _draw_patch(fnum=fnum, pnum=pnum_(px + six.next(countgen)))
        # pnum = pnum_(px + six.next(countgen)
        pnum = pnum_()
        ax = _draw_patch(fnum=fnum, pnum=pnum)
        ph.set_plotdat(ax, "viztype", "unwarped")
        ph.set_plotdat(ax, "aid", aid)
        ph.set_plotdat(ax, "fx", fx)
        if shape_labels:
            unwarped_lbl = "affine feature invV =\n" + shape_str + "\n" + ori_str
            custom_figure.set_xlabel(unwarped_lbl, ax)

    if draw_warped:
        # Draw the warped selected feature
        # ax = _draw_patch(fnum=fnum, pnum=pnum_(px + six.next(countgen)), warped=True)
        pnum = pnum_()
        ax = _draw_patch(fnum=fnum, pnum=pnum, warped=True, **kwargs)
        ph.set_plotdat(ax, "viztype", "warped")
        ph.set_plotdat(ax, "aid", aid)
        ph.set_plotdat(ax, "fx", fx)
        if shape_labels:
            warped_lbl = ("warped feature\n" + "fx=%r scale=%.1f\n" + "%s") % (fx, scale, xy_str)
        else:
            warped_lbl = ""
        warped_lbl += info
        custom_figure.set_xlabel(warped_lbl, ax)

    if draw_desc:
        border_color = {
            "None": None,
            "query": None,
            "match": custom_constants.BLUE,
            "norm": custom_constants.ORANGE,
        }.get(str(type_).lower(), None)
        if border_color is not None:
            df2.draw_border(ax, color=border_color)

        # Draw the SIFT representation
        # pnum = pnum_(px + six.next(countgen))
        pnum = pnum_()
        sift_as_vecfield = ph.SIFT_OR_VECFIELD or vecfield
        if sift_as_vecfield:
            custom_figure.figure(fnum=fnum, pnum=pnum)
            df2.draw_keypoint_gradient_orientations(chip, kp, sift=sift)
        else:
            if sift.dtype.type == np.uint8:
                sigtitle = "sift histogram" if (px % 3) == 0 else ""
                ax = df2.plot_sift_signature(sift, sigtitle, fnum=fnum, pnum=pnum)
            else:
                sigtitle = "descriptor vector" if (px % 3) == 0 else ""
                ax = df2.plot_descriptor_signature(sift, sigtitle, fnum=fnum, pnum=pnum)
            ax._hs_viztype = "histogram"
        # dist_list = ['L1', 'L2', 'hist_isect', 'emd']
        # dist_list = ['L2', 'hist_isect']
        # dist_list = ['L2']
        # dist_list = ['bar_L2_sift', 'cos_sift']
        # dist_list = ['L2_sift', 'bar_cos_sift']
        dist_list = ["L2_sift"]
        dist_str_list = []
        if origsift is not None:
            distmap_orig = vt.compute_distances(sift, origsift, dist_list)
            dist_str_list.append(
                "query_dist: "
                + ", ".join(["(%s, %s)" % (key, formatdist(val)) for key, val in six.iteritems(distmap_orig)])
            )
        if prevsift is not None:
            distmap_prev = vt.compute_distances(sift, prevsift, dist_list)
            dist_str_list.append(
                "prev_dist: "
                + ", ".join(["(%s, %s)" % (key, formatdist(val)) for key, val in six.iteritems(distmap_prev)])
            )
        dist_str = "\n".join(dist_str_list)
        custom_figure.set_xlabel(dist_str)
    return px + nCols
Example #4
0
def get_orgres_desc_match_dists(allres, orgtype_list=['false', 'true'],
                                distkey_list=['L2'],
                                verbose=True):
    r"""
    computes distances between matching descriptors of orgtypes in allres

    Args:
        allres (AllResults): AllResults object
        orgtype_list (list): of strings denoting the type of results to compare
        distkey_list (list): list of requested distance types

    Returns:
        dict: orgres2_descmatch_dists mapping from orgtype to dicts of distances (ndarrays)

    Notes:
        Just SIFT distance seems to have a very interesting property

    CommandLine:
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --show
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_Master0 --show
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_Master0 --distkeys=fs,lnbnn,bar_L2_sift --show
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_MTEST --distkeys=fs,lnbnn,bar_L2_sift,cos_sift --show
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_Master0 --distkeys=fs,lnbnn,bar_L2_sift,cos_sift --show
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_MTEST --distkeys=cos_sift --show
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_Master0 --distkeys=fs,lnbnn,bar_L2_sift,cos_sift --show --nosupport

        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_MTEST --distkeys=lnbnn --show --feat_type=hesaff+siam128
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_MTEST --distkeys=lnbnn --show --feat_type=hesaff+sift

        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_MTEST --distkeys=lnbnn --show --feat_type=hesaff+sift --num-top-fs=2
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_MTEST --distkeys=lnbnn --show --feat_type=hesaff+sift --num-top-fs=10
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_MTEST --distkeys=lnbnn --show --feat_type=hesaff+sift --num-top-fs=1000
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_MTEST --distkeys=lnbnn --show --feat_type=hesaff+siam128 --num-top-fs=1

    Example:
        >>> # SLOW_DOCTEST
        >>> from ibeis.expt.results_analyzer import *  # NOQA
        >>> from ibeis.expt import results_all
        >>> import ibeis
        >>> ibs = ibeis.opendb(defaultdb='PZ_MTEST')
        >>> qaid_list = ibs.get_valid_aids(hasgt=True)
        >>> from ibeis.model import Config
        >>> cfgdict = ut.argparse_dict(dict(Config.parse_config_items(Config.QueryConfig())), only_specified=True)
        >>> allres = results_all.get_allres(ibs, qaid_list, cfgdict=cfgdict)
        >>> # {'feat_type': 'hesaff+siam128'})
        >>> orgtype_list = ['false', 'top_true']
        >>> verbose = True
        >>> distkey_list = ut.get_argval('--distkeys', type_=list, default=['fs', 'lnbnn', 'bar_L2_sift'])
        >>> #distkey_list = ['hist_isect']
        >>> #distkey_list = ['L2_sift', 'bar_L2_sift']
        >>> # execute function
        >>> orgres2_descmatch_dists = get_orgres_desc_match_dists(allres, orgtype_list, distkey_list, verbose)
        >>> #print('orgres2_descmatch_dists = ' + ut.dict_str(orgres2_descmatch_dists, truncate=-1, precision=3))
        >>> stats_ = {key: ut.dict_val_map(val, ut.get_stats) for key, val in orgres2_descmatch_dists.items()}
        >>> print('orgres2_descmatch_dists = ' + ut.dict_str(stats_, truncate=2, precision=3, nl=4))
        >>> # ------ VISUALIZE ------------
        >>> ut.quit_if_noshow()
        >>> import vtool as vt
        >>> # If viewing a large amount of data this might help on OverFlowError
        >>> #ut.embed()
        >>> # http://stackoverflow.com/questions/20330475/matplotlib-overflowerror-allocated-too-many-blocks
        >>> # http://matplotlib.org/1.3.1/users/customizing.html
        >>> limit_ = len(qaid_list) > 100
        >>> if limit_ or True:
        >>>     import matplotlib as mpl
        >>>     mpl.rcParams['agg.path.chunksize'] = 100000
        >>> # visualize the descriptor scores
        >>> for fnum, distkey in enumerate(distkey_list, start=1):
        >>>     encoder = vt.ScoreNormalizer()
        >>>     tn_scores, tp_scores = ut.get_list_column(ut.dict_take(orgres2_descmatch_dists, orgtype_list), distkey)
        >>>     encoder.fit_partitioned(tp_scores, tn_scores, verbose=False)
        >>>     figtitle = 'Descriptor Distance: %r. db=%r\norgtype_list=%r' % (distkey, ibs.get_dbname(), orgtype_list)
        >>>     use_support = not ut.get_argflag('--nosupport')
        >>>     encoder.visualize(figtitle=figtitle, use_stems=not limit_, fnum=fnum, with_normscore=use_support, with_scores=use_support)
        >>> ut.show_if_requested()
    """
    import vtool as vt
    orgres2_descmatch_dists = {}
    desc_dist_xs, other_xs = vt.index_partition(distkey_list, vt.VALID_DISTS)
    distkey_list1 = ut.list_take(distkey_list, desc_dist_xs)
    distkey_list2 = ut.list_take(distkey_list, other_xs)

    for orgtype in orgtype_list:
        if verbose:
            print('[rr2] getting orgtype=%r distances between vecs' % orgtype)
        orgres = allres.get_orgtype(orgtype)
        qaids = orgres.qaids
        aids  = orgres.aids
        # DO distance that need real computation
        if len(desc_dist_xs) > 0:
            try:
                stacked_qvecs, stacked_dvecs = get_matching_descriptors(allres, qaids, aids)
            except Exception as ex:
                orgres.printme3()
                ut.printex(ex)
                raise
            if verbose:
                print('[rr2]  * stacked_qvecs.shape = %r' % (stacked_qvecs.shape,))
                print('[rr2]  * stacked_dvecs.shape = %r' % (stacked_dvecs.shape,))
            #distkey_list = ['L1', 'L2', 'hist_isect', 'emd']
            #distkey_list = ['L1', 'L2', 'hist_isect']
            #distkey_list = ['L2', 'hist_isect']
            hist1 = np.asarray(stacked_qvecs, dtype=np.float32)
            hist2 = np.asarray(stacked_dvecs, dtype=np.float32)
            # returns an ordered dictionary
            distances1 = vt.compute_distances(hist1, hist2, distkey_list1)
        else:
            distances1 = {}
        # DO precomputed distances like fs (true weights) or lnbnn
        if len(other_xs) > 0:
            distances2 = ut.odict([(disttype, []) for disttype in distkey_list2])
            for qaid, daid in zip(qaids, aids):
                try:
                    qres = allres.qaid2_qres[qaid]
                    for disttype in distkey_list2:
                        if disttype == 'fs':
                            # hack in full fs
                            assert disttype == 'fs', 'unimplemented'
                            vals = qres.aid2_fs[daid]
                        else:
                            assert disttype in qres.filtkey_list, 'no score labeled %' % (disttype,)
                            index = qres.filtkey_list.index(disttype)
                            vals = qres.aid2_fsv[daid].T[index]
                        if len(vals) == 0:
                            continue
                        else:
                            # individual score component
                            pass
                        #num_top_vec_scores = None
                        num_top_vec_scores = ut.get_argval('--num-top-fs', type_=int, default=None)
                        if num_top_vec_scores is not None:
                            # Take only the best matching descriptor scores for each pair in this analysis
                            # This tries to see how deperable the BEST descriptor score is for each match
                            vals = vals[vals.argsort()[::-1][0:num_top_vec_scores]]
                            vals = vals[vals.argsort()[::-1][0:num_top_vec_scores]]
                        distances2[disttype].extend(vals)
                except KeyError:
                    continue
            # convert to numpy array
            for disttype in distkey_list2:
                distances2[disttype] = np.array(distances2[disttype])
        else:
            distances2 = {}
        # Put things back in expected order
        dist1_vals = ut.dict_take(distances1, distkey_list1)
        dist2_vals = ut.dict_take(distances2, distkey_list2)
        dist_vals = vt.rebuild_partition(dist1_vals, dist2_vals, desc_dist_xs, other_xs)
        distances = ut.odict(list(zip(distkey_list, dist_vals)))
        orgres2_descmatch_dists[orgtype] = distances
    return orgres2_descmatch_dists
Example #5
0
def get_orgres_desc_match_dists(allres,
                                orgtype_list=['false', 'true'],
                                distkey_list=['L2'],
                                verbose=True):
    r"""
    computes distances between matching descriptors of orgtypes in allres

    Args:
        allres (AllResults): AllResults object
        orgtype_list (list): of strings denoting the type of results to compare
        distkey_list (list): list of requested distance types

    Returns:
        dict: orgres2_descmatch_dists mapping from orgtype to dicts of distances (ndarrays)

    Notes:
        Just SIFT distance seems to have a very interesting property

    CommandLine:
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --show
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_Master0 --show
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_Master0 --distkeys=fs,lnbnn,bar_L2_sift --show
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_MTEST --distkeys=fs,lnbnn,bar_L2_sift,cos_sift --show
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_Master0 --distkeys=fs,lnbnn,bar_L2_sift,cos_sift --show
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_MTEST --distkeys=cos_sift --show
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_Master0 --distkeys=fs,lnbnn,bar_L2_sift,cos_sift --show --nosupport

        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_MTEST --distkeys=lnbnn --show --feat_type=hesaff+siam128
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_MTEST --distkeys=lnbnn --show --feat_type=hesaff+sift

        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_MTEST --distkeys=lnbnn --show --feat_type=hesaff+sift --num-top-fs=2
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_MTEST --distkeys=lnbnn --show --feat_type=hesaff+sift --num-top-fs=10
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_MTEST --distkeys=lnbnn --show --feat_type=hesaff+sift --num-top-fs=1000
        python -m ibeis.expt.results_analyzer --test-get_orgres_desc_match_dists --db PZ_MTEST --distkeys=lnbnn --show --feat_type=hesaff+siam128 --num-top-fs=1

    Example:
        >>> # SLOW_DOCTEST
        >>> from ibeis.expt.results_analyzer import *  # NOQA
        >>> from ibeis.expt import results_all
        >>> import ibeis
        >>> ibs = ibeis.opendb(defaultdb='PZ_MTEST')
        >>> qaid_list = ibs.get_valid_aids(hasgt=True)
        >>> from ibeis.model import Config
        >>> cfgdict = ut.argparse_dict(dict(Config.parse_config_items(Config.QueryConfig())), only_specified=True)
        >>> allres = results_all.get_allres(ibs, qaid_list, cfgdict=cfgdict)
        >>> # {'feat_type': 'hesaff+siam128'})
        >>> orgtype_list = ['false', 'top_true']
        >>> verbose = True
        >>> distkey_list = ut.get_argval('--distkeys', type_=list, default=['fs', 'lnbnn', 'bar_L2_sift'])
        >>> #distkey_list = ['hist_isect']
        >>> #distkey_list = ['L2_sift', 'bar_L2_sift']
        >>> # execute function
        >>> orgres2_descmatch_dists = get_orgres_desc_match_dists(allres, orgtype_list, distkey_list, verbose)
        >>> #print('orgres2_descmatch_dists = ' + ut.dict_str(orgres2_descmatch_dists, truncate=-1, precision=3))
        >>> stats_ = {key: ut.dict_val_map(val, ut.get_stats) for key, val in orgres2_descmatch_dists.items()}
        >>> print('orgres2_descmatch_dists = ' + ut.dict_str(stats_, truncate=2, precision=3, nl=4))
        >>> # ------ VISUALIZE ------------
        >>> ut.quit_if_noshow()
        >>> import vtool as vt
        >>> # If viewing a large amount of data this might help on OverFlowError
        >>> #ut.embed()
        >>> # http://stackoverflow.com/questions/20330475/matplotlib-overflowerror-allocated-too-many-blocks
        >>> # http://matplotlib.org/1.3.1/users/customizing.html
        >>> limit_ = len(qaid_list) > 100
        >>> if limit_ or True:
        >>>     import matplotlib as mpl
        >>>     mpl.rcParams['agg.path.chunksize'] = 100000
        >>> # visualize the descriptor scores
        >>> for fnum, distkey in enumerate(distkey_list, start=1):
        >>>     encoder = vt.ScoreNormalizer()
        >>>     tn_scores, tp_scores = ut.get_list_column(ut.dict_take(orgres2_descmatch_dists, orgtype_list), distkey)
        >>>     encoder.fit_partitioned(tp_scores, tn_scores, verbose=False)
        >>>     figtitle = 'Descriptor Distance: %r. db=%r\norgtype_list=%r' % (distkey, ibs.get_dbname(), orgtype_list)
        >>>     use_support = not ut.get_argflag('--nosupport')
        >>>     encoder.visualize(figtitle=figtitle, use_stems=not limit_, fnum=fnum, with_normscore=use_support, with_scores=use_support)
        >>> ut.show_if_requested()
    """
    import vtool as vt
    orgres2_descmatch_dists = {}
    desc_dist_xs, other_xs = vt.index_partition(distkey_list, vt.VALID_DISTS)
    distkey_list1 = ut.list_take(distkey_list, desc_dist_xs)
    distkey_list2 = ut.list_take(distkey_list, other_xs)

    for orgtype in orgtype_list:
        if verbose:
            print('[rr2] getting orgtype=%r distances between vecs' % orgtype)
        orgres = allres.get_orgtype(orgtype)
        qaids = orgres.qaids
        aids = orgres.aids
        # DO distance that need real computation
        if len(desc_dist_xs) > 0:
            try:
                stacked_qvecs, stacked_dvecs = get_matching_descriptors(
                    allres, qaids, aids)
            except Exception as ex:
                orgres.printme3()
                ut.printex(ex)
                raise
            if verbose:
                print('[rr2]  * stacked_qvecs.shape = %r' %
                      (stacked_qvecs.shape, ))
                print('[rr2]  * stacked_dvecs.shape = %r' %
                      (stacked_dvecs.shape, ))
            #distkey_list = ['L1', 'L2', 'hist_isect', 'emd']
            #distkey_list = ['L1', 'L2', 'hist_isect']
            #distkey_list = ['L2', 'hist_isect']
            hist1 = np.asarray(stacked_qvecs, dtype=np.float32)
            hist2 = np.asarray(stacked_dvecs, dtype=np.float32)
            # returns an ordered dictionary
            distances1 = vt.compute_distances(hist1, hist2, distkey_list1)
        else:
            distances1 = {}
        # DO precomputed distances like fs (true weights) or lnbnn
        if len(other_xs) > 0:
            distances2 = ut.odict([(disttype, [])
                                   for disttype in distkey_list2])
            for qaid, daid in zip(qaids, aids):
                try:
                    qres = allres.qaid2_qres[qaid]
                    for disttype in distkey_list2:
                        if disttype == 'fs':
                            # hack in full fs
                            assert disttype == 'fs', 'unimplemented'
                            vals = qres.aid2_fs[daid]
                        else:
                            assert disttype in qres.filtkey_list, 'no score labeled %' % (
                                disttype, )
                            index = qres.filtkey_list.index(disttype)
                            vals = qres.aid2_fsv[daid].T[index]
                        if len(vals) == 0:
                            continue
                        else:
                            # individual score component
                            pass
                        #num_top_vec_scores = None
                        num_top_vec_scores = ut.get_argval('--num-top-fs',
                                                           type_=int,
                                                           default=None)
                        if num_top_vec_scores is not None:
                            # Take only the best matching descriptor scores for each pair in this analysis
                            # This tries to see how deperable the BEST descriptor score is for each match
                            vals = vals[vals.argsort()[::-1]
                                        [0:num_top_vec_scores]]
                            vals = vals[vals.argsort()[::-1]
                                        [0:num_top_vec_scores]]
                        distances2[disttype].extend(vals)
                except KeyError:
                    continue
            # convert to numpy array
            for disttype in distkey_list2:
                distances2[disttype] = np.array(distances2[disttype])
        else:
            distances2 = {}
        # Put things back in expected order
        dist1_vals = ut.dict_take(distances1, distkey_list1)
        dist2_vals = ut.dict_take(distances2, distkey_list2)
        dist_vals = vt.rebuild_partition(dist1_vals, dist2_vals, desc_dist_xs,
                                         other_xs)
        distances = ut.odict(list(zip(distkey_list, dist_vals)))
        orgres2_descmatch_dists[orgtype] = distances
    return orgres2_descmatch_dists