4
4
"""
5
5
6
6
import math
7
- import numpy as np
7
+
8
8
import matplotlib .pyplot as plt
9
+ import numpy as np
9
10
10
11
# ICP parameters
11
12
EPS = 0.0001
12
- MAXITER = 100
13
+ MAX_ITER = 100
13
14
14
15
show_animation = True
15
16
16
17
17
- def ICP_matching ( ppoints , cpoints ):
18
+ def icp_matching ( previous_points , current_points ):
18
19
"""
19
20
Iterative Closest Point matching
20
21
- input
21
- ppoints : 2D points in the previous frame
22
- cpoints : 2D points in the current frame
22
+ previous_points : 2D points in the previous frame
23
+ current_points : 2D points in the current frame
23
24
- output
24
25
R: Rotation matrix
25
26
T: Translation vector
@@ -35,17 +36,17 @@ def ICP_matching(ppoints, cpoints):
35
36
36
37
if show_animation : # pragma: no cover
37
38
plt .cla ()
38
- plt .plot (ppoints [0 , :], ppoints [1 , :], ".r" )
39
- plt .plot (cpoints [0 , :], cpoints [1 , :], ".b" )
39
+ plt .plot (previous_points [0 , :], previous_points [1 , :], ".r" )
40
+ plt .plot (current_points [0 , :], current_points [1 , :], ".b" )
40
41
plt .plot (0.0 , 0.0 , "xr" )
41
42
plt .axis ("equal" )
42
43
plt .pause (0.1 )
43
44
44
- inds , error = nearest_neighbor_assosiation ( ppoints , cpoints )
45
- Rt , Tt = SVD_motion_estimation ( ppoints [:, inds ], cpoints )
45
+ indexes , error = nearest_neighbor_association ( previous_points , current_points )
46
+ Rt , Tt = svd_motion_estimation ( previous_points [:, indexes ], current_points )
46
47
47
48
# update current points
48
- cpoints = (Rt @ cpoints ) + Tt [:, np .newaxis ]
49
+ current_points = (Rt @ current_points ) + Tt [:, np .newaxis ]
49
50
50
51
H = update_homogeneous_matrix (H , Rt , Tt )
51
52
@@ -56,7 +57,7 @@ def ICP_matching(ppoints, cpoints):
56
57
if dError <= EPS :
57
58
print ("Converge" , error , dError , count )
58
59
break
59
- elif MAXITER <= count :
60
+ elif MAX_ITER <= count :
60
61
print ("Not Converge..." , error , dError , count )
61
62
break
62
63
@@ -85,31 +86,29 @@ def update_homogeneous_matrix(Hin, R, T):
85
86
return Hin @ H
86
87
87
88
88
- def nearest_neighbor_assosiation ( ppoints , cpoints ):
89
+ def nearest_neighbor_association ( previous_points , current_points ):
89
90
90
91
# calc the sum of residual errors
91
- dcpoints = ppoints - cpoints
92
- d = np .linalg .norm (dcpoints , axis = 0 )
92
+ delta_points = previous_points - current_points
93
+ d = np .linalg .norm (delta_points , axis = 0 )
93
94
error = sum (d )
94
95
95
96
# calc index with nearest neighbor assosiation
96
- d = np .linalg .norm (
97
- np .repeat (cpoints , ppoints .shape [1 ], axis = 1 ) - np .tile (ppoints , (1 ,
98
- cpoints .shape [1 ])), axis = 0 )
99
- inds = np .argmin (d .reshape (cpoints .shape [1 ], ppoints .shape [1 ]), axis = 1 )
100
-
101
- return inds , error
97
+ d = np .linalg .norm (np .repeat (current_points , previous_points .shape [1 ], axis = 1 )
98
+ - np .tile (previous_points , (1 , current_points .shape [1 ])), axis = 0 )
99
+ indexes = np .argmin (d .reshape (current_points .shape [1 ], previous_points .shape [1 ]), axis = 1 )
102
100
101
+ return indexes , error
103
102
104
- def SVD_motion_estimation (ppoints , cpoints ):
105
103
106
- pm = np .mean (ppoints , axis = 1 )
107
- cm = np .mean (cpoints , axis = 1 )
104
+ def svd_motion_estimation (previous_points , current_points ):
105
+ pm = np .mean (previous_points , axis = 1 )
106
+ cm = np .mean (current_points , axis = 1 )
108
107
109
- pshift = ppoints - pm [:, np .newaxis ]
110
- cshift = cpoints - cm [:, np .newaxis ]
108
+ p_shift = previous_points - pm [:, np .newaxis ]
109
+ c_shift = current_points - cm [:, np .newaxis ]
111
110
112
- W = cshift @ pshift .T
111
+ W = c_shift @ p_shift .T
113
112
u , s , vh = np .linalg .svd (W )
114
113
115
114
R = (u @ vh ).T
@@ -133,16 +132,16 @@ def main():
133
132
# previous points
134
133
px = (np .random .rand (nPoint ) - 0.5 ) * fieldLength
135
134
py = (np .random .rand (nPoint ) - 0.5 ) * fieldLength
136
- ppoints = np .vstack ((px , py ))
135
+ previous_points = np .vstack ((px , py ))
137
136
138
137
# current points
139
138
cx = [math .cos (motion [2 ]) * x - math .sin (motion [2 ]) * y + motion [0 ]
140
139
for (x , y ) in zip (px , py )]
141
140
cy = [math .sin (motion [2 ]) * x + math .cos (motion [2 ]) * y + motion [1 ]
142
141
for (x , y ) in zip (px , py )]
143
- cpoints = np .vstack ((cx , cy ))
142
+ current_points = np .vstack ((cx , cy ))
144
143
145
- R , T = ICP_matching ( ppoints , cpoints )
144
+ R , T = icp_matching ( previous_points , current_points )
146
145
print ("R:" , R )
147
146
print ("T:" , T )
148
147
0 commit comments