About matching score
reacher-l opened this issue · 2 comments
Hello, your work is excellent. I would like to follow your work, Can you open your test code about matching score?
same interest here, I cannot reproduce the results stated in the paper
-- coding: utf-8 --
"""
Spyder Editor
This is a temporary script file.
"""
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import os
import torch
from scipy.io import loadmat
from tqdm import tqdm_notebook as tqdm
#%matplotlib inline
use_cuda = torch.cuda.is_available()
device = torch.device('cuda:0' if use_cuda else 'cpu')
top_k = None
n_i = 52
n_v = 56
#dataset_path = 'hpatches-sequences-release'
dataset_path = '/hpatch/hpatches_sequences/hpatches-sequences-release'
lim = [1, 15]
rng = np.arange(lim[0], lim[1] + 1)
def mnn_matcher(descriptors_a, descriptors_b):
device = descriptors_a.device
sim = descriptors_a @ descriptors_b.t()
nn12 = torch.max(sim, dim=1)[1]
nn21 = torch.max(sim, dim=0)[1]
ids1 = torch.arange(0, sim.shape[0], device=device)
# mask = (ids1 == nn21[nn12])
# matches = torch.stack([ids1[mask], nn12[mask]])
matches = torch.stack([ids1, nn12])
return matches.t().data.cpu().numpy()
import pdb
def benchmark_features(read_feats):
seq_names = sorted(os.listdir(dataset_path))
n_feats = []
n_matches = []
match_score = 0
match_score_count = 0
for seq_idx, seq_name in tqdm(enumerate(seq_names), total=len(seq_names)):
keypoints_a, descriptors_a = read_feats(seq_name, 1)
n_feats.append(keypoints_a.shape[0])
for im_idx in range(2, 7):
keypoints_b, descriptors_b = read_feats(seq_name, im_idx)
# pdb.set_trace()
n_feats.append(keypoints_b.shape[0])
matches = mnn_matcher(
torch.from_numpy(descriptors_a).to(device=device),
torch.from_numpy(descriptors_b).to(device=device)
)
# pdb.set_trace()
homography = np.loadtxt(os.path.join(dataset_path, seq_name, "H_1_" + str(im_idx)))
pos_a = keypoints_a[matches[:, 0], : 2]
pos_a_h = np.concatenate([pos_a, np.ones([matches.shape[0], 1])], axis=1)
pos_b_proj_h = np.transpose(np.dot(homography, np.transpose(pos_a_h)))
pos_b_proj = pos_b_proj_h[:, : 2] / pos_b_proj_h[:, 2 :]
pos_b = keypoints_b[matches[:, 1], : 2]
dist = np.sqrt(np.sum((pos_b - pos_b_proj) ** 2, axis=1)) #2713
n_matches.append(matches.shape[0])#2713, 2
# pdb.set_trace()
match_score += sum(dist<=5)/dist.shape[0]
match_score_count+=1
return match_score, match_score_count
def summary(stats):
seq_type, n_feats, n_matches = stats
print('# Features: {:f} - [{:d}, {:d}]'.format(np.mean(n_feats), np.min(n_feats), np.max(n_feats)))
print('# Matches: Overall {:f}, Illumination {:f}, Viewpoint {:f}'.format(
np.sum(n_matches) / ((n_i + n_v) * 5),
np.sum(n_matches[seq_type == 'i']) / (n_i * 5),
np.sum(n_matches[seq_type == 'v']) / (n_v * 5))
)
def generate_read_function(method, extension='ppm'):
def read_function(seq_name, im_idx):
aux = np.load(os.path.join(dataset_path, seq_name, '%d.%s.%s' % (im_idx, extension, method)))
if top_k is None:
return aux['keypoints'], aux['descriptors']
else:
assert('scores' in aux)
ids = np.argsort(aux['scores'])[-top_k :]
return aux['keypoints'][ids, :], aux['descriptors'][ids, :]
return read_function
errors = {}
method = 'r2d2_fuxian'
read_function = generate_read_function(method)
match_score,match_score_count = benchmark_features(read_function)
print(match_score/match_score_count)
I used the code above to get a similar matching score!