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.geometry.estimators;
17  
18  import com.irurueta.algebra.Matrix;
19  import com.irurueta.geometry.Line2D;
20  import com.irurueta.geometry.Point2D;
21  import com.irurueta.geometry.ProjectiveTransformation2D;
22  import com.irurueta.numerical.robust.InliersData;
23  import com.irurueta.numerical.robust.RobustEstimatorException;
24  import com.irurueta.numerical.robust.RobustEstimatorMethod;
25  
26  import java.util.List;
27  
28  /**
29   * This is an abstract class for algorithms to robustly find the best projective
30   * 2D transformation for collections of matching 2D points, or 2D lines.
31   * Implementations o this class should be able to detect and discard outliers
32   * in order to find the best solution.
33   */
34  public abstract class ProjectiveTransformation2DRobustEstimator {
35  
36      /**
37       * Minimum number of matched points or matched lines required to estimate a
38       * projective 2D transformation.
39       */
40      public static final int MINIMUM_SIZE = 4;
41  
42      /**
43       * Default amount of progress variation before notifying a change in
44       * estimation progress. By default, this is set to 5%.
45       */
46      public static final float DEFAULT_PROGRESS_DELTA = 0.05f;
47  
48      /**
49       * Minimum allowed value for progress delta.
50       */
51      public static final float MIN_PROGRESS_DELTA = 0.0f;
52  
53      /**
54       * Maximum allowed value for progress delta.
55       */
56      public static final float MAX_PROGRESS_DELTA = 1.0f;
57  
58      /**
59       * Constant defining default confidence of the estimated result, which is
60       * 99%. This means that with a probability of 99% estimation will be
61       * accurate because chosen sub-samples will be inliers.
62       */
63      public static final double DEFAULT_CONFIDENCE = 0.99;
64  
65      /**
66       * Default maximum allowed number of iterations.
67       */
68      public static final int DEFAULT_MAX_ITERATIONS = 5000;
69  
70      /**
71       * Minimum allowed confidence value.
72       */
73      public static final double MIN_CONFIDENCE = 0.0;
74  
75      /**
76       * Maximum allowed confidence value.
77       */
78      public static final double MAX_CONFIDENCE = 1.0;
79  
80      /**
81       * Minimum allowed number of iterations.
82       */
83      public static final int MIN_ITERATIONS = 1;
84  
85      /**
86       * Indicates that result is refined by default using Levenberg-Marquardt
87       * fitting algorithm over found inliers.
88       */
89      public static final boolean DEFAULT_REFINE_RESULT = true;
90  
91      /**
92       * Indicates that covariance is not kept by default after refining result.
93       */
94      public static final boolean DEFAULT_KEEP_COVARIANCE = false;
95  
96      /**
97       * Listener to be notified of events such as when estimation starts, ends or
98       * its progress significantly changes.
99       */
100     protected ProjectiveTransformation2DRobustEstimatorListener listener;
101 
102     /**
103      * Indicates if this estimator is locked because an estimation is being
104      * computed.
105      */
106     protected volatile boolean locked;
107 
108     /**
109      * Amount of progress variation before notifying a progress change during
110      * estimation.
111      */
112     protected float progressDelta;
113 
114     /**
115      * Amount of confidence expressed as a value between 0.0 and 1.0 (which is
116      * equivalent to 100%). The amount of confidence indicates the probability
117      * that the estimated result is correct. Usually this value will be close
118      * to 1.0, but not exactly 1.0.
119      */
120     protected double confidence;
121 
122     /**
123      * Maximum allowed number of iterations. When the maximum number of
124      * iterations is exceeded, result will not be available, however an
125      * approximate result will be available for retrieval.
126      */
127     protected int maxIterations;
128 
129     /**
130      * Data related to inliers found after estimation.
131      */
132     protected InliersData inliersData;
133 
134     /**
135      * Indicates whether result must be refined using Levenberg-Marquardt
136      * fitting algorithm over found inliers.
137      * If true, inliers will be computed and kept in any implementation
138      * regardless of the settings.
139      */
140     protected boolean refineResult;
141 
142     /**
143      * Indicates whether covariance must be kept after refining result.
144      * This setting is only taken into account if result is refined.
145      */
146     protected boolean keepCovariance;
147 
148     /**
149      * Estimated covariance of estimated 2D projective transformation.
150      * This is only available when result has been refined and covariance is
151      * kept.
152      */
153     protected Matrix covariance;
154 
155     /**
156      * Constructor.
157      */
158     protected ProjectiveTransformation2DRobustEstimator() {
159         progressDelta = DEFAULT_PROGRESS_DELTA;
160         confidence = DEFAULT_CONFIDENCE;
161         maxIterations = DEFAULT_MAX_ITERATIONS;
162         refineResult = DEFAULT_REFINE_RESULT;
163         keepCovariance = DEFAULT_KEEP_COVARIANCE;
164     }
165 
166     /**
167      * Constructor.
168      *
169      * @param listener listener to be notified of events such as when estimation
170      *                 starts, ends or its progress significantly changes.
171      */
172     protected ProjectiveTransformation2DRobustEstimator(
173             final ProjectiveTransformation2DRobustEstimatorListener listener) {
174         this.listener = listener;
175         progressDelta = DEFAULT_PROGRESS_DELTA;
176         confidence = DEFAULT_CONFIDENCE;
177         maxIterations = DEFAULT_MAX_ITERATIONS;
178         refineResult = DEFAULT_REFINE_RESULT;
179         keepCovariance = DEFAULT_KEEP_COVARIANCE;
180     }
181 
182     /**
183      * Returns reference to listener to be notified of events such as when
184      * estimation starts, ends or its progress significantly changes.
185      *
186      * @return listener to be notified of events.
187      */
188     public ProjectiveTransformation2DRobustEstimatorListener getListener() {
189         return listener;
190     }
191 
192     /**
193      * Sets listener to be notified of events such as when estimation starts,
194      * ends or its progress significantly changes.
195      *
196      * @param listener listener to be notified of events.
197      * @throws LockedException if robust estimator is locked.
198      */
199     public void setListener(final ProjectiveTransformation2DRobustEstimatorListener listener) throws LockedException {
200         if (isLocked()) {
201             throw new LockedException();
202         }
203         this.listener = listener;
204     }
205 
206     /**
207      * Indicates whether listener has been provided and is available for
208      * retrieval.
209      *
210      * @return true if available, false otherwise.
211      */
212     public boolean isListenerAvailable() {
213         return listener != null;
214     }
215 
216     /**
217      * Indicates if this instance is locked because estimation is being computed.
218      *
219      * @return true if locked, false otherwise.
220      */
221     public boolean isLocked() {
222         return locked;
223     }
224 
225     /**
226      * Returns amount of progress variation before notifying a progress change
227      * during estimation.
228      *
229      * @return amount of progress variation before notifying a progress change
230      * during estimation.
231      */
232     public float getProgressDelta() {
233         return progressDelta;
234     }
235 
236     /**
237      * Sets amount of progress variation before notifying a progress change
238      * during estimation.
239      *
240      * @param progressDelta amount of progress variation before notifying a
241      *                      progress change during estimation.
242      * @throws IllegalArgumentException if progress delta is less than zero or
243      *                                  greater than 1.
244      * @throws LockedException          if this estimator is locked because an estimation
245      *                                  is being computed.
246      */
247     public void setProgressDelta(final float progressDelta) throws LockedException {
248         if (isLocked()) {
249             throw new LockedException();
250         }
251         if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
252             throw new IllegalArgumentException();
253         }
254         this.progressDelta = progressDelta;
255     }
256 
257     /**
258      * Returns amount of confidence expressed as a value between 0.0 and 1.0
259      * (which is equivalent to 100%). The amount of confidence indicates the
260      * probability that the estimated result is correct. Usually this value will
261      * be close to 1.0, but not exactly 1.0.
262      *
263      * @return amount of confidence as a value between 0.0 and 1.0.
264      */
265     public double getConfidence() {
266         return confidence;
267     }
268 
269     /**
270      * Sets amount of confidence expressed as a value between 0.0 and 1.0 (which
271      * is equivalent to 100%). The amount of confidence indicates the
272      * probability that the estimated result is correct. Usually this value will
273      * be close to 1.0, but not exactly 1.0.
274      *
275      * @param confidence confidence to be set as a value between 0.0 and 1.0.
276      * @throws IllegalArgumentException if provided value is not between 0.0 and
277      *                                  1.0.
278      * @throws LockedException          if this estimator is locked because an estimator
279      *                                  is being computed.
280      */
281     public void setConfidence(final double confidence) throws LockedException {
282         if (isLocked()) {
283             throw new LockedException();
284         }
285         if (confidence < MIN_CONFIDENCE || confidence > MAX_CONFIDENCE) {
286             throw new IllegalArgumentException();
287         }
288         this.confidence = confidence;
289     }
290 
291     /**
292      * Returns maximum allowed number of iterations. If maximum allowed number
293      * of iterations is achieved without converging to a result when calling
294      * estimate(), a RobustEstimatorException will be raised.
295      *
296      * @return maximum allowed number of iterations.
297      */
298     public int getMaxIterations() {
299         return maxIterations;
300     }
301 
302     /**
303      * Sets maximum allowed number of iterations. When the maximum number of
304      * iterations is exceeded, result will not be available, however an
305      * approximate result will be available for retrieval.
306      *
307      * @param maxIterations maximum allowed number of iterations to be set.
308      * @throws IllegalArgumentException if provided value is less than 1.
309      * @throws LockedException          if this estimator is locked because an estimation
310      *                                  is being computed.
311      */
312     public void setMaxIterations(final int maxIterations) throws LockedException {
313         if (isLocked()) {
314             throw new LockedException();
315         }
316         if (maxIterations < MIN_ITERATIONS) {
317             throw new IllegalArgumentException();
318         }
319         this.maxIterations = maxIterations;
320     }
321 
322     /**
323      * Gets data related to inliers found after estimation.
324      *
325      * @return data related to inliers found after estimation.
326      */
327     public InliersData getInliersData() {
328         return inliersData;
329     }
330 
331     /**
332      * Indicates whether result must be refined using Levenberg-Marquardt
333      * fitting algorithm over found inliers.
334      * If true, inliers will be computed and kept in any implementation
335      * regardless of the settings.
336      *
337      * @return true to refine result, false to simply use result found by
338      * robust estimator without further refining.
339      */
340     public boolean isResultRefined() {
341         return refineResult;
342     }
343 
344     /**
345      * Specifies whether result must be refined using Levenberg-Marquardt
346      * fitting algorithm over found inliers.
347      *
348      * @param refineResult true to refine result, false to simply use result
349      *                     found by robust estimator without further refining.
350      * @throws LockedException if estimator is locked.
351      */
352     public void setResultRefined(final boolean refineResult) throws LockedException {
353         if (isLocked()) {
354             throw new LockedException();
355         }
356         this.refineResult = refineResult;
357     }
358 
359     /**
360      * Indicates whether covariance must be kept after refining result.
361      * This setting is only taken into account if result is refined.
362      *
363      * @return true if covariance must be kept after refining result, false
364      * otherwise.
365      */
366     public boolean isCovarianceKept() {
367         return keepCovariance;
368     }
369 
370     /**
371      * Specifies whether covariance must be kept after refining result.
372      * This setting is only taken into account if result is refined.
373      *
374      * @param keepCovariance true if covariance must be kept after refining
375      *                       result, false otherwise.
376      * @throws LockedException if estimator is locked.
377      */
378     public void setCovarianceKept(final boolean keepCovariance) throws LockedException {
379         if (isLocked()) {
380             throw new LockedException();
381         }
382         this.keepCovariance = keepCovariance;
383     }
384 
385     /**
386      * Gets estimated covariance of estimated homography if available.
387      * This is only available when result has been refined and covariance is
388      * kept.
389      *
390      * @return estimated covariance or null.
391      */
392     public Matrix getCovariance() {
393         return covariance;
394     }
395 
396     /**
397      * Estimates a projective 2D transformation using a robust estimator and
398      * the best set of matched 2D point correspondences found using the robust
399      * estimator.
400      *
401      * @return a projective 2D transformation.
402      * @throws LockedException          if robust estimator is locked because an
403      *                                  estimation is already in progress.
404      * @throws NotReadyException        if provided input data is not enough to start
405      *                                  the estimation.
406      * @throws RobustEstimatorException if estimation fails for any reason
407      *                                  (i.e. numerical instability, no solution available, etc).
408      */
409     public abstract ProjectiveTransformation2D estimate() throws LockedException, NotReadyException,
410             RobustEstimatorException;
411 
412     /**
413      * Returns method being used for robust estimation.
414      *
415      * @return method being used for robust estimation.
416      */
417     public abstract RobustEstimatorMethod getMethod();
418 
419     /**
420      * Creates a projective 2D transformation estimator based on 2D point
421      * correspondences and using provided robust estimator method.
422      *
423      * @param inputPoints  list of input points to be used to estimate a
424      *                     projective 2D transformation.
425      * @param outputPoints list of output points to be used to estimate a
426      *                     projective 2D transformation.
427      * @param method       method of a robust estimator algorithm to estimate best
428      *                     projective 2D transformation.
429      * @return an instance of a projective 2D transformation estimator.
430      * @throws IllegalArgumentException if provided lists of points don't have
431      *                                  the same size or their size is smaller than MINIMUM_SIZE.
432      */
433     public static ProjectiveTransformation2DRobustEstimator createFromPoints(
434             final List<Point2D> inputPoints, final List<Point2D> outputPoints, final RobustEstimatorMethod method) {
435         return PointCorrespondenceProjectiveTransformation2DRobustEstimator.create(inputPoints, outputPoints, method);
436     }
437 
438     /**
439      * Creates a projective 2D transformation estimator based on 2D point
440      * correspondences and using provided robust estimator method.
441      *
442      * @param listener     listener to be notified of events such as when estimation
443      *                     starts, ends or its progress significantly changes.
444      * @param inputPoints  list of input points to be used to estimate a
445      *                     projective 2D transformation.
446      * @param outputPoints list of output points to be used to estimate a
447      *                     projective 2D transformation.
448      * @param method       method of a robust estimator algorithm to estimate best
449      *                     projective 2D transformation.
450      * @return an instance of a projective 2D transformation estimator.
451      * @throws IllegalArgumentException if provided lists of points don't have
452      *                                  the same size or their size is smaller than MINIMUM_SIZE.
453      */
454     public static ProjectiveTransformation2DRobustEstimator createFromPoints(
455             final ProjectiveTransformation2DRobustEstimatorListener listener, final List<Point2D> inputPoints,
456             final List<Point2D> outputPoints, final RobustEstimatorMethod method) {
457         return PointCorrespondenceProjectiveTransformation2DRobustEstimator.create(listener, inputPoints, outputPoints,
458                 method);
459     }
460 
461     /**
462      * Creates a projective 2D transformation estimator based on 2D point
463      * correspondences and using provided robust estimator method.
464      *
465      * @param inputPoints   list of input points to be used to estimate a
466      *                      projective 2D transformation.
467      * @param outputPoints  list of output points to be used to estimate a
468      *                      projective 2D transformation.
469      * @param qualityScores quality scores corresponding to each pair of matched
470      *                      points.
471      * @param method        method of a robust estimator algorithm to estimate best
472      *                      projective 2D transformation.
473      * @return an instance of projective 2D transformation estimator.
474      * @throws IllegalArgumentException if provided lists of points don't have
475      *                                  the same size or their size is smaller than MINIMUM_SIZE.
476      */
477     public static ProjectiveTransformation2DRobustEstimator createFromPoints(
478             final List<Point2D> inputPoints, final List<Point2D> outputPoints, final double[] qualityScores,
479             final RobustEstimatorMethod method) {
480         return PointCorrespondenceProjectiveTransformation2DRobustEstimator.create(inputPoints, outputPoints,
481                 qualityScores, method);
482     }
483 
484     /**
485      * Creates a projective 2D transformation estimator based on 2D point
486      * correspondences and using provided robust estimator method.
487      *
488      * @param listener      listener to be notified of events such as when estimation
489      *                      starts, ends or its progress significantly changes.
490      * @param inputPoints   list of input points to be used to estimate a
491      *                      projective 2D transformation.
492      * @param outputPoints  list of output points to be used to estimate a
493      *                      projective 2D transformation.
494      * @param qualityScores quality scores corresponding to each pair of matched
495      *                      points.
496      * @param method        method of a robust estimator algorithm to estimate best
497      *                      projective 2D transformation.
498      * @return an instance of projective 2D transformation estimator.
499      * @throws IllegalArgumentException if provided lists of points doesn't have
500      *                                  the same size or their size is smaller than MINIMUM_SIZE.
501      */
502     public static ProjectiveTransformation2DRobustEstimator createFromPoints(
503             final ProjectiveTransformation2DRobustEstimatorListener listener, final List<Point2D> inputPoints,
504             final List<Point2D> outputPoints, final double[] qualityScores, final RobustEstimatorMethod method) {
505         return PointCorrespondenceProjectiveTransformation2DRobustEstimator.create(listener, inputPoints, outputPoints,
506                 qualityScores, method);
507     }
508 
509     /**
510      * Creates a projective 2D transformation estimator based on 2D point
511      * correspondences and using default robust estimator method.
512      *
513      * @param inputPoints  list of input points to be used to estimate a
514      *                     projective 2D transformation.
515      * @param outputPoints list of output points to be used to estimate a
516      *                     projective 2D transformation.
517      * @return an instance of a projective 2D transformation estimator.
518      * @throws IllegalArgumentException if provided lists of points don't have
519      *                                  the same size or their size is smaller than MINIMUM_SIZE.
520      */
521     public static ProjectiveTransformation2DRobustEstimator createFromPoints(
522             final List<Point2D> inputPoints, final List<Point2D> outputPoints) {
523         return PointCorrespondenceProjectiveTransformation2DRobustEstimator.create(inputPoints, outputPoints);
524     }
525 
526     /**
527      * Creates a projective 2D transformation estimator based on 2D point
528      * correspondences and using default robust estimator method.
529      *
530      * @param listener     listener to be notified of events such as when estimation
531      *                     starts, ends or its progress significantly changes.
532      * @param inputPoints  list of input points to be used to estimate a
533      *                     projective 2D transformation.
534      * @param outputPoints list of output points to be used to estimate a
535      *                     projective 2D transformation.
536      * @return an instance of projective 2D transformation estimator.
537      * @throws IllegalArgumentException if provided lists of points don't have
538      *                                  the same size or their size is smaller than MINIMUM_SIZE.
539      */
540     public static ProjectiveTransformation2DRobustEstimator createFromPoints(
541             final ProjectiveTransformation2DRobustEstimatorListener listener,
542             final List<Point2D> inputPoints, final List<Point2D> outputPoints) {
543         return PointCorrespondenceProjectiveTransformation2DRobustEstimator.create(listener, inputPoints,
544                 outputPoints);
545     }
546 
547     /**
548      * Creates a projective 2D transformation estimator based on 2D point
549      * correspondences and using default robust estimator method.
550      *
551      * @param inputPoints   list of input points to be used to estimate a
552      *                      projective 2D transformation.
553      * @param outputPoints  list of output points to be used to estimate a
554      *                      projective 2D transformation.
555      * @param qualityScores quality scores corresponding to each pair of matched
556      *                      points.
557      * @return an instance of projective 2D transformation estimator.
558      * @throws IllegalArgumentException if provided lists of points don't have
559      *                                  the same size or their size is smaller than MINIMUM_SIZE.
560      */
561     public static ProjectiveTransformation2DRobustEstimator createFromPoints(
562             final List<Point2D> inputPoints, final List<Point2D> outputPoints, final double[] qualityScores) {
563         return PointCorrespondenceProjectiveTransformation2DRobustEstimator.create(inputPoints, outputPoints,
564                 qualityScores);
565     }
566 
567     /**
568      * Creates a projective 2D transformation estimator based on 2D point
569      * correspondences and using default robust estimator method.
570      *
571      * @param listener      listener to be notified of events such as when estimation
572      *                      starts, ends or its progress significantly changes.
573      * @param inputPoints   list of input points to be used to estimate a
574      *                      projective 2D transformation.
575      * @param outputPoints  list of output points to be used to estimate a
576      *                      projective 2D transformation.
577      * @param qualityScores quality scores corresponding to each pair of matched
578      *                      points.
579      * @return an instance of projective 2D transformation estimator.
580      * @throws IllegalArgumentException if provided lists of points don't have
581      *                                  the same size or their size is smaller than MINIMUM_SIZE.
582      */
583     public static ProjectiveTransformation2DRobustEstimator createFromPoints(
584             final ProjectiveTransformation2DRobustEstimatorListener listener,
585             final List<Point2D> inputPoints, final List<Point2D> outputPoints, final double[] qualityScores) {
586         return PointCorrespondenceProjectiveTransformation2DRobustEstimator.create(listener, inputPoints, outputPoints,
587                 qualityScores);
588     }
589 
590     /**
591      * Creates a projective 2D transformation estimator based on 2D line
592      * correspondences and using provided robust estimator method.
593      *
594      * @param inputLines  list of input lines to be used to estimate a
595      *                    projective 2D transformation.
596      * @param outputLines list of output lines to be used to estimate a
597      *                    projective 2D transformation.
598      * @param method      method of a robust estimator algorithm to estimate
599      *                    best projective 2D transformation.
600      * @return an instance of projective 2D transformation estimator.
601      * @throws IllegalArgumentException if provided lists of lines don't have
602      *                                  the same size or their size is smaller than MINIMUM_SIZE.
603      */
604     public static ProjectiveTransformation2DRobustEstimator createFromLines(
605             final List<Line2D> inputLines, final List<Line2D> outputLines, final RobustEstimatorMethod method) {
606         return LineCorrespondenceProjectiveTransformation2DRobustEstimator.create(inputLines, outputLines, method);
607     }
608 
609     /**
610      * Creates a projective 2D transformation estimator based on 2D line
611      * correspondences and using provided robust estimator method.
612      *
613      * @param listener    listener to be notified of events such as when estimation
614      *                    starts, ends or its progress significantly changes.
615      * @param inputLines  list of input lines to be used to estimate a projective
616      *                    2D transformation.
617      * @param outputLines list of output lines to be used to estimate a
618      *                    projective 2D transformation.
619      * @param method      method of a robust estimator algorithm to estimate best
620      *                    projective 2D transformation.
621      * @return an instance of projective 2D transformation estimator.
622      * @throws IllegalArgumentException if provided lists of lines don't have
623      *                                  the same size or their size is smaller than MINIMUM_SIZE.
624      */
625     public static ProjectiveTransformation2DRobustEstimator createFromLines(
626             final ProjectiveTransformation2DRobustEstimatorListener listener, final List<Line2D> inputLines,
627             final List<Line2D> outputLines, final RobustEstimatorMethod method) {
628         return LineCorrespondenceProjectiveTransformation2DRobustEstimator.create(listener, inputLines, outputLines,
629                 method);
630     }
631 
632     /**
633      * Creates a projective 2D transformation estimator based on 2D line
634      * correspondences and using provided robust estimator method.
635      *
636      * @param inputLines    list of input lines to be used to estimate a
637      *                      projective 2D transformation.
638      * @param outputLines   list of output lines to be used to estimate a
639      *                      projective 2D transformation.
640      * @param qualityScores quality scores corresponding to each pair of matched
641      *                      lines.
642      * @param method        method of a robust estimator algorithm to estimate best
643      *                      projective 2D transformation.
644      * @return an instance of projective 2D transformation estimator.
645      * @throws IllegalArgumentException if provided lists of lines don't have
646      *                                  the same size or their size is smaller than MINIMUM_SIZE.
647      */
648     public static ProjectiveTransformation2DRobustEstimator createFromLines(
649             final List<Line2D> inputLines, final List<Line2D> outputLines, final double[] qualityScores,
650             final RobustEstimatorMethod method) {
651         return LineCorrespondenceProjectiveTransformation2DRobustEstimator.create(inputLines, outputLines,
652                 qualityScores, method);
653     }
654 
655     /**
656      * Creates a projective 2D transformation estimator based on 2D line
657      * correspondences and using provided robust estimator method.
658      *
659      * @param listener      listener to be notified of events such as when estimation
660      *                      starts, ends or its progress significantly changes.
661      * @param inputLines    list of input lines to be used to estimate a projective
662      *                      2D transformation.
663      * @param outputLines   list of output lines to be used to estimate a
664      *                      projective 2D transformation.
665      * @param qualityScores quality scores corresponding to each pair of matched
666      *                      lines.
667      * @param method        method of a robust estimator algorithm to estimate best
668      *                      projective 2D transformation.
669      * @return an instance of projective 2D transformation estimator.
670      * @throws IllegalArgumentException if provided lists of lines don't have
671      *                                  the same size or their size is smaller than MINIMUM_SIZE.
672      */
673     public static ProjectiveTransformation2DRobustEstimator createFromLines(
674             final ProjectiveTransformation2DRobustEstimatorListener listener, final List<Line2D> inputLines,
675             final List<Line2D> outputLines, final double[] qualityScores, final RobustEstimatorMethod method) {
676         return LineCorrespondenceProjectiveTransformation2DRobustEstimator.create(listener, inputLines, outputLines,
677                 qualityScores, method);
678     }
679 
680     /**
681      * Creates a projective 2D transformation estimator based on 2D line
682      * correspondences and using default robust estimator method.
683      *
684      * @param inputLines  list of input lines to be used to estimate a
685      *                    projective 2D transformation.
686      * @param outputLines list of output lines to be used to estimate a
687      *                    projective 2D transformation.
688      * @return an instance of projective 2D transformation estimator.
689      * @throws IllegalArgumentException if provided lists of lines don't have
690      *                                  the same size or their size is smaller than MINIMUM_SIZE.
691      */
692     public static ProjectiveTransformation2DRobustEstimator createFromLines(
693             final List<Line2D> inputLines, final List<Line2D> outputLines) {
694         return LineCorrespondenceProjectiveTransformation2DRobustEstimator.create(inputLines, outputLines);
695     }
696 
697     /**
698      * Creates a projective 2D transformation estimator based on 2D line
699      * correspondences and using default robust estimator method.
700      *
701      * @param listener    listener to be notified of events such as when estimation
702      *                    starts, ends or its progress significantly changes.
703      * @param inputLines  list of input lines to be used to estimate a projective
704      *                    2D transformation.
705      * @param outputLines list of output lines to be used to estimate a
706      *                    projective 2D transformation.
707      * @return an instance of projective 2D transformation estimator.
708      * @throws IllegalArgumentException if provided lists of lines don't have
709      *                                  the same size or their size is smaller than MINIMUM_SIZE.
710      */
711     public static ProjectiveTransformation2DRobustEstimator createFromLines(
712             final ProjectiveTransformation2DRobustEstimatorListener listener, final List<Line2D> inputLines,
713             final List<Line2D> outputLines) {
714         return LineCorrespondenceProjectiveTransformation2DRobustEstimator.create(listener, inputLines, outputLines);
715     }
716 
717     /**
718      * Creates a projective 2D transformation estimator based on 2D line
719      * correspondences and using default robust estimator method.
720      *
721      * @param inputLines    list of input lines to be used to estimate a projective
722      *                      2D transformation.
723      * @param outputLines   list of output lines to be used to estimate a
724      *                      projective 2D transformation.
725      * @param qualityScores quality scores corresponding to each pair of matched
726      *                      points.
727      * @return an instance of projective 2D transformation estimator.
728      * @throws IllegalArgumentException if provided lists of lines don't have
729      *                                  the same size or their size is smaller than MINIMUM_SIZE.
730      */
731     public static ProjectiveTransformation2DRobustEstimator createFromLines(
732             final List<Line2D> inputLines, final List<Line2D> outputLines, final double[] qualityScores) {
733         return LineCorrespondenceProjectiveTransformation2DRobustEstimator.create(inputLines, outputLines,
734                 qualityScores);
735     }
736 
737     /**
738      * Creates a projective 2D transformation estimator based on 2D line
739      * correspondences and using default robust estimator method.
740      *
741      * @param listener      listener to be notified of events such as when estimation
742      *                      starts, ends or its progress significantly changes.
743      * @param inputLines    list of input lines to be used to estimate a projective
744      *                      2D transformation.
745      * @param outputLines   list of output lines to be used to estimate a
746      *                      projective 2D transformation.
747      * @param qualityScores quality scores corresponding to each pair of matched
748      *                      lines.
749      * @return an instance of projective 2D transformation estimator.
750      * @throws IllegalArgumentException if provided lists of lines don't have
751      *                                  the same size or their size is smaller than MINIMUM_SIZE.
752      */
753     public static ProjectiveTransformation2DRobustEstimator createFromLines(
754             final ProjectiveTransformation2DRobustEstimatorListener listener, final List<Line2D> inputLines,
755             final List<Line2D> outputLines, final double[] qualityScores) {
756         return LineCorrespondenceProjectiveTransformation2DRobustEstimator.create(listener, inputLines, outputLines,
757                 qualityScores);
758     }
759 
760     /**
761      * Gets standard deviation used for Levenberg-Marquardt fitting during
762      * refinement.
763      * Returned value gives an indication of how much variance each residual
764      * has.
765      * Typically, this value is related to the threshold used on each robust
766      * estimation, since residuals of found inliers are within the range of
767      * such threshold.
768      *
769      * @return standard deviation used for refinement.
770      */
771     protected abstract double getRefinementStandardDeviation();
772 }