1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.irurueta.ar.sfm;
17
18 import com.irurueta.ar.calibration.estimators.DualAbsoluteQuadricEstimator;
19 import com.irurueta.ar.calibration.estimators.LMSEDualAbsoluteQuadricEstimator;
20 import com.irurueta.ar.epipolar.FundamentalMatrix;
21 import com.irurueta.geometry.PinholeCamera;
22 import com.irurueta.geometry.estimators.LockedException;
23 import com.irurueta.geometry.estimators.NotReadyException;
24
25 import java.util.ArrayList;
26
27
28
29
30
31
32
33
34 public class DualAbsoluteQuadricInitialCamerasEstimator extends InitialCamerasEstimator {
35
36
37
38
39
40
41 private double aspectRatio = DualAbsoluteQuadricEstimator.DEFAULT_FOCAL_DISTANCE_ASPECT_RATIO;
42
43
44
45
46 public DualAbsoluteQuadricInitialCamerasEstimator() {
47 super();
48 }
49
50
51
52
53
54
55 public DualAbsoluteQuadricInitialCamerasEstimator(final FundamentalMatrix fundamentalMatrix) {
56 super(fundamentalMatrix);
57 }
58
59
60
61
62
63
64 public DualAbsoluteQuadricInitialCamerasEstimator(final InitialCamerasEstimatorListener listener) {
65 super(listener);
66 }
67
68
69
70
71
72
73
74 public DualAbsoluteQuadricInitialCamerasEstimator(
75 final FundamentalMatrix fundamentalMatrix, final InitialCamerasEstimatorListener listener) {
76 super(fundamentalMatrix, listener);
77 }
78
79
80
81
82
83
84 @Override
85 public InitialCamerasEstimatorMethod getMethod() {
86 return InitialCamerasEstimatorMethod.DUAL_ABSOLUTE_QUADRIC;
87 }
88
89
90
91
92
93
94 @Override
95 public boolean isReady() {
96 return fundamentalMatrix != null;
97 }
98
99
100
101
102
103
104
105
106
107
108 @Override
109 public void estimate() throws LockedException, NotReadyException, InitialCamerasEstimationFailedException {
110 if (isLocked()) {
111 throw new LockedException();
112 }
113
114 if (!isReady()) {
115 throw new NotReadyException();
116 }
117
118 try {
119 locked = true;
120
121 if (listener != null) {
122 listener.onStart(this);
123 }
124
125 if (estimatedLeftCamera == null) {
126 estimatedLeftCamera = new PinholeCamera();
127 }
128 if (estimatedRightCamera == null) {
129 estimatedRightCamera = new PinholeCamera();
130 }
131
132 generateInitialMetricCamerasUsingDAQ(fundamentalMatrix, aspectRatio, estimatedLeftCamera,
133 estimatedRightCamera);
134
135 if (listener != null) {
136 listener.onFinish(this, estimatedLeftCamera, estimatedRightCamera);
137 }
138 } catch (final InitialCamerasEstimationFailedException e) {
139 if (listener != null) {
140 listener.onFail(this, e);
141 }
142 throw e;
143 } finally {
144 locked = false;
145 }
146 }
147
148
149
150
151
152
153
154
155 public double getAspectRatio() {
156 return aspectRatio;
157 }
158
159
160
161
162
163
164
165
166
167 public void setAspectRatio(final double aspectRatio) throws LockedException {
168 if (isLocked()) {
169 throw new LockedException();
170 }
171 this.aspectRatio = aspectRatio;
172 }
173
174
175
176
177
178
179
180
181
182
183
184 public static void generateInitialMetricCamerasUsingDAQ(
185 final FundamentalMatrix fundamentalMatrix,
186 final PinholeCamera leftCamera,
187 final PinholeCamera rightCamera)
188 throws InitialCamerasEstimationFailedException {
189 generateInitialMetricCamerasUsingDAQ(fundamentalMatrix,
190 DualAbsoluteQuadricEstimator.DEFAULT_FOCAL_DISTANCE_ASPECT_RATIO, leftCamera, rightCamera);
191 }
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206 public static void generateInitialMetricCamerasUsingDAQ(
207 final FundamentalMatrix fundamentalMatrix,
208 final double aspectRatio,
209 final PinholeCamera leftCamera,
210 final PinholeCamera rightCamera)
211 throws InitialCamerasEstimationFailedException {
212
213 try {
214
215 fundamentalMatrix.generateCamerasInArbitraryProjectiveSpace(leftCamera, rightCamera);
216
217 final var cameras = new ArrayList<PinholeCamera>();
218 cameras.add(leftCamera);
219 cameras.add(rightCamera);
220
221
222 final var daqEstimator = new LMSEDualAbsoluteQuadricEstimator(cameras);
223 daqEstimator.setLMSESolutionAllowed(false);
224 daqEstimator.setZeroSkewness(true);
225 daqEstimator.setPrincipalPointAtOrigin(true);
226 daqEstimator.setFocalDistanceAspectRatioKnown(true);
227 daqEstimator.setFocalDistanceAspectRatio(aspectRatio);
228 daqEstimator.setSingularityEnforced(true);
229
230 final var daq = daqEstimator.estimate();
231 final var transformation = daq.getMetricToProjectiveTransformation();
232
233
234 transformation.inverse();
235
236
237 transformation.transform(leftCamera);
238 transformation.transform(rightCamera);
239 } catch (final Exception e) {
240 throw new InitialCamerasEstimationFailedException(e);
241 }
242 }
243 }