Spaces:
Running
Running
import numpy as np | |
import sys | |
import os | |
ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) | |
sys.path.insert(0, ROOT_DIR) | |
from utils import evaluation_utils,metrics,fm_utils | |
import cv2 | |
class auc_eval: | |
def __init__(self,config): | |
self.config=config | |
self.err_r,self.err_t,self.err=[],[],[] | |
self.ms=[] | |
self.precision=[] | |
def run(self,info): | |
E,r_gt,t_gt=info['e'],info['r_gt'],info['t_gt'] | |
K1,K2,img1,img2=info['K1'],info['K2'],info['img1'],info['img2'] | |
corr1,corr2=info['corr1'],info['corr2'] | |
corr1,corr2=evaluation_utils.normalize_intrinsic(corr1,K1),evaluation_utils.normalize_intrinsic(corr2,K2) | |
size1,size2=max(img1.shape),max(img2.shape) | |
scale1,scale2=self.config['rescale']/size1,self.config['rescale']/size2 | |
#ransac | |
ransac_th=4./((K1[0,0]+K1[1,1])*scale1+(K2[0,0]+K2[1,1])*scale2) | |
R_hat,t_hat,E_hat=self.estimate(corr1,corr2,ransac_th) | |
#get pose error | |
err_r, err_t=metrics.evaluate_R_t(r_gt,t_gt,R_hat,t_hat) | |
err=max(err_r,err_t) | |
if len(corr1)>1: | |
inlier_mask=metrics.compute_epi_inlier(corr1,corr2,E,self.config['inlier_th']) | |
precision=inlier_mask.mean() | |
ms=inlier_mask.sum()/len(info['x1']) | |
else: | |
ms=precision=0 | |
return {'err_r':err_r,'err_t':err_t,'err':err,'ms':ms,'precision':precision} | |
def res_inqueue(self,res): | |
self.err_r.append(res['err_r']),self.err_t.append(res['err_t']),self.err.append(res['err']) | |
self.ms.append(res['ms']),self.precision.append(res['precision']) | |
def estimate(self,corr1,corr2,th): | |
num_inlier = -1 | |
if corr1.shape[0] >= 5: | |
E, mask_new = cv2.findEssentialMat(corr1, corr2,method=cv2.RANSAC, threshold=th,prob=1-1e-5) | |
if E is None: | |
E=[np.eye(3)] | |
for _E in np.split(E, len(E) / 3): | |
_num_inlier, _R, _t, _ = cv2.recoverPose(_E, corr1, corr2,np.eye(3), 1e9,mask=mask_new) | |
if _num_inlier > num_inlier: | |
num_inlier = _num_inlier | |
R = _R | |
t = _t | |
E = _E | |
else: | |
E,R,t=np.eye(3),np.eye(3),np.zeros(3) | |
return R,t,E | |
def parse(self): | |
ths = np.arange(7) * 5 | |
approx_auc=metrics.approx_pose_auc(self.err,ths) | |
exact_auc=metrics.pose_auc(self.err,ths) | |
mean_pre,mean_ms=np.mean(np.asarray(self.precision)),np.mean(np.asarray(self.ms)) | |
print('auc th: ',ths[1:]) | |
print('approx auc: ',approx_auc) | |
print('exact auc: ', exact_auc) | |
print('mean match score: ',mean_ms*100) | |
print('mean precision: ',mean_pre*100) | |
class FMbench_eval: | |
def __init__(self,config): | |
self.config=config | |
self.pre,self.pre_post,self.sgd=[],[],[] | |
self.num_corr,self.num_corr_post=[],[] | |
def run(self,info): | |
corr1,corr2=info['corr1'],info['corr2'] | |
F=info['f'] | |
img1,img2=info['img1'],info['img2'] | |
if len(corr1)>1: | |
pre_bf=fm_utils.compute_inlier_rate(corr1,corr2,np.flip(img1.shape[:2]),np.flip(img2.shape[:2]),F,th=self.config['inlier_th']).mean() | |
F_hat,mask_F=cv2.findFundamentalMat(corr1,corr2,method=cv2.FM_RANSAC,ransacReprojThreshold=1,confidence=1-1e-5) | |
if F_hat is None: | |
F_hat=np.ones([3,3]) | |
mask_F=np.ones([len(corr1)]).astype(bool) | |
else: | |
mask_F=mask_F.squeeze().astype(bool) | |
F_hat=F_hat[:3] | |
pre_af=fm_utils.compute_inlier_rate(corr1[mask_F],corr2[mask_F],np.flip(img1.shape[:2]),np.flip(img2.shape[:2]),F,th=self.config['inlier_th']).mean() | |
num_corr_af=mask_F.sum() | |
num_corr=len(corr1) | |
sgd=fm_utils.compute_SGD(F,F_hat,np.flip(img1.shape[:2]),np.flip(img2.shape[:2])) | |
else: | |
pre_bf,pre_af,sgd=0,0,1e8 | |
num_corr,num_corr_af=0,0 | |
return {'pre':pre_bf,'pre_post':pre_af,'sgd':sgd,'num_corr':num_corr,'num_corr_post':num_corr_af} | |
def res_inqueue(self,res): | |
self.pre.append(res['pre']),self.pre_post.append(res['pre_post']),self.sgd.append(res['sgd']) | |
self.num_corr.append(res['num_corr']),self.num_corr_post.append(res['num_corr_post']) | |
def parse(self): | |
for seq_index in range(len(self.config['seq'])): | |
seq=self.config['seq'][seq_index] | |
offset=seq_index*1000 | |
pre=np.asarray(self.pre)[offset:offset+1000].mean() | |
pre_post=np.asarray(self.pre_post)[offset:offset+1000].mean() | |
num_corr=np.asarray(self.num_corr)[offset:offset+1000].mean() | |
num_corr_post=np.asarray(self.num_corr_post)[offset:offset+1000].mean() | |
f_recall=(np.asarray(self.sgd)[offset:offset+1000]<self.config['sgd_inlier_th']).mean() | |
print(seq,'results:') | |
print('F_recall: ',f_recall) | |
print('precision: ',pre) | |
print('precision_post: ',pre_post) | |
print('num_corr: ',num_corr) | |
print('num_corr_post: ',num_corr_post,'\n') | |