-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathintrinsics.py
69 lines (54 loc) · 2.23 KB
/
intrinsics.py
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
import numpy as np
import util
def generate_v_ij(H_stack, i, j):
"""Generate intrinsic orthogonality constraints. See Zhang pg. 6 for
details.
"""
M = H_stack.shape[0]
v_ij = np.zeros((M, 6))
v_ij[:, 0] = H_stack[:, 0, i] * H_stack[:, 0, j]
v_ij[:, 1] = H_stack[:, 0, i] * H_stack[:, 1, j] + H_stack[:, 1, i] * H_stack[:, 0, j]
v_ij[:, 2] = H_stack[:, 1, i] * H_stack[:, 1, j]
v_ij[:, 3] = H_stack[:, 2, i] * H_stack[:, 0, j] + H_stack[:, 0, i] * H_stack[:, 2, j]
v_ij[:, 4] = H_stack[:, 2, i] * H_stack[:, 1, j] + H_stack[:, 1, i] * H_stack[:, 2, j]
v_ij[:, 5] = H_stack[:, 2, i] * H_stack[:, 2, j]
return v_ij
def recover_intrinsics(homographies):
"""Use computed homographies to calculate intrinsic matrix.
Requires >= 3 homographies for a full 5-parameter intrinsic matrix.
"""
M = len(homographies)
# Stack homographies
H_stack = np.zeros((M, 3, 3))
for h, H in enumerate(homographies):
H_stack[h] = H
# Generate constraints
v_00 = generate_v_ij(H_stack, 0, 0)
v_01 = generate_v_ij(H_stack, 0, 1)
v_11 = generate_v_ij(H_stack, 1, 1)
# Mount constraint matrix
V = np.zeros((2 * M, 6))
V[:M] = v_01
V[M:] = v_00 - v_11
# Use SVD to solve the homogeneous system Vb = 0
b = util.svd_solve(V)
B0, B1, B2, B3, B4, B5 = b
# Form B = K_-T K_-1
B = np.array([[B0, B1, B3],
[B1, B2, B4],
[B3, B4, B5]])
# Form auxilliaries
w = B0 * B2 * B5 - B1**2 * B5 - B0 * B4**2 + 2. * B1 * B3 * B4 - B2 * B3**2
d = B0 * B2 - B1**2
# Use Zhang's closed form solution for intrinsic parameters (Zhang, Appendix B, pg. 18)
v0 = (B[0,1] * B[0,2] - B[0,0] * B[1,2]) / (B[0,0] * B[1,1] - B[0,1] * B[0,1])
lambda_ = B[2,2] - (B[0,2] * B[0,2] + v0 * (B[0,1] * B[0,2] - B[0,0] * B[1,2])) / B[0,0]
alpha = np.sqrt(lambda_ / B[0,0])
beta = np.sqrt(lambda_ * B[0,0] / (B[0,0] * B[1,1] - B[0,1] * B[0,1]))
gamma = -B[0,1] * alpha * alpha * beta / lambda_
u0 = gamma * v0 / beta - B[0,2] * alpha * alpha / lambda_
# Reconstitute intrinsic matrix
K = np.array([[alpha, gamma, u0],
[ 0., beta, v0],
[ 0., 0., 1.]])
return K