File size: 2,799 Bytes
a80d6bb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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