naver / r2d2

Other
455 stars 85 forks source link

About matching score #44

Open reacher-l opened 2 years ago

reacher-l commented 2 years ago

Hello, your work is excellent. I would like to follow your work, Can you open your test code about matching score?

santelelle commented 2 years ago

same interest here, I cannot reproduce the results stated in the paper

reacher-l commented 2 years ago

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