File size: 3,086 Bytes
a80d6bb
 
 
c74a070
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a80d6bb
c74a070
a80d6bb
 
c74a070
a80d6bb
c74a070
 
 
 
 
 
a80d6bb
 
c74a070
 
 
 
a80d6bb
 
c74a070
 
 
 
 
a80d6bb
 
c74a070
 
 
a80d6bb
 
c74a070
 
 
a80d6bb
 
c74a070
 
 
 
 
 
 
 
 
 
a80d6bb
c74a070
 
 
a80d6bb
c74a070
 
a80d6bb
c74a070
 
a80d6bb
c74a070
 
 
a80d6bb
c74a070
a80d6bb
 
c74a070
a80d6bb
 
c74a070
 
 
 
 
 
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
97
98
99
100
101
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