View Javadoc
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 }