Spaces:
Running
on
Zero
Running
on
Zero
| 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 | |