Пример #1
0
def get_namescore_nonvoting_feature_flags(fm_list, fs_list, dnid_list, name_groupxs, kpts1=None):
    r"""
    fm_list = [fm[:min(len(fm), 10)] for fm in fm_list]
    fs_list = [fs[:min(len(fs), 10)] for fs in fs_list]
    """
    fx1_list = [fm.T[0] for fm in fm_list]
    # Group annotation matches by name
    name_grouped_fx1_list = vt.apply_grouping_(fx1_list, name_groupxs)
    name_grouped_fs_list  = vt.apply_grouping_(fs_list,  name_groupxs)
    # Stack up all matches to a particular name, keep track of original indicies via offets
    name_invertable_flat_fx1_list = list(map(ut.invertible_flatten2_numpy, name_grouped_fx1_list))
    name_grouped_fx1_flat = ut.get_list_column(name_invertable_flat_fx1_list, 0)
    name_grouped_invertable_cumsum_list = ut.get_list_column(name_invertable_flat_fx1_list, 1)
    name_grouped_fs_flat = list(map(np.hstack, name_grouped_fs_list))
    if kpts1 is not None:
        xys1_ = vt.get_xys(kpts1).T
        kpts_xyid_list = vt.compute_unique_data_ids(xys1_)
        # Make nested group for every name by query feature index (accounting for duplicate orientation)
        name_grouped_xyid_flat = list(kpts_xyid_list.take(fx1) for fx1 in name_grouped_fx1_flat)
        xyid_groupxs_list = list(vt.group_indices(xyid_flat)[1] for xyid_flat in name_grouped_xyid_flat)
        name_group_fx1_groupxs_list = xyid_groupxs_list
    else:
        # Make nested group for every name by query feature index
        fx1_groupxs_list = [vt.group_indices(fx1_flat)[1] for fx1_flat in name_grouped_fx1_flat]
        name_group_fx1_groupxs_list = fx1_groupxs_list
    name_grouped_fid_grouped_fs_list = [
        vt.apply_grouping(fs_flat, fid_groupxs)
        for fs_flat, fid_groupxs in zip(name_grouped_fs_flat, name_group_fx1_groupxs_list)
    ]

    # Flag which features are valid in this grouped space. Only one keypoint should be able to vote
    # for each group
    name_grouped_fid_grouped_isvalid_list = [
        np.array([fs_group.max() == fs_group for fs_group in fid_grouped_fs_list])
        for fid_grouped_fs_list in name_grouped_fid_grouped_fs_list
    ]

    # Go back to being grouped only in name space
    #dtype = np.bool
    name_grouped_isvalid_flat_list = [
        vt.invert_apply_grouping2(fid_grouped_isvalid_list, fid_groupxs, dtype=np.bool)
        for fid_grouped_isvalid_list, fid_groupxs in zip(name_grouped_fid_grouped_isvalid_list, name_group_fx1_groupxs_list)
    ]

    name_grouped_isvalid_unflat_list = [
        ut.unflatten2(isvalid_flat, invertable_cumsum_list)
        for isvalid_flat, invertable_cumsum_list in zip(name_grouped_isvalid_flat_list, name_grouped_invertable_cumsum_list)
    ]

    # Reports which features were valid in name scoring for every annotation
    featflag_list = vt.invert_apply_grouping(name_grouped_isvalid_unflat_list, name_groupxs)
    return featflag_list
Пример #2
0
def general_name_coverage_mask_generator(make_mask_func, qreq_, cm, config,
                                         cov_cfg):
    """
    DEPRICATE

    Yeilds:
        nid, weight_mask_m, weight_mask

    CommandLine:
        python -m wbia.algo.hots.scoring --test-general_name_coverage_mask_generator --show
        python -m wbia.algo.hots.scoring --test-general_name_coverage_mask_generator --show --qaid 18

    Note:
        Evaluate output one at a time or it will get clobbered

    Example0:
        >>> # SLOW_DOCTEST
        >>> # (IMPORTANT)
        >>> from wbia.algo.hots.scoring import *  # NOQA
        >>> qreq_, cm = plh.testdata_scoring('PZ_MTEST', qaid_list=[18])
        >>> config = qreq_.qparams
        >>> make_mask_func, cov_cfg = get_mask_func(config)
        >>> masks_iter = general_name_coverage_mask_generator(make_mask_func, qreq_, cm, config, cov_cfg)
        >>> dnid_list, score_list, masks_list = evaluate_masks_iter(masks_iter)
        >>> ut.quit_if_noshow()
        >>> nidx = np.where(dnid_list == cm.qnid)[0][0]
        >>> daids = cm.get_groundtruth_daids()
        >>> dnid, weight_mask_m, weight_mask = masks_list[nidx]
        >>> show_single_coverage_mask(qreq_, cm, weight_mask_m, weight_mask, daids)
        >>> ut.show_if_requested()
    """
    import vtool as vt

    if ut.VERYVERBOSE:
        logger.info('[ncov] make_mask_func = %r' % (make_mask_func, ))
        logger.info('[ncov] cov_cfg = %s' % (ut.repr2(cov_cfg), ))
    assert cm.dnid_list is not None, 'eval nids'
    unique_dnids, groupxs = vt.group_indices(cm.dnid_list)
    fm_groups = vt.apply_grouping_(cm.fm_list, groupxs)
    fs_groups = vt.apply_grouping_(cm.fs_list, groupxs)
    fs_name_list = [np.hstack(fs_group) for fs_group in fs_groups]
    fm_name_list = [np.vstack(fm_group) for fm_group in fm_groups]
    return general_coverage_mask_generator(
        make_mask_func,
        qreq_,
        cm.qaid,
        unique_dnids,
        fm_name_list,
        fs_name_list,
        config,
        cov_cfg,
    )
Пример #3
0
def compute_nsum_score2(cm, qreq_=None):
    r"""
    Example3:
        >>> # DISABLE_DOCTEST
        >>> from ibeis.algo.hots.name_scoring import *  # NOQA
        >>> #ibs, qreq_, cm_list = plh.testdata_pre_sver('testdb1', qaid_list=[1])
        >>> ibs, qreq_, cm_list = plh.testdata_post_sver('testdb1', qaid_list=[1], cfgdict=dict(fg_on=False, augment_queryside_hack=True))
        >>> cm = cm_list[0]
        >>> cm.evaluate_dnids(qreq_.ibs)
        >>> nsum_nid_list1, nsum_score_list1, featflag_list1 = compute_nsum_score2(cm, qreq_)
        >>> nsum_nid_list2, nsum_score_list2 = compute_nsum_score(cm, qreq_)
        >>> ut.quit_if_noshow()
        >>> cm.show_ranked_matches(qreq_, ori=True)
    """
    featflag_list2 = get_chipmatch_namescore_nonvoting_feature_flags(cm, qreq_)
    fs_list = cm.get_fsv_prod_list()
    name_groupxs2 = cm.name_groupxs
    nsum_nid_list2 = cm.unique_nids
    #--
    valid_fs_list2 = vt.zipcompress(fs_list, featflag_list2)
    name_grouped_valid_fs_list2 = vt.apply_grouping_(valid_fs_list2,  name_groupxs2)
    nsum_score_list2 = np.array([sum(list(map(np.sum, valid_fs_group)))
                                 for valid_fs_group in name_grouped_valid_fs_list2])
    if False:
        nsum_score_list3 = np.array([  # NOQA
            np.sum([fs_group.sum() for fs_group in valid_fs_group])
            for valid_fs_group in name_grouped_valid_fs_list2])
    return nsum_nid_list2, nsum_score_list2, featflag_list2
Пример #4
0
def general_name_coverage_mask_generator(make_mask_func, qreq_, cm, config, cov_cfg):
    """
    Yeilds:
        nid, weight_mask_m, weight_mask

    CommandLine:
        python -m ibeis.algo.hots.scoring --test-general_name_coverage_mask_generator --show
        python -m ibeis.algo.hots.scoring --test-general_name_coverage_mask_generator --show --qaid 18

    Note:
        Evaluate output one at a time or it will get clobbered

    Example0:
        >>> # SLOW_DOCTEST
        >>> # (IMPORTANT)
        >>> from ibeis.algo.hots.scoring import *  # NOQA
        >>> qreq_, cm = plh.testdata_scoring('PZ_MTEST', qaid_list=[18])
        >>> config = qreq_.qparams
        >>> make_mask_func, cov_cfg = get_mask_func(config)
        >>> masks_iter = general_name_coverage_mask_generator(make_mask_func, qreq_, cm, config, cov_cfg)
        >>> dnid_list, score_list, masks_list = evaluate_masks_iter(masks_iter)
        >>> ut.quit_if_noshow()
        >>> nidx = np.where(dnid_list == cm.qnid)[0][0]
        >>> daids = cm.get_groundtruth_daids()
        >>> dnid, weight_mask_m, weight_mask = masks_list[nidx]
        >>> show_single_coverage_mask(qreq_, cm, weight_mask_m, weight_mask, daids)
        >>> ut.show_if_requested()
    """
    if ut.VERYVERBOSE:
        print('[ncov] make_mask_func = %r' % (make_mask_func,))
        print('[ncov] cov_cfg = %s' % (ut.dict_str(cov_cfg),))
    assert cm.dnid_list is not None, 'eval nids'
    unique_dnids, groupxs = vt.group_indices(cm.dnid_list)
    fm_groups = vt.apply_grouping_(cm.fm_list, groupxs)
    fs_groups = vt.apply_grouping_(cm.fs_list, groupxs)
    fs_name_list = [np.hstack(fs_group) for fs_group in fs_groups]
    fm_name_list = [np.vstack(fm_group) for fm_group in fm_groups]
    return general_coverage_mask_generator(make_mask_func, qreq_, cm.qaid, unique_dnids, fm_name_list, fs_name_list, config, cov_cfg)
Пример #5
0
def compute_nsum_score(cm, qreq_=None):
    r"""
    nsum

    Args:
        cm (ibeis.ChipMatch):

    Returns:
        tuple: (unique_nids, nsum_score_list)

    CommandLine:
        python -m ibeis.algo.hots.name_scoring --test-compute_nsum_score
        python -m ibeis.algo.hots.name_scoring --test-compute_nsum_score:0
        python -m ibeis.algo.hots.name_scoring --test-compute_nsum_score:2
        utprof.py -m ibeis.algo.hots.name_scoring --test-compute_nsum_score:2
        utprof.py -m ibeis.algo.hots.pipeline --test-request_ibeis_query_L0:0 --db PZ_Master1 -a timectrl:qindex=0:256

    Example0:
        >>> # ENABLE_DOCTEST
        >>> from ibeis.algo.hots.name_scoring import *  # NOQA
        >>> # build test data
        >>> cm = testdata_chipmatch()
        >>> # execute function
        >>> (unique_nids, nsum_score_list) = compute_nsum_score(cm)
        >>> result = ut.list_str((unique_nids, nsum_score_list), label_list=['unique_nids', 'nsum_score_list'], with_dtype=False)
        >>> print(result)
        unique_nids = np.array([1, 2, 3])
        nsum_score_list = np.array([ 4.,  7.,  5.])

    Example1:
        >>> # ENABLE_DOCTEST
        >>> from ibeis.algo.hots.name_scoring import *  # NOQA
        >>> #ibs, qreq_, cm_list = plh.testdata_pre_sver('testdb1', qaid_list=[1])
        >>> ibs, qreq_, cm_list = plh.testdata_post_sver('PZ_MTEST', qaid_list=[18])
        >>> cm = cm_list[0]
        >>> cm.evaluate_dnids(qreq_.ibs)
        >>> cm._cast_scores()
        >>> #cm.qnid = 1   # Hack for testdb1 names
        >>> nsum_nid_list, nsum_score_list = compute_nsum_score(cm, qreq_)
        >>> assert np.all(nsum_nid_list == cm.unique_nids), 'nids out of alignment'
        >>> flags = (nsum_nid_list == cm.qnid)
        >>> max_true = nsum_score_list[flags].max()
        >>> max_false = nsum_score_list[~flags].max()
        >>> assert max_true > max_false, 'is this truely a hard case?'
        >>> assert max_true > 1.2, 'score=%r should be higher for aid=18' % (max_true,)
        >>> nsum_nid_list2, nsum_score_list2, _ = compute_nsum_score2(cm, qreq_)
        >>> assert np.allclose(nsum_score_list2, nsum_score_list), 'something is very wrong'
        >>> #assert np.all(nsum_score_list2 == nsum_score_list), 'could be a percision issue'

    Example2:
        >>> # ENABLE_DOCTEST
        >>> from ibeis.algo.hots.name_scoring import *  # NOQA
        >>> #ibs, qreq_, cm_list = plh.testdata_pre_sver('testdb1', qaid_list=[1])
        >>> ibs, qreq_, cm_list = plh.testdata_post_sver('PZ_MTEST', qaid_list=[18], cfgdict=dict(augment_queryside_hack=True))
        >>> cm = cm_list[0]
        >>> cm.score_nsum(qreq_)
        >>> #cm.evaluate_dnids(qreq_.ibs)
        >>> #cm.qnid = 1   # Hack for testdb1 names
        >>> #nsum_nid_list, nsum_score_list = compute_nsum_score(cm, qreq_=qreq_)
        >>> ut.quit_if_noshow()
        >>> cm.show_ranked_matches(qreq_, ori=True)

    Example3:
        >>> # DISABLE_DOCTEST
        >>> from ibeis.algo.hots.name_scoring import *  # NOQA
        >>> #ibs, qreq_, cm_list = plh.testdata_pre_sver('testdb1', qaid_list=[1])
        >>> ibs, qreq_, cm_list = plh.testdata_post_sver('testdb1', qaid_list=[1], cfgdict=dict(augment_queryside_hack=True))
        >>> cm = cm_list[0]
        >>> cm.score_nsum(qreq_)
        >>> #cm.evaluate_dnids(qreq_.ibs)
        >>> #cm.qnid = 1   # Hack for testdb1 names
        >>> #nsum_nid_list, nsum_score_list = compute_nsum_score(cm, qreq_=qreq_)
        >>> ut.quit_if_noshow()
        >>> cm.show_ranked_matches(qreq_, ori=True)

    Example4:
        >>> # ENABLE_DOCTEST
        >>> # FIXME: breaks when fg_on=True
        >>> from ibeis.algo.hots.name_scoring import *  # NOQA
        >>> from ibeis.algo.hots import name_scoring
        >>> from ibeis.algo.hots import scoring
        >>> import ibeis
        >>> # Test to make sure name score and chips score are equal when per_name=1
        >>> qreq_, args = plh.testdata_pre(
        >>>     'spatial_verification', defaultdb='PZ_MTEST',
        >>>     a=['default:dpername=1,qsize=1,dsize=10'],
        >>>     p=['default:K=1,fg_on=True,sqrd_dist_on=True'])
        >>> cm = args.cm_list_FILT[0]
        >>> ibs = qreq_.ibs
        >>> # Ensure there is only one aid per database name
        >>> assert isinstance(ibs, ibeis.control.IBEISControl.IBEISController)
        >>> #stats_dict = ibs.get_annot_stats_dict(qreq_.get_external_daids(), prefix='d')
        >>> #stats = stats_dict['dper_name']
        >>> stats = ibs.get_annot_per_name_stats(qreq_.get_external_daids())
        >>> print('per_name_stats = %s' % (ut.dict_str(stats, nl=False),))
        >>> assert stats['mean'] == 1 and stats['std'] == 0, 'this test requires one annot per name in the database'
        >>> cm.evaluate_dnids(qreq_.ibs)
        >>> cm.assert_self(qreq_)
        >>> cm._cast_scores()
        >>> # cm.fs_list = cm.fs_list.astype(np.float)
        >>> nsum_nid_list, nsum_score_list = name_scoring.compute_nsum_score(cm, qreq_)
        >>> nsum_nid_list2, nsum_score_list2, _ = name_scoring.compute_nsum_score2(cm, qreq_)
        >>> csum_score_list = scoring.compute_csum_score(cm)
        >>> vt.asserteq(nsum_score_list, csum_score_list)
        >>> vt.asserteq(nsum_score_list, csum_score_list, thresh=0, iswarning=True)
        >>> vt.asserteq(nsum_score_list2, csum_score_list, thresh=0, iswarning=True)
        >>> #assert np.allclose(nsum_score_list, csum_score_list), 'should be the same when K=1 and per_name=1'
        >>> #assert all(nsum_score_list  == csum_score_list), 'should be the same when K=1 and per_name=1'
        >>> #assert all(nsum_score_list2 == csum_score_list), 'should be the same when K=1 and per_name=1'
        >>> # Evaluate parts of the sourcecode


    Ignore:
        assert all(nsum_score_list3 == csum_score_list), 'should be the same when K=1 and per_name=1'
        fm_list = fm_list[0:1]
        fs_list = fs_list[0:1]
        featflag_list2 = featflag_list2[0:1]
        dnid_list = dnid_list[0:1]
        name_groupxs2 = name_groupxs2[0:1]
        nsum_nid_list2 = nsum_nid_list2[0:1]

    """
    #assert qreq_ is not None
    try:
        HACK_SINGLE_ORI =  qreq_ is not None and (qreq_.qparams.augment_queryside_hack or qreq_.qparams.rotation_invariance)
    except AttributeError:
        HACK_SINGLE_ORI =  qreq_ is not None and (qreq_.config.augment_queryside_hack or qreq_.config.feat_cfg.rotation_invariance)
        pass
    # The core for each feature match
    #
    # The query feature index for each feature match
    fm_list = cm.fm_list
    fs_list = cm.get_fsv_prod_list()
    dnid_list = cm.dnid_list
    #--
    fx1_list = [fm.T[0] for fm in fm_list]
    """
    # Try a rebase?
    fx1_list = list(map(vt.compute_unique_data_ids_, fx1_list))
    """
    # Group annotation matches by name
    nsum_nid_list, name_groupxs = vt.group_indices(dnid_list)
    name_grouped_fx1_list = vt.apply_grouping_(fx1_list, name_groupxs)
    name_grouped_fs_list  = vt.apply_grouping_(fs_list,  name_groupxs)
    # Stack up all matches to a particular name
    name_grouped_fx1_flat = list(map(np.hstack, name_grouped_fx1_list))
    name_grouped_fs_flat  = list(map(np.hstack, name_grouped_fs_list))
    """
    assert np.all(name_grouped_fs_list[0][0] == fs_list[0])
    assert np.all(name_grouped_fs_flat[0] == fs_list[0])
    """
    if HACK_SINGLE_ORI:
        # keypoints with the same xy can only have one of them vote
        kpts1 = qreq_.ibs.get_annot_kpts(cm.qaid, config2_=qreq_.get_external_query_config2())
        xys1_ = vt.get_xys(kpts1).T
        kpts_xyid_list = vt.compute_unique_arr_dataids(xys1_)
        # Make nested group for every name by query feature index (accounting for duplicate orientation)
        name_grouped_xyid_flat = [kpts_xyid_list.take(fx1) for fx1 in name_grouped_fx1_flat]
        feat_groupxs_list = [vt.group_indices(xyid_flat)[1] for xyid_flat in name_grouped_xyid_flat]
    else:
        # make unique indicies using feature indexes
        feat_groupxs_list = [vt.group_indices(fx1_flat)[1] for fx1_flat in name_grouped_fx1_flat]
    # Make nested group for every name by unique query feature index
    feat_grouped_fs_list = [[fs_flat.take(xs, axis=0) for xs in feat_groupxs]
                            for fs_flat, feat_groupxs in zip(name_grouped_fs_flat, feat_groupxs_list)]
    """
    np.array(feat_grouped_fs_list)[0].T[0] == fs_list
    """
    if False:
        valid_fs_list = [
            np.array([group.max() for group in grouped_fs])
            #np.array([group[group.argmax()] for group in grouped_fs])
            for grouped_fs in feat_grouped_fs_list
        ]
        nsum_score_list4 = np.array([valid_fs.sum() for valid_fs in valid_fs_list])  # NOQA
    # Prevent a feature from voting twice:
    # take only the max score that a query feature produced
    #name_grouped_valid_fs_list1 =[np.array([fs_group.max() for fs_group in feat_grouped_fs])
    #                            for feat_grouped_fs in feat_grouped_fs_list]
    nsum_score_list = np.array([np.sum([fs_group.max() for fs_group in feat_grouped_fs])
                                for feat_grouped_fs in feat_grouped_fs_list])
    return nsum_nid_list, nsum_score_list