| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- from PIL import Image
- import numpy as np
- import torch
- import os
- from tqdm import tqdm
- from romatch.utils import pose_auc
- import cv2
- class HpatchesHomogBenchmark:
- """Hpatches grid goes from [0,n-1] instead of [0.5,n-0.5]"""
- def __init__(self, dataset_path) -> None:
- seqs_dir = "hpatches-sequences-release"
- self.seqs_path = os.path.join(dataset_path, seqs_dir)
- self.seq_names = sorted(os.listdir(self.seqs_path))
- # Ignore seqs is same as LoFTR.
- self.ignore_seqs = set(
- [
- "i_contruction",
- "i_crownnight",
- "i_dc",
- "i_pencils",
- "i_whitebuilding",
- "v_artisans",
- "v_astronautis",
- "v_talent",
- ]
- )
- def convert_coordinates(self, im_A_coords, im_A_to_im_B, wq, hq, wsup, hsup):
- offset = 0.5 # Hpatches assumes that the center of the top-left pixel is at [0,0] (I think)
- im_A_coords = (
- torch.stack(
- (
- wq * (im_A_coords[..., 0] + 1) / 2,
- hq * (im_A_coords[..., 1] + 1) / 2,
- ),
- axis=-1,
- )
- - offset
- )
- im_A_to_im_B = (
- torch.stack(
- (
- wsup * (im_A_to_im_B[..., 0] + 1) / 2,
- hsup * (im_A_to_im_B[..., 1] + 1) / 2,
- ),
- axis=-1,
- )
- - offset
- )
- return im_A_coords, im_A_to_im_B
- def benchmark(self, model, model_name = None):
- n_matches = []
- homog_dists = []
- for seq_idx, seq_name in tqdm(
- enumerate(self.seq_names), total=len(self.seq_names)
- ):
- im_A_path = os.path.join(self.seqs_path, seq_name, "1.ppm")
- im_A = Image.open(im_A_path)
- w1, h1 = im_A.size
- for im_idx in range(2, 7):
- im_B_path = os.path.join(self.seqs_path, seq_name, f"{im_idx}.ppm")
- im_B = Image.open(im_B_path)
- w2, h2 = im_B.size
- H = np.loadtxt(
- os.path.join(self.seqs_path, seq_name, "H_1_" + str(im_idx))
- )
- dense_matches, dense_certainty = model.match(
- im_A_path, im_B_path
- )
- good_matches, _ = model.sample(dense_matches, dense_certainty, 5000)
- pos_a, pos_b = self.convert_coordinates(
- good_matches[:, :2], good_matches[:, 2:], w1, h1, w2, h2
- )
- try:
- H_pred, inliers = cv2.findHomography(
- pos_a.cpu().numpy(),
- pos_b.cpu().numpy(),
- method = cv2.RANSAC,
- confidence = 0.99999,
- ransacReprojThreshold = 3 * min(w2, h2) / 480,
- )
- except:
- H_pred = None
- if H_pred is None:
- H_pred = np.zeros((3, 3))
- H_pred[2, 2] = 1.0
- corners = np.array(
- [[0, 0, 1], [0, h1 - 1, 1], [w1 - 1, 0, 1], [w1 - 1, h1 - 1, 1]]
- )
- real_warped_corners = np.dot(corners, np.transpose(H))
- real_warped_corners = (
- real_warped_corners[:, :2] / real_warped_corners[:, 2:]
- )
- warped_corners = np.dot(corners, np.transpose(H_pred))
- warped_corners = warped_corners[:, :2] / warped_corners[:, 2:]
- mean_dist = np.mean(
- np.linalg.norm(real_warped_corners - warped_corners, axis=1)
- ) / (min(w2, h2) / 480.0)
- homog_dists.append(mean_dist)
- n_matches = np.array(n_matches)
- thresholds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
- auc = pose_auc(np.array(homog_dists), thresholds)
- return {
- "hpatches_homog_auc_3": auc[2],
- "hpatches_homog_auc_5": auc[4],
- "hpatches_homog_auc_10": auc[9],
- }
|