import cv2 import numpy as np import LFUtilities import ORBParameters import WebAppSettings as settings class ORBRescorer: def __init__(self): self.lf = LFUtilities.load(settings.DATASET_LF) self.ids = np.loadtxt(settings.DATASET_IDS, dtype=str).tolist() #self.orb = cv2.ORB_create() self.bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) def rescore_by_id(self, query_id, resultset): query_idx = self.ids.index(query_id) return self.rescore_by_img(self.lf[query_idx], resultset) def rescore_by_img(self, query, resultset): max_inliers = -1 res = [] for data_id, _ in resultset: data_idx = self.ids.index(data_id) try: data_el = self.lf[data_idx] matches = self.bf.match(query[1], data_el[1]) good = [m for m in matches if m.distance <= ORBParameters.THRESHOLD] if len(good) > ORBParameters.MIN_GOOD_MATCHES: src_pts = np.float32([query[0][m.queryIdx].pt for m in good]).reshape(-1, 1, 2) dst_pts = np.float32([data_el[0][m.trainIdx].pt for m in good]).reshape(-1, 1, 2) M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 1.0) matches_mask = mask.ravel().tolist() # print(len(good)) inliers = np.count_nonzero(matches_mask) # print(inliers) if (inliers >= ORBParameters.MIN_INLIERS and inliers > max_inliers): max_inliers = inliers res.append((data_id, inliers)) except: print('rescore error evaluating ' + data_id) pass if res: res.sort(key=lambda result: result[1], reverse=True) return res def add(self, lf): self.lf.append(lf) def remove(self, idx): self.descs = np.delete(self.descs, idx, axis=0) def save(self, is_backup=False): lf_save_file = settings.DATASET_LF ids_file = settings.DATASET_IDS_LF if lf_save_file != "None": if is_backup: lf_save_file += '.bak' ids_file += '.bak' LFUtilities.save(lf_save_file, self.lf) np.savetxt(ids_file, self.ids, fmt='%s')