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)
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)
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)