-
Notifications
You must be signed in to change notification settings - Fork 3
/
NonLinearTriangulation.py
54 lines (42 loc) · 1.8 KB
/
NonLinearTriangulation.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
import numpy as np
import scipy.optimize as optimize
from Utils.MiscUtils import ProjectionMatrix
def ReprojectionLoss(X, pts1, pts2, P1, P2):
# X = homo(X.reshape(1,-1)).reshape(-1,1) # make X a column of homogenous vector
p1_1T, p1_2T, p1_3T = P1 # rows of P1
p1_1T, p1_2T, p1_3T = p1_1T.reshape(1,-1), p1_2T.reshape(1,-1),p1_3T.reshape(1,-1)
p2_1T, p2_2T, p2_3T = P2 # rows of P2
p2_1T, p2_2T, p2_3T = p2_1T.reshape(1,-1), p2_2T.reshape(1,-1), p2_3T.reshape(1,-1)
## reprojection error for reference camera points - j = 1
u1,v1 = pts1[0], pts1[1]
u1_proj = np.divide(p1_1T.dot(X) , p1_3T.dot(X))
v1_proj = np.divide(p1_2T.dot(X) , p1_3T.dot(X))
E1= np.square(v1 - v1_proj) + np.square(u1 - u1_proj)
## reprojection error for second camera points - j = 2
u2,v2 = pts2[0], pts2[1]
u2_proj = np.divide(p2_1T.dot(X) , p2_3T.dot(X))
v2_proj = np.divide(p2_2T.dot(X) , p2_3T.dot(X))
E2= np.square(v2 - v2_proj) + np.square(u2 - u2_proj)
error = E1 + E2
return error.squeeze()
def NonLinearTriangulation(K, pts1, pts2, x3D, R1, C1, R2, C2):
"""
K : Camera Matrix
pts1, pts2 : Point Correspondences
x3D : initial 3D point
R2, C2 : relative camera pose
Returns:
x3D : optimized 3D points
"""
P1 = ProjectionMatrix(R1,C1,K)
P2 = ProjectionMatrix(R2,C2,K)
# pts1, pts2, x3D = pts1, pts2, x3D
if pts1.shape[0] != pts2.shape[0] != x3D.shape[0]:
raise 'Check point dimensions - level nlt'
x3D_ = []
for i in range(len(x3D)):
optimized_params = optimize.least_squares(fun=ReprojectionLoss, x0=x3D[i], method="trf", args=[pts1[i], pts2[i], P1, P2])
X1 = optimized_params.x
x3D_.append(X1)
# x3D_.append(X1[:3])
return np.array(x3D_)