File size: 3,086 Bytes
404d2af
 
 
8b973ee
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
404d2af
8b973ee
404d2af
 
8b973ee
404d2af
8b973ee
 
 
 
 
 
404d2af
 
8b973ee
 
 
 
404d2af
 
8b973ee
 
 
 
 
404d2af
 
8b973ee
 
 
404d2af
 
8b973ee
 
 
404d2af
 
8b973ee
 
 
 
 
 
 
 
 
 
404d2af
8b973ee
 
 
404d2af
8b973ee
 
404d2af
8b973ee
 
404d2af
8b973ee
 
 
404d2af
8b973ee
404d2af
 
8b973ee
404d2af
 
8b973ee
 
 
 
 
 
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