def match_words(f1, words1, f2, words2, config):
    """Match using words and apply Lowe's ratio filter.

    Args:
        f1: feature descriptors of the first image
        w1: the nth closest words for each feature in the first image
        f2: feature descriptors of the second image
        w2: the nth closest words for each feature in the second image
        config: config parameters
    """
    ratio = config['lowes_ratio']
    num_checks = config['bow_num_checks']
    return csfm.match_using_words(f1, words1, f2, words2[:, 0],
                                  ratio, num_checks)
Beispiel #2
0
def match(im1, im2, camera1, camera2, data):
    """Perform matching for a pair of images."""
    # Apply mask to features if any
    time_start = timer()
    p1, f1, _ = feature_loader.instance.load_points_features_colors(
        data, im1, masked=True)
    p2, f2, _ = feature_loader.instance.load_points_features_colors(
        data, im2, masked=True)

    if p1 is None or p2 is None:
        return []

    config = data.config
    matcher_type = config['matcher_type'].upper()

    w1, w2 = None, None
    if 'WORDS' in matcher_type:
        w1 = feature_loader.instance.load_words(data, im1, masked=True)
        w2 = feature_loader.instance.load_words(data, im2, masked=True)
        if w1 is None or w2 is None:
            return []

    if matcher_type == 'WORDS':
        matches = csfm.match_using_words(f1, w1, f2, w2[:, 0],
                                         data.config['lowes_ratio'],
                                         data.config['bow_num_checks'])
    elif matcher_type == 'WORDS_SYMMETRIC':
        matches = match_words_symmetric(f1, w1, f2, w2, config)
    elif 'FLANN' in matcher_type:
        i1 = feature_loader.instance.load_features_index(data,
                                                         im1,
                                                         masked=True)
        i2 = feature_loader.instance.load_features_index(data,
                                                         im2,
                                                         masked=True)
        matches = match_flann_symmetric(f1, i1, f2, i2, config)
    elif matcher_type == 'BRUTEFORCE':
        matches = match_brute_force_symmetric(f1, f2, config)
    else:
        raise ValueError("Invalid matcher_type: {}".format(matcher_type))

    # Adhoc filters
    if config['matching_use_filters']:
        matches = apply_adhoc_filters(data, matches, im1, camera1, p1, im2,
                                      camera2, p2)

    matches = np.array(matches, dtype=int)
    time_2d_matching = timer() - time_start
    t = timer()

    robust_matching_min_match = config['robust_matching_min_match']
    if len(matches) < robust_matching_min_match:
        logger.debug('Matching {} and {}.  Matcher: {} T-desc: {:1.3f} '
                     'Matches: FAILED'.format(im1, im2, matcher_type,
                                              time_2d_matching))
        return []

    # robust matching
    rmatches = robust_match(p1, p2, camera1, camera2, matches, config)
    rmatches = np.array([[a, b] for a, b in rmatches])
    time_robust_matching = timer() - t
    time_total = timer() - time_start

    # From indexes in filtered sets, to indexes in original sets of features
    m1 = feature_loader.instance.load_mask(data, im1)
    m2 = feature_loader.instance.load_mask(data, im2)
    if m1 is not None and m2 is not None:
        rmatches = unfilter_matches(rmatches, m1, m2)

    logger.debug('Matching {} and {}.  Matcher: {} '
                 'T-desc: {:1.3f} T-robust: {:1.3f} T-total: {:1.3f} '
                 'Matches: {} Robust: {} Success: {}'.format(
                     im1, im2, matcher_type, time_2d_matching,
                     time_robust_matching, time_total, len(matches),
                     len(rmatches),
                     len(rmatches) >= robust_matching_min_match))

    if len(rmatches) < robust_matching_min_match:
        return []

    return np.array(rmatches, dtype=int)
Beispiel #3
0
def match(im1, im2, camera1, camera2,
          p1, p2, f1, f2, w1, w2,
          i1, i2, m1, m2, data, pdr_shots_dict):
    """ Perform matching for a pair of images

    Given a pair of images (1,2) and their :
    - features position p
    - features descriptor f
    - descriptor BoW assignments w (optionnal, can be None)
    - descriptor kNN index indexing structure (optionnal, can be None)
    - mask selection m  (optionnal, can be None)
    - camera
    Compute 2D + robust geometric matching (either E or F-matrix)
    """
    if p1 is None or p2 is None:
        return None, np.array([])

    # Apply mask to features if any
    time_start = timer()
    f1_filtered = f1 if m1 is None else f1[m1]
    f2_filtered = f2 if m2 is None else f2[m2]

    config = data.config
    matcher_type = config['matcher_type'].upper()

    if matcher_type == 'WORDS':
        w1_filtered = w1 if m1 is None else w1[m1]
        w2_filtered = w2 if m2 is None else w2[m2]
        matches = csfm.match_using_words(
            f1_filtered, w1_filtered,
            f2_filtered, w2_filtered[:, 0],
            data.config['lowes_ratio'],
            data.config['bow_num_checks'])
    elif matcher_type == 'WORDS_SYMMETRIC':
        w1_filtered = w1 if m1 is None else w1[m1]
        w2_filtered = w2 if m2 is None else w2[m2]
        matches = match_words_symmetric(
            f1_filtered, w1_filtered,
            f2_filtered, w2_filtered, config)
    elif matcher_type == 'FLANN':
        matches = match_flann_symmetric(f1_filtered, i1, f2_filtered, i2, config)
    elif matcher_type == 'BRUTEFORCE':
        matches = match_brute_force_symmetric(f1_filtered, f2_filtered, config)
    else:
        raise ValueError("Invalid matcher_type: {}".format(matcher_type))

    # From indexes in filtered sets, to indexes in original sets of features
    if m1 is not None and m2 is not None:
        matches = unfilter_matches(matches, m1, m2)

    # Adhoc filters
    if config['matching_use_filters']:
        matches = apply_adhoc_filters(data, matches,
                                      im1, camera1, p1,
                                      im2, camera2, p2)

    matches = np.array(matches, dtype=int)
    time_2d_matching = timer() - time_start
    t = timer()

    robust_matching_min_match = config['robust_matching_min_match']
    if len(matches) < robust_matching_min_match:
        logger.debug(
            'Matching {} and {}.  Matcher: {} T-desc: {:1.3f} '
            'Matches: FAILED'.format(im1, im2, matcher_type, time_2d_matching))
        return None, np.array([])

    # robust matching
    T, rmatches = robust_match(p1, p2, camera1, camera2, matches, config)
    rmatches = np.array([[a, b] for a, b in rmatches])
    time_robust_matching = timer() - t
    time_total = timer() - time_start

    if len(rmatches) < robust_matching_min_match:
        logger.debug(
            'Matching {} and {}.  Matcher: {} '
            'T-desc: {:1.3f} T-robust: {:1.3f} T-total: {:1.3f} '
            'Matches: {} Robust: FAILED'.format(
                im1, im2, matcher_type,
                time_2d_matching, time_robust_matching, time_total,
                len(matches)))
        return None, np.array([])

    if config['filtering_use_preint']:
        if not filtering.rotation_close_to_preint(im1, im2, T, pdr_shots_dict):
            logger.debug(
                'Matching {} and {}.  Matcher: {} '
                'T-desc: {:1.3f} T-robust: {:1.3f} T-total: {:1.3f} '
                'Matches: {} Robust: {} Preint check: FAILED'.format(
                    im1, im2, matcher_type,
                    time_2d_matching, time_robust_matching, time_total,
                    len(matches), len(rmatches)))
            return None, np.array([])

    logger.debug(
        'Matching {} and {}.  Matcher: {} '
        'T-desc: {:1.3f} T-robust: {:1.3f} T-total: {:1.3f} '
        'Matches: {} Robust: {} Thresh: {}'.format(
            im1, im2, matcher_type,
            time_2d_matching, time_robust_matching, time_total,
            len(matches), len(rmatches), robust_matching_min_match))

    return T, np.array(rmatches, dtype=int)