def assign_nearest_neighbors(vecs1, vecs2, K=2): checks = 800 flann_params = {'algorithm': 'kdtree', 'trees': 8} #pseudo_max_dist_sqrd = (np.sqrt(2) * 512) ** 2 pseudo_max_dist_sqrd = 2 * (512**2) flann = vt.flann_cache(vecs1, flann_params=flann_params) try: fx2_to_fx1, _fx2_to_dist = flann.nn_index(vecs2, num_neighbors=K, checks=checks) except pyflann.FLANNException: print('vecs1.shape = %r' % (vecs1.shape, )) print('vecs2.shape = %r' % (vecs2.shape, )) print('vecs1.dtype = %r' % (vecs1.dtype, )) print('vecs2.dtype = %r' % (vecs2.dtype, )) raise fx2_to_dist = np.divide(_fx2_to_dist, pseudo_max_dist_sqrd) return fx2_to_fx1, fx2_to_dist
def assign_nearest_neighbors(vecs1, vecs2, K=2): checks = 800 flann_params = { 'algorithm': 'kdtree', 'trees': 8 } #pseudo_max_dist_sqrd = (np.sqrt(2) * 512) ** 2 pseudo_max_dist_sqrd = 2 * (512 ** 2) flann = vt.flann_cache(vecs1, flann_params=flann_params) try: fx2_to_fx1, _fx2_to_dist = flann.nn_index(vecs2, num_neighbors=K, checks=checks) except pyflann.FLANNException: print('vecs1.shape = %r' % (vecs1.shape,)) print('vecs2.shape = %r' % (vecs2.shape,)) print('vecs1.dtype = %r' % (vecs1.dtype,)) print('vecs2.dtype = %r' % (vecs2.dtype,)) raise fx2_to_dist = np.divide(_fx2_to_dist, pseudo_max_dist_sqrd) return fx2_to_fx1, fx2_to_dist
def get_dummy_test_vars1(fname1='easy1.png', fname2='easy2.png'): import utool as ut from vtool import image as gtool from vtool import features as feattool fpath1 = ut.grab_test_imgpath(fname1) fpath2 = ut.grab_test_imgpath(fname2) kpts1, vecs1 = feattool.extract_features(fpath1) kpts2, vecs2 = feattool.extract_features(fpath2) chip1 = gtool.imread(fpath1) chip2 = gtool.imread(fpath2) #chip1_shape = vt.gtool.open_image_size(fpath1) #chip2_shape = gtool.open_image_size(fpath2) #dlen_sqrd2 = chip2_shape[0] ** 2 + chip2_shape[1] #testtup = (rchip1, rchip2, kpts1, vecs1, kpts2, vecs2, dlen_sqrd2) import vtool as vt checks = 800 flann_params = { 'algorithm': 'kdtree', 'trees': 8 } #pseudo_max_dist_sqrd = (np.sqrt(2) * 512) ** 2 pseudo_max_dist_sqrd = 2 * (512 ** 2) flann = vt.flann_cache(vecs1, flann_params=flann_params) import pyflann try: fx2_to_fx1, _fx2_to_dist = flann.nn_index(vecs2, num_neighbors=2, checks=checks) except pyflann.FLANNException: print('vecs1.shape = %r' % (vecs1.shape,)) print('vecs2.shape = %r' % (vecs2.shape,)) print('vecs1.dtype = %r' % (vecs1.dtype,)) print('vecs2.dtype = %r' % (vecs2.dtype,)) raise fx2_to_dist = np.divide(_fx2_to_dist, pseudo_max_dist_sqrd) fx2_to_ratio = np.divide(fx2_to_dist.T[0], fx2_to_dist.T[1]) ratio_thresh = .625 fx2_to_isvalid = fx2_to_ratio < ratio_thresh fx2_m = np.where(fx2_to_isvalid)[0] fx1_m = fx2_to_fx1.T[0].take(fx2_m) #fs_RAT = np.subtract(1.0, fx2_to_ratio.take(fx2_m)) fm_RAT = np.vstack((fx1_m, fx2_m)).T fm = fm_RAT return chip1, chip2, kpts1, kpts2, fm
def assign_nearest_neighbors(vecs1, vecs2, K=2): import vtool as vt import pyflann checks = 800 flann_params = {"algorithm": "kdtree", "trees": 8} # pseudo_max_dist_sqrd = (np.sqrt(2) * 512) ** 2 # pseudo_max_dist_sqrd = 2 * (512 ** 2) flann = vt.flann_cache(vecs1, flann_params=flann_params) try: fx2_to_fx1, fx2_to_dist = matching.normalized_nearest_neighbors(flann, vecs2, K, checks) # fx2_to_fx1, _fx2_to_dist = flann.nn_index(vecs2, num_neighbors=K, checks=checks) except pyflann.FLANNException: print("vecs1.shape = %r" % (vecs1.shape,)) print("vecs2.shape = %r" % (vecs2.shape,)) print("vecs1.dtype = %r" % (vecs1.dtype,)) print("vecs2.dtype = %r" % (vecs2.dtype,)) raise # fx2_to_dist = np.divide(_fx2_to_dist, pseudo_max_dist_sqrd) return fx2_to_fx1, fx2_to_dist
def get_dummy_test_vars1(fname1='easy1.png', fname2='easy2.png'): import utool as ut from vtool import image as gtool from vtool import features as feattool fpath1 = ut.grab_test_imgpath(fname1) fpath2 = ut.grab_test_imgpath(fname2) kpts1, vecs1 = feattool.extract_features(fpath1) kpts2, vecs2 = feattool.extract_features(fpath2) chip1 = gtool.imread(fpath1) chip2 = gtool.imread(fpath2) #chip1_shape = vt.gtool.open_image_size(fpath1) #chip2_shape = gtool.open_image_size(fpath2) #dlen_sqrd2 = chip2_shape[0] ** 2 + chip2_shape[1] #testtup = (rchip1, rchip2, kpts1, vecs1, kpts2, vecs2, dlen_sqrd2) import vtool as vt checks = 800 flann_params = {'algorithm': 'kdtree', 'trees': 8} #pseudo_max_dist_sqrd = (np.sqrt(2) * 512) ** 2 pseudo_max_dist_sqrd = 2 * (512**2) flann = vt.flann_cache(vecs1, flann_params=flann_params) import pyflann try: fx2_to_fx1, _fx2_to_dist = flann.nn_index(vecs2, num_neighbors=2, checks=checks) except pyflann.FLANNException: print('vecs1.shape = %r' % (vecs1.shape, )) print('vecs2.shape = %r' % (vecs2.shape, )) print('vecs1.dtype = %r' % (vecs1.dtype, )) print('vecs2.dtype = %r' % (vecs2.dtype, )) raise fx2_to_dist = np.divide(_fx2_to_dist, pseudo_max_dist_sqrd) fx2_to_ratio = np.divide(fx2_to_dist.T[0], fx2_to_dist.T[1]) ratio_thresh = .625 fx2_to_isvalid = fx2_to_ratio < ratio_thresh fx2_m = np.where(fx2_to_isvalid)[0] fx1_m = fx2_to_fx1.T[0].take(fx2_m) #fs_RAT = np.subtract(1.0, fx2_to_ratio.take(fx2_m)) fm_RAT = np.vstack((fx1_m, fx2_m)).T fm = fm_RAT return chip1, chip2, kpts1, kpts2, fm
def vsone_feature_matching(kpts1, vecs1, kpts2, vecs2, dlen_sqrd2, cfgdict={}, flann1=None, flann2=None, verbose=None): r""" Actual logic for matching Args: vecs1 (ndarray[uint8_t, ndim=2]): SIFT descriptors vecs2 (ndarray[uint8_t, ndim=2]): SIFT descriptors kpts1 (ndarray[float32_t, ndim=2]): keypoints kpts2 (ndarray[float32_t, ndim=2]): keypoints Ignore: >>> from vtool.matching import * # NOQA %pylab qt4 import plottool as pt pt.imshow(rchip1) pt.draw_kpts2(kpts1) pt.show_chipmatch2(rchip1, rchip2, kpts1, kpts2, fm=fm, fs=fs) pt.show_chipmatch2(rchip1, rchip2, kpts1, kpts2, fm=fm, fs=fs) """ import vtool as vt import pyflann from vtool import spatial_verification as sver #import vtool as vt sver_xy_thresh = cfgdict.get('sver_xy_thresh', .01) ratio_thresh = cfgdict.get('ratio_thresh', .625) refine_method = cfgdict.get('refine_method', 'homog') symmetric = cfgdict.get('symmetric', False) K = cfgdict.get('K', 1) Knorm = cfgdict.get('Knorm', 1) #ratio_thresh = .99 # GET NEAREST NEIGHBORS checks = 800 #pseudo_max_dist_sqrd = (np.sqrt(2) * 512) ** 2 #pseudo_max_dist_sqrd = 2 * (512 ** 2) if verbose is None: verbose = True flann_params = {'algorithm': 'kdtree', 'trees': 8} if flann1 is None: flann1 = vt.flann_cache(vecs1, flann_params=flann_params, verbose=verbose) #print('symmetric = %r' % (symmetric,)) if symmetric: if flann2 is None: flann2 = vt.flann_cache(vecs2, flann_params=flann_params, verbose=verbose) try: try: num_neighbors = K + Knorm fx2_to_fx1, fx2_to_dist = normalized_nearest_neighbors(flann1, vecs2, num_neighbors, checks) #fx2_to_fx1, _fx2_to_dist = flann1.nn_index(vecs2, num_neighbors=K, checks=checks) if symmetric: fx1_to_fx2, fx1_to_dist = normalized_nearest_neighbors(flann2, vecs1, K, checks) except pyflann.FLANNException: print('vecs1.shape = %r' % (vecs1.shape,)) print('vecs2.shape = %r' % (vecs2.shape,)) print('vecs1.dtype = %r' % (vecs1.dtype,)) print('vecs2.dtype = %r' % (vecs2.dtype,)) raise if symmetric: is_symmetric = flag_symmetric_matches(fx2_to_fx1, fx1_to_fx2) fx2_to_fx1 = fx2_to_fx1.compress(is_symmetric, axis=0) fx2_to_dist = fx2_to_dist.compress(is_symmetric, axis=0) assigntup = assign_unconstrained_matches(fx2_to_fx1, fx2_to_dist) fx2_match, fx1_match, fx1_norm, match_dist, norm_dist = assigntup fm_ORIG = np.vstack((fx1_match, fx2_match)).T fs_ORIG = 1 - np.divide(match_dist, norm_dist) # APPLY RATIO TEST fm_RAT, fs_RAT, fm_norm_RAT = ratio_test(fx2_match, fx1_match, fx1_norm, match_dist, norm_dist, ratio_thresh) # SPATIAL VERIFICATION FILTER #with ut.EmbedOnException(): match_weights = np.ones(len(fm_RAT)) svtup = sver.spatially_verify_kpts(kpts1, kpts2, fm_RAT, sver_xy_thresh, dlen_sqrd2, match_weights=match_weights, refine_method=refine_method) if svtup is not None: (homog_inliers, homog_errors, H_RAT) = svtup[0:3] else: H_RAT = np.eye(3) homog_inliers = [] fm_RAT_SV = fm_RAT.take(homog_inliers, axis=0) fs_RAT_SV = fs_RAT.take(homog_inliers, axis=0) fm_norm_RAT_SV = fm_norm_RAT[homog_inliers] top_percent = .5 top_idx = ut.take_percentile(fx2_to_dist.T[0].argsort(), top_percent) fm_TOP = fm_ORIG.take(top_idx, axis=0) fs_TOP = fx2_to_dist.T[0].take(top_idx) #match_weights = np.ones(len(fm_TOP)) #match_weights = (np.exp(fs_TOP) / np.sqrt(np.pi * 2)) match_weights = 1 - fs_TOP #match_weights = np.ones(len(fm_TOP)) svtup = sver.spatially_verify_kpts(kpts1, kpts2, fm_TOP, sver_xy_thresh, dlen_sqrd2, match_weights=match_weights, refine_method=refine_method) if svtup is not None: (homog_inliers, homog_errors, H_TOP) = svtup[0:3] np.sqrt(homog_errors[0] / dlen_sqrd2) else: H_TOP = np.eye(3) homog_inliers = [] fm_TOP_SV = fm_TOP.take(homog_inliers, axis=0) fs_TOP_SV = fs_TOP.take(homog_inliers, axis=0) matches = { 'ORIG' : MatchTup2(fm_ORIG, fs_ORIG), 'RAT' : MatchTup3(fm_RAT, fs_RAT, fm_norm_RAT), 'RAT+SV' : MatchTup3(fm_RAT_SV, fs_RAT_SV, fm_norm_RAT_SV), 'TOP' : MatchTup2(fm_TOP, fs_TOP), 'TOP+SV' : MatchTup2(fm_TOP_SV, fs_TOP_SV), } output_metdata = { 'H_RAT': H_RAT, 'H_TOP': H_TOP, } except MatchingError: fm_ERR = np.empty((0, 2), dtype=np.int32) fs_ERR = np.empty((0, 1), dtype=np.float32) H_ERR = np.eye(3) matches = { 'ORIG' : MatchTup2(fm_ERR, fs_ERR), 'RAT' : MatchTup3(fm_ERR, fs_ERR, fm_ERR), 'RAT+SV' : MatchTup3(fm_ERR, fs_ERR, fm_ERR), 'TOP' : MatchTup2(fm_ERR, fs_ERR), 'TOP+SV' : MatchTup2(fm_ERR, fs_ERR), } output_metdata = { 'H_RAT': H_ERR, 'H_TOP': H_ERR, } return matches, output_metdata
def vsone_feature_matching(kpts1, vecs1, kpts2, vecs2, dlen_sqrd2, cfgdict={}, flann1=None, flann2=None, verbose=None): r""" Actual logic for matching Args: vecs1 (ndarray[uint8_t, ndim=2]): SIFT descriptors vecs2 (ndarray[uint8_t, ndim=2]): SIFT descriptors kpts1 (ndarray[float32_t, ndim=2]): keypoints kpts2 (ndarray[float32_t, ndim=2]): keypoints Ignore: >>> from vtool.matching import * # NOQA %pylab qt4 import plottool as pt pt.imshow(rchip1) pt.draw_kpts2(kpts1) pt.show_chipmatch2(rchip1, rchip2, kpts1, kpts2, fm=fm, fs=fs) pt.show_chipmatch2(rchip1, rchip2, kpts1, kpts2, fm=fm, fs=fs) """ import vtool as vt import pyflann from vtool import spatial_verification as sver #import vtool as vt sver_xy_thresh = cfgdict.get('sver_xy_thresh', .01) ratio_thresh = cfgdict.get('ratio_thresh', .625) refine_method = cfgdict.get('refine_method', 'homog') symmetric = cfgdict.get('symmetric', False) K = cfgdict.get('K', 1) Knorm = cfgdict.get('Knorm', 1) #ratio_thresh = .99 # GET NEAREST NEIGHBORS checks = 800 #pseudo_max_dist_sqrd = (np.sqrt(2) * 512) ** 2 #pseudo_max_dist_sqrd = 2 * (512 ** 2) if verbose is None: verbose = True flann_params = {'algorithm': 'kdtree', 'trees': 8} if flann1 is None: flann1 = vt.flann_cache(vecs1, flann_params=flann_params, verbose=verbose) #print('symmetric = %r' % (symmetric,)) if symmetric: if flann2 is None: flann2 = vt.flann_cache(vecs2, flann_params=flann_params, verbose=verbose) try: try: num_neighbors = K + Knorm fx2_to_fx1, fx2_to_dist = normalized_nearest_neighbors( flann1, vecs2, num_neighbors, checks) #fx2_to_fx1, _fx2_to_dist = flann1.nn_index(vecs2, num_neighbors=K, checks=checks) if symmetric: fx1_to_fx2, fx1_to_dist = normalized_nearest_neighbors( flann2, vecs1, K, checks) except pyflann.FLANNException: print('vecs1.shape = %r' % (vecs1.shape, )) print('vecs2.shape = %r' % (vecs2.shape, )) print('vecs1.dtype = %r' % (vecs1.dtype, )) print('vecs2.dtype = %r' % (vecs2.dtype, )) raise if symmetric: is_symmetric = flag_symmetric_matches(fx2_to_fx1, fx1_to_fx2) fx2_to_fx1 = fx2_to_fx1.compress(is_symmetric, axis=0) fx2_to_dist = fx2_to_dist.compress(is_symmetric, axis=0) assigntup = assign_unconstrained_matches(fx2_to_fx1, fx2_to_dist) fx2_match, fx1_match, fx1_norm, match_dist, norm_dist = assigntup fm_ORIG = np.vstack((fx1_match, fx2_match)).T fs_ORIG = 1 - np.divide(match_dist, norm_dist) # APPLY RATIO TEST fm_RAT, fs_RAT, fm_norm_RAT = ratio_test(fx2_match, fx1_match, fx1_norm, match_dist, norm_dist, ratio_thresh) # SPATIAL VERIFICATION FILTER #with ut.EmbedOnException(): match_weights = np.ones(len(fm_RAT)) svtup = sver.spatially_verify_kpts(kpts1, kpts2, fm_RAT, sver_xy_thresh, dlen_sqrd2, match_weights=match_weights, refine_method=refine_method) if svtup is not None: (homog_inliers, homog_errors, H_RAT) = svtup[0:3] else: H_RAT = np.eye(3) homog_inliers = [] fm_RAT_SV = fm_RAT.take(homog_inliers, axis=0) fs_RAT_SV = fs_RAT.take(homog_inliers, axis=0) fm_norm_RAT_SV = fm_norm_RAT[homog_inliers] top_percent = .5 top_idx = ut.take_percentile(fx2_to_dist.T[0].argsort(), top_percent) fm_TOP = fm_ORIG.take(top_idx, axis=0) fs_TOP = fx2_to_dist.T[0].take(top_idx) #match_weights = np.ones(len(fm_TOP)) #match_weights = (np.exp(fs_TOP) / np.sqrt(np.pi * 2)) match_weights = 1 - fs_TOP #match_weights = np.ones(len(fm_TOP)) svtup = sver.spatially_verify_kpts(kpts1, kpts2, fm_TOP, sver_xy_thresh, dlen_sqrd2, match_weights=match_weights, refine_method=refine_method) if svtup is not None: (homog_inliers, homog_errors, H_TOP) = svtup[0:3] np.sqrt(homog_errors[0] / dlen_sqrd2) else: H_TOP = np.eye(3) homog_inliers = [] fm_TOP_SV = fm_TOP.take(homog_inliers, axis=0) fs_TOP_SV = fs_TOP.take(homog_inliers, axis=0) matches = { 'ORIG': MatchTup2(fm_ORIG, fs_ORIG), 'RAT': MatchTup3(fm_RAT, fs_RAT, fm_norm_RAT), 'RAT+SV': MatchTup3(fm_RAT_SV, fs_RAT_SV, fm_norm_RAT_SV), 'TOP': MatchTup2(fm_TOP, fs_TOP), 'TOP+SV': MatchTup2(fm_TOP_SV, fs_TOP_SV), } output_metdata = { 'H_RAT': H_RAT, 'H_TOP': H_TOP, } except MatchingError: fm_ERR = np.empty((0, 2), dtype=np.int32) fs_ERR = np.empty((0, 1), dtype=np.float32) H_ERR = np.eye(3) matches = { 'ORIG': MatchTup2(fm_ERR, fs_ERR), 'RAT': MatchTup3(fm_ERR, fs_ERR, fm_ERR), 'RAT+SV': MatchTup3(fm_ERR, fs_ERR, fm_ERR), 'TOP': MatchTup2(fm_ERR, fs_ERR), 'TOP+SV': MatchTup2(fm_ERR, fs_ERR), } output_metdata = { 'H_RAT': H_ERR, 'H_TOP': H_ERR, } return matches, output_metdata