1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.irurueta.ar.epipolar.estimators;
17
18 import com.irurueta.ar.epipolar.EssentialMatrix;
19 import com.irurueta.ar.epipolar.FundamentalMatrix;
20 import com.irurueta.geometry.GeometryException;
21 import com.irurueta.geometry.HomogeneousPoint2D;
22 import com.irurueta.geometry.PinholeCameraIntrinsicParameters;
23 import com.irurueta.geometry.Transformation2D;
24 import com.irurueta.geometry.estimators.LockedException;
25 import com.irurueta.geometry.estimators.NotReadyException;
26
27 import java.util.ArrayList;
28 import java.util.List;
29
30
31
32
33
34
35
36
37
38
39
40
41
42 public class PlanarFundamentalMatrixEstimator {
43
44
45
46
47 private Transformation2D homography;
48
49
50
51
52 private PinholeCameraIntrinsicParameters leftIntrinsics;
53
54
55
56
57 private PinholeCameraIntrinsicParameters rightIntrinsics;
58
59
60
61
62 private PlanarFundamentalMatrixEstimatorListener listener;
63
64
65
66
67
68 private boolean locked;
69
70
71
72
73 public PlanarFundamentalMatrixEstimator() {
74 }
75
76
77
78
79
80
81
82
83
84 public PlanarFundamentalMatrixEstimator(final Transformation2D homography,
85 final PinholeCameraIntrinsicParameters leftIntrinsics,
86 final PinholeCameraIntrinsicParameters rightIntrinsics) {
87 this.homography = homography;
88 this.leftIntrinsics = leftIntrinsics;
89 this.rightIntrinsics = rightIntrinsics;
90 }
91
92
93
94
95
96
97
98
99
100
101 public PlanarFundamentalMatrixEstimator(final Transformation2D homography,
102 final PinholeCameraIntrinsicParameters leftIntrinsics,
103 final PinholeCameraIntrinsicParameters rightIntrinsics,
104 final PlanarFundamentalMatrixEstimatorListener listener) {
105 this(homography, leftIntrinsics, rightIntrinsics);
106 this.listener = listener;
107 }
108
109
110
111
112
113
114 public Transformation2D getHomography() {
115 return homography;
116 }
117
118
119
120
121
122
123
124 public void setHomography(final Transformation2D homography) throws LockedException {
125 if (isLocked()) {
126 throw new LockedException();
127 }
128 this.homography = homography;
129 }
130
131
132
133
134
135
136 public PinholeCameraIntrinsicParameters getLeftIntrinsics() {
137 return leftIntrinsics;
138 }
139
140
141
142
143
144
145
146 public void setLeftIntrinsics(final PinholeCameraIntrinsicParameters leftIntrinsics) throws LockedException {
147 if (isLocked()) {
148 throw new LockedException();
149 }
150 this.leftIntrinsics = leftIntrinsics;
151 }
152
153
154
155
156
157
158 public PinholeCameraIntrinsicParameters getRightIntrinsics() {
159 return rightIntrinsics;
160 }
161
162
163
164
165
166
167
168 public void setRightIntrinsics(final PinholeCameraIntrinsicParameters rightIntrinsics) throws LockedException {
169 if (isLocked()) {
170 throw new LockedException();
171 }
172 this.rightIntrinsics = rightIntrinsics;
173 }
174
175
176
177
178
179
180 public PlanarFundamentalMatrixEstimatorListener getListener() {
181 return listener;
182 }
183
184
185
186
187
188
189 public void setListener(final PlanarFundamentalMatrixEstimatorListener listener) {
190 this.listener = listener;
191 }
192
193
194
195
196
197
198
199 public boolean isLocked() {
200 return locked;
201 }
202
203
204
205
206
207
208
209 public boolean isReady() {
210 return homography != null && leftIntrinsics != null && rightIntrinsics != null;
211 }
212
213
214
215
216
217
218
219
220
221
222 public List<FundamentalMatrix> estimate() throws LockedException, NotReadyException,
223 FundamentalMatrixEstimatorException {
224 final var result = new ArrayList<FundamentalMatrix>();
225 estimate(result);
226 return result;
227 }
228
229
230
231
232
233
234
235
236
237
238 public void estimate(final List<FundamentalMatrix> result) throws LockedException, NotReadyException,
239 FundamentalMatrixEstimatorException {
240 if (isLocked()) {
241 throw new LockedException();
242 }
243 if (!isReady()) {
244 throw new NotReadyException();
245 }
246
247 try {
248 locked = true;
249
250 if (listener != null) {
251 listener.onEstimateStart(this);
252 }
253
254 final var decomposer = new HomographyDecomposer(homography, leftIntrinsics, rightIntrinsics);
255
256 final var decompositions = decomposer.decompose();
257 result.clear();
258 for (final var decomposition : decompositions) {
259 final var rotation = decomposition.getTransformation().getRotation();
260 final var translation = new HomogeneousPoint2D(decomposition.getTransformation().getTranslation());
261 final var essential = new EssentialMatrix(rotation, translation);
262 final var fundamentalMatrix = essential.toFundamentalMatrix(leftIntrinsics, rightIntrinsics);
263 result.add(fundamentalMatrix);
264 }
265
266 if (listener != null) {
267 listener.onEstimateEnd(this, result);
268 }
269
270 } catch (final GeometryException e) {
271 throw new FundamentalMatrixEstimatorException(e);
272 } finally {
273 locked = false;
274 }
275 }
276 }