Vincentqyw
update: features and matchers
a80d6bb
raw
history blame
2.8 kB
import numpy as np
def line_to_border(line,size):
#line:(a,b,c), ax+by+c=0
#size:(W,H)
H,W=size[1],size[0]
a,b,c=line[0],line[1],line[2]
epsa=1e-8 if a>=0 else -1e-8
epsb=1e-8 if b>=0 else -1e-8
intersection_list=[]
y_left=-c/(b+epsb)
y_right=(-c-a*(W-1))/(b+epsb)
x_top=-c/(a+epsa)
x_down=(-c-b*(H-1))/(a+epsa)
if y_left>=0 and y_left<=H-1:
intersection_list.append([0,y_left])
if y_right>=0 and y_right<=H-1:
intersection_list.append([W-1,y_right])
if x_top>=0 and x_top<=W-1:
intersection_list.append([x_top,0])
if x_down>=0 and x_down<=W-1:
intersection_list.append([x_down,H-1])
if len(intersection_list)!=2:
return None
intersection_list=np.asarray(intersection_list)
return intersection_list
def find_point_in_line(end_point):
x_span,y_span=end_point[1,0]-end_point[0,0],end_point[1,1]-end_point[0,1]
mv=np.random.uniform()
point=np.asarray([end_point[0,0]+x_span*mv,end_point[0,1]+y_span*mv])
return point
def epi_line(point,F):
homo=np.concatenate([point,np.ones([len(point),1])],axis=-1)
epi=np.matmul(homo,F.T)
return epi
def dis_point_to_line(line,point):
homo=np.concatenate([point,np.ones([len(point),1])],axis=-1)
dis=line*homo
dis=dis.sum(axis=-1)/(np.linalg.norm(line[:,:2],axis=-1)+1e-8)
return abs(dis)
def SGD_oneiter(F1,F2,size1,size2):
H1,W1=size1[1],size1[0]
factor1 = 1 / np.linalg.norm(size1)
factor2 = 1 / np.linalg.norm(size2)
p0=np.asarray([(W1-1)*np.random.uniform(),(H1-1)*np.random.uniform()])
epi1=epi_line(p0[np.newaxis],F1)[0]
border_point1=line_to_border(epi1,size2)
if border_point1 is None:
return -1
p1=find_point_in_line(border_point1)
epi2=epi_line(p0[np.newaxis],F2)
d1=dis_point_to_line(epi2,p1[np.newaxis])[0]*factor2
epi3=epi_line(p1[np.newaxis],F2.T)
d2=dis_point_to_line(epi3,p0[np.newaxis])[0]*factor1
return (d1+d2)/2
def compute_SGD(F1,F2,size1,size2):
np.random.seed(1234)
N=1000
max_iter=N*10
count,sgd=0,0
for i in range(max_iter):
d1=SGD_oneiter(F1,F2,size1,size2)
if d1<0:
continue
d2=SGD_oneiter(F2,F1,size1,size2)
if d2<0:
continue
count+=1
sgd+=(d1+d2)/2
if count==N:
break
if count==0:
return 1
else:
return sgd/count
def compute_inlier_rate(x1,x2,size1,size2,F_gt,th=0.003):
t1,t2=np.linalg.norm(size1)*th,np.linalg.norm(size2)*th
epi1,epi2=epi_line(x1,F_gt),epi_line(x2,F_gt.T)
dis1,dis2=dis_point_to_line(epi1,x2),dis_point_to_line(epi2,x1)
mask_inlier=np.logical_and(dis1<t2,dis2<t1)
return mask_inlier.mean() if len(mask_inlier)!=0 else 0