1 /*
2 * Copyright (C) 2015 Alberto Irurueta Carro (alberto@irurueta.com)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package com.irurueta.ar.epipolar;
17
18 import com.irurueta.geometry.Point2D;
19 import com.irurueta.geometry.estimators.NotReadyException;
20
21 /**
22 * Fixes a single matched pair of points so that they perfectly follow a given
23 * epipolar geometry.
24 * When matching points typically the matching precision is about 1 pixel,
25 * however this makes that matched points under a given epipolar geometry (i.e.
26 * fundamental or essential matrix), do not lie perfectly on the corresponding
27 * epipolar plane or epipolar lines.
28 * The consequence is that triangularization of these matches will fail or
29 * produce inaccurate results.
30 * By fixing matched points using a corrector following a given epipolar
31 * geometry, this effect is alleviated.
32 * This is an abstract class, subclasses will implement different methods to
33 * fix matched points coordinates
34 */
35 public abstract class SingleCorrector {
36
37 /**
38 * Default corrector type.
39 */
40 public static final CorrectorType DEFAULT_TYPE = CorrectorType.GOLD_STANDARD;
41
42 /**
43 * Left matched point to be corrected.
44 */
45 protected Point2D leftPoint;
46
47 /**
48 * Right matched point to be corrected.
49 */
50 protected Point2D rightPoint;
51
52 /**
53 * Left matched point after correction.
54 */
55 protected Point2D leftCorrectedPoint;
56
57 /**
58 * Right matched point after correction.
59 */
60 protected Point2D rightCorrectedPoint;
61
62 /**
63 * A fundamental matrix defining an epipolar geometry.
64 */
65 protected FundamentalMatrix fundamentalMatrix;
66
67 /**
68 * Constructor.
69 */
70 protected SingleCorrector() {
71 }
72
73 /**
74 * Constructor.
75 *
76 * @param fundamentalMatrix fundamental matrix defining the epipolar
77 * geometry.
78 */
79 protected SingleCorrector(final FundamentalMatrix fundamentalMatrix) {
80 setFundamentalMatrix(fundamentalMatrix);
81 }
82
83 /**
84 * Constructor.
85 *
86 * @param leftPoint matched point on left view to be corrected.
87 * @param rightPoint matched point on right view to be corrected.
88 */
89 protected SingleCorrector(final Point2D leftPoint, final Point2D rightPoint) {
90 setPoints(leftPoint, rightPoint);
91 }
92
93 /**
94 * Constructor.
95 *
96 * @param leftPoint matched point on left view to be corrected.
97 * @param rightPoint matched point on right view to be corrected.
98 * @param fundamentalMatrix fundamental matrix defining an epipolar geometry.
99 */
100 protected SingleCorrector(final Point2D leftPoint, final Point2D rightPoint,
101 final FundamentalMatrix fundamentalMatrix) {
102 setPointsAndFundamentalMatrix(leftPoint, rightPoint, fundamentalMatrix);
103 }
104
105 /**
106 * Sets a matched pair of points to be corrected and a fundamental matrix
107 * defining the epipolar geometry.
108 *
109 * @param leftPoint matched point on left view to be corrected.
110 * @param rightPoint matched point on right view to be corrected.
111 * @param fundamentalMatrix fundamental matrix defining an epipolar geometry.
112 */
113 public final void setPointsAndFundamentalMatrix(
114 final Point2D leftPoint, final Point2D rightPoint, final FundamentalMatrix fundamentalMatrix) {
115 setPoints(leftPoint, rightPoint);
116 setFundamentalMatrix(fundamentalMatrix);
117 }
118
119 /**
120 * Sets a matched pair of points to be corrected.
121 *
122 * @param leftPoint matched point on left view to be corrected.
123 * @param rightPoint matched point on right view to be corrected.
124 */
125 public final void setPoints(final Point2D leftPoint, final Point2D rightPoint) {
126 this.leftPoint = leftPoint;
127 this.rightPoint = rightPoint;
128 }
129
130 /**
131 * Sets the fundamental matrix defining the epipolar geometry.
132 *
133 * @param fundamentalMatrix fundamental matrix to be set.
134 */
135 public final void setFundamentalMatrix(final FundamentalMatrix fundamentalMatrix) {
136 this.fundamentalMatrix = fundamentalMatrix;
137 }
138
139 /**
140 * Returns matched point on left view.
141 *
142 * @return matched point on left view.
143 */
144 public Point2D getLeftPoint() {
145 return leftPoint;
146 }
147
148 /**
149 * Returns matched point on right view.
150 *
151 * @return matched point on right view.
152 */
153 public Point2D getRightPoint() {
154 return rightPoint;
155 }
156
157 /**
158 * Returns fundamental matrix defining epipolar geometry.
159 *
160 * @return fundamental matrix defining epipolar geometry.
161 */
162 public FundamentalMatrix getFundamentalMatrix() {
163 return fundamentalMatrix;
164 }
165
166 /**
167 * Indicates whether this instance is ready to correct provided left
168 * and right points using provided fundamental matrix.
169 *
170 * @return true if ready, false otherwise.
171 */
172 public boolean isReady() {
173 return leftPoint != null && rightPoint != null && fundamentalMatrix != null
174 && fundamentalMatrix.isInternalMatrixAvailable();
175 }
176
177 /**
178 * Returns matched point on left view after correction.
179 *
180 * @return matched point on left view after correction.
181 */
182 public Point2D getLeftCorrectedPoint() {
183 return leftCorrectedPoint;
184 }
185
186 /**
187 * Returns matched point on right view after correction.
188 *
189 * @return matched point on right view after correction.
190 */
191 public Point2D getRightCorrectedPoint() {
192 return rightCorrectedPoint;
193 }
194
195 /**
196 * Corrects the pair of provided matched points to be corrected.
197 *
198 * @throws NotReadyException if this instance is not ready (either points or
199 * fundamental matrix has not been provided yet).
200 * @throws CorrectionException if correction fails.
201 */
202 public abstract void correct() throws NotReadyException, CorrectionException;
203
204 /**
205 * Gets type of correction being used.
206 *
207 * @return type of correction.
208 */
209 public abstract CorrectorType getType();
210
211 /**
212 * Creates an instance of a single corrector using provided type.
213 *
214 * @param type a corrector type.
215 * @return an instance of a single corrector.
216 */
217 public static SingleCorrector create(final CorrectorType type) {
218 return type == CorrectorType.SAMPSON_CORRECTOR
219 ? new SampsonSingleCorrector() : new GoldStandardSingleCorrector();
220 }
221
222 /**
223 * Creates an instance of a single corrector using provided fundamental
224 * matrix and provided type.
225 *
226 * @param fundamentalMatrix fundamental matrix defining the epipolar
227 * geometry.
228 * @param type a corrector type.
229 * @return an instance of a single corrector.
230 */
231 public static SingleCorrector create(final FundamentalMatrix fundamentalMatrix, final CorrectorType type) {
232 return type == CorrectorType.SAMPSON_CORRECTOR
233 ? new SampsonSingleCorrector(fundamentalMatrix) : new GoldStandardSingleCorrector(fundamentalMatrix);
234 }
235
236 /**
237 * Creates an instance of a single corrector using provided left and right
238 * points to be corrected, and provided type.
239 *
240 * @param leftPoint matched point on left view to be corrected.
241 * @param rightPoint matched point on right view to be corrected.
242 * @param type a corrector type.
243 * @return an instance of a single corrector.
244 */
245 public static SingleCorrector create(final Point2D leftPoint, final Point2D rightPoint, final CorrectorType type) {
246 return type == CorrectorType.SAMPSON_CORRECTOR
247 ? new SampsonSingleCorrector(leftPoint, rightPoint)
248 : new GoldStandardSingleCorrector(leftPoint, rightPoint);
249 }
250
251 /**
252 * Creates an instance of a single corrector using provided left and right
253 * points to be corrected, fundamental matrix and provided type.
254 *
255 * @param leftPoint matched point on left view to be corrected.
256 * @param rightPoint matched point on right view to be corrected.
257 * @param fundamentalMatrix fundamental matrix defining the epipolar
258 * geometry.
259 * @param type a corrector type.
260 * @return an instance of a single corrector.
261 */
262 public static SingleCorrector create(
263 final Point2D leftPoint, final Point2D rightPoint, final FundamentalMatrix fundamentalMatrix,
264 final CorrectorType type) {
265 return type == CorrectorType.SAMPSON_CORRECTOR
266 ? new SampsonSingleCorrector(leftPoint, rightPoint, fundamentalMatrix)
267 : new GoldStandardSingleCorrector(leftPoint, rightPoint, fundamentalMatrix);
268 }
269
270 /**
271 * Creates an instance of a single corrector using default type.
272 *
273 * @return an instance of a single corrector.
274 */
275 public static SingleCorrector create() {
276 return create(DEFAULT_TYPE);
277 }
278
279 /**
280 * Creates an instance of a single corrector using provided fundamental
281 * matrix and default type.
282 *
283 * @param fundamentalMatrix fundamental matrix defining the epipolar
284 * geometry.
285 * @return an instance of a single corrector.
286 */
287 public static SingleCorrector create(final FundamentalMatrix fundamentalMatrix) {
288 return create(fundamentalMatrix, DEFAULT_TYPE);
289 }
290
291 /**
292 * Creates an instance of a single corrector using provided left and right
293 * points to be corrected.
294 *
295 * @param leftPoint matched point on left view to be corrected.
296 * @param rightPoint matched point on right view to be corrected.
297 * @return an instance of a single corrector.
298 */
299 public static SingleCorrector create(final Point2D leftPoint, final Point2D rightPoint) {
300 return create(leftPoint, rightPoint, DEFAULT_TYPE);
301 }
302
303 /**
304 * Creates an instance of a single corrector using provided left and right
305 * points to be corrected, provided fundamental matrix and default type.
306 *
307 * @param leftPoint matched point on left view to be corrected.
308 * @param rightPoint matched point on right view to be corrected.
309 * @param fundamentalMatrix fundamental matrix defining the epipolar
310 * geometry.
311 * @return an instance of a single corrector.
312 */
313 public static SingleCorrector create(
314 final Point2D leftPoint, final Point2D rightPoint,
315 final FundamentalMatrix fundamentalMatrix) {
316 return create(leftPoint, rightPoint, fundamentalMatrix, DEFAULT_TYPE);
317 }
318 }