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.*;
20  import com.irurueta.numerical.robust.InliersData;
21  import com.irurueta.numerical.robust.RobustEstimatorException;
22  import com.irurueta.numerical.robust.RobustEstimatorMethod;
23  
24  import java.util.List;
25  
26  /**
27   * This is an abstract class for algorithms to robustly find the best
28   * PinholeCamera for provided collections of matched 3D points and their
29   * corresponding projected 2D points, or collections of matched 3D planes and
30   * their corresponding projected 2D lines (depending on point
31   * correspondence or plane/line correspondence is being used).
32   * Implementations of this class should be able to detect and discard outliers
33   * in order to find the best solution.
34   */
35  public abstract class PinholeCameraRobustEstimator {
36      /**
37       * Indicates that result is refined by default using Levenberg-Marquardt
38       * fitting algorithm over found inliers.
39       */
40      public static final boolean DEFAULT_REFINE_RESULT = true;
41  
42      /**
43       * Indicates that covariance is not kept by default after refining result.
44       */
45      public static final boolean DEFAULT_KEEP_COVARIANCE = false;
46  
47      /**
48       * Indicates whether fast refinement is used by default.
49       */
50      public static final boolean DEFAULT_USE_FAST_REFINEMENT = false;
51  
52      /**
53       * Default amount of progress variation before notifying a change in
54       * estimation progress. By default, this is set to 5%.
55       */
56      public static final float DEFAULT_PROGRESS_DELTA = 0.05f;
57  
58      /**
59       * Minimum allowed value for progress delta.
60       */
61      public static final float MIN_PROGRESS_DELTA = 0.0f;
62  
63      /**
64       * Maximum allowed value for progress delta.
65       */
66      public static final float MAX_PROGRESS_DELTA = 1.0f;
67  
68      /**
69       * Constant defining default confidence of the estimated result, which is
70       * 99%. This means that with a probability of 99% estimation will be
71       * accurate because chosen sub-samples will be inliers.
72       */
73      public static final double DEFAULT_CONFIDENCE = 0.99;
74  
75      /**
76       * Default maximum allowed number of iterations.
77       */
78      public static final int DEFAULT_MAX_ITERATIONS = 5000;
79  
80      /**
81       * Minimum allowed confidence value.
82       */
83      public static final double MIN_CONFIDENCE = 0.0;
84  
85      /**
86       * Maximum allowed confidence value.
87       */
88      public static final double MAX_CONFIDENCE = 1.0;
89  
90      /**
91       * Minimum allowed number of iterations.
92       */
93      public static final int MIN_ITERATIONS = 1;
94  
95      /**
96       * Default value indicating whether skewness value is suggested or not.
97       * By default, this is disabled.
98       */
99      public static final boolean DEFAULT_SUGGEST_SKEWNESS_VALUE_ENABLED = false;
100 
101     /**
102      * Default value of skewness to be suggested when suggestion is enabled.
103      * By default suggested skewness is zero.
104      */
105     public static final double DEFAULT_SUGGESTED_SKEWNESS_VALUE = 0.0;
106 
107     /**
108      * Default value indicating whether horizontal focal length value is
109      * suggested or not. By default, this is disabled.
110      */
111     public static final boolean DEFAULT_SUGGEST_HORIZONTAL_FOCAL_LENGTH_ENABLED = false;
112 
113     /**
114      * Default value indicating whether vertical focal length value is suggested
115      * or not. By default, this is disabled.
116      */
117     public static final boolean DEFAULT_SUGGEST_VERTICAL_FOCAL_LENGTH_ENABLED = false;
118 
119     /**
120      * Default value indicating whether aspect ratio is suggested or not. By
121      * default, this is disabled.
122      */
123     public static final boolean DEFAULT_SUGGEST_ASPECT_RATIO_ENABLED = false;
124 
125     /**
126      * Default value of aspect ratio to be suggested when suggestion is enabled.
127      * By default, suggested aspect ratio is 1.0, although also -1.0 is a typical
128      * value when vertical coordinates increase downwards.
129      */
130     public static final double DEFAULT_SUGGESTED_ASPECT_RATIO_VALUE = 1.0;
131 
132     /**
133      * Default value indicating whether principal point is suggested or not. By
134      * default, this is disabled.
135      */
136     public static final boolean DEFAULT_SUGGEST_PRINCIPAL_POINT_ENABLED = false;
137 
138     /**
139      * Default value indicating whether rotation is suggested or not. By default,
140      * this is disabled.
141      */
142     public static final boolean DEFAULT_SUGGEST_ROTATION_ENABLED = false;
143 
144     /**
145      * Default value indicating whether center is suggested or not. By default
146      * this is disabled.
147      */
148     public static final boolean DEFAULT_SUGGEST_CENTER_ENABLED = false;
149 
150     /**
151      * Listener to be notified of events such as when estimation starts, ends
152      * or its progress significantly changes.
153      */
154     protected PinholeCameraRobustEstimatorListener listener;
155 
156     /**
157      * Indicates if this estimator is locked because an estimation is being
158      * computed.
159      */
160     protected volatile boolean locked;
161 
162     /**
163      * Amount of progress variation before notifying a progress change during
164      * estimation.
165      */
166     protected float progressDelta;
167 
168     /**
169      * Amount of confidence expressed as a value between 0.0 and 1.0 (which is
170      * equivalent to 100%). The amount of confidence indicates the probability
171      * that the estimated result is correct. Usually this value will be close
172      * to 1.0, but not exactly 1.0.
173      */
174     protected double confidence;
175 
176     /**
177      * Maximum allowed number of iterations. When the maximum number of
178      * iterations is exceeded, result will not be available, however an
179      * approximate result will be available for retrieval.
180      */
181     protected int maxIterations;
182 
183     /**
184      * Data related to inliers found after estimation.
185      */
186     protected InliersData inliersData;
187 
188     /**
189      * Indicates whether result must be refined using Levenberg-Marquardt
190      * fitting algorithm over found inliers.
191      * If true, inliers will be computed and kept in any implementation
192      * regardless of the settings.
193      */
194     protected boolean refineResult;
195 
196     /**
197      * Indicates whether covariance must be kept after refining result.
198      * This setting is only taken into account if result is refined.
199      */
200     protected boolean keepCovariance;
201 
202     /**
203      * Indicates whether fast refinement must be used or not.
204      * When true Levenberg/Marquardt refinement will be used, when false
205      * an initial Powell optimization is done and then Levenberg/Marquard is
206      * used for covariance estimation if needed.
207      */
208     protected boolean useFastRefinement;
209 
210     /**
211      * Estimated covariance of estimated fundamental matrix.
212      * This is only available when result has been refined and covariance is
213      * kept.
214      */
215     protected Matrix covariance;
216 
217     /**
218      * Indicates whether skewness value is suggested or not. When enabled, the
219      * estimator will attempt to enforce suggested value in an iterative manner
220      * starting from an initially estimated camera.
221      * Even when suggestion is enabled, the iterative algorithm might not reach
222      * suggested value if the initial value largely differs from the suggested
223      * value.
224      */
225     protected boolean suggestSkewnessValueEnabled = DEFAULT_SUGGEST_SKEWNESS_VALUE_ENABLED;
226 
227     /**
228      * Suggested skewness value to be reached when suggestion is enabled.
229      * Suggested value should be close to the initially estimated value
230      * otherwise the iterative refinement might not converge to provided
231      * value.
232      */
233     protected double suggestedSkewnessValue = DEFAULT_SUGGESTED_SKEWNESS_VALUE;
234 
235     /**
236      * Indicates whether horizontal focal length is suggested or not. When
237      * enabled, the estimator will attempt to enforce suggested value in an
238      * iterative manner starting from an initially estimated camera.
239      * Even when suggestion is enabled, the iterative algorithm might not reach
240      * suggested value if the initial value largely differs from the suggested
241      * value.
242      */
243     protected boolean suggestHorizontalFocalLengthEnabled = DEFAULT_SUGGEST_HORIZONTAL_FOCAL_LENGTH_ENABLED;
244 
245     /**
246      * Suggested horizontal focal length value to be reached when suggestion is
247      * enabled.
248      * Suggested value should be close to the initially estimated value
249      * otherwise the iterative refinement might not converge to provided value.
250      */
251     protected double suggestedHorizontalFocalLengthValue;
252 
253     /**
254      * Indicates whether vertical focal length is suggested or not. When
255      * enabled, the estimator will attempt to enforce suggested value in an
256      * iterative manner starting from an initially estimated camera.
257      * Even when suggestion is enabled, the iterative algorithm might not reach
258      * suggested value if the initial value largely differs from the suggested
259      * value.
260      */
261     protected boolean suggestVerticalFocalLengthEnabled = DEFAULT_SUGGEST_VERTICAL_FOCAL_LENGTH_ENABLED;
262 
263     /**
264      * Suggested vertical focal length value to be reached when suggestion is
265      * enabled.
266      * Suggested value should be close to the initially estimated value
267      * otherwise the iterative refinement might not converge to provided value.
268      */
269     protected double suggestedVerticalFocalLengthValue;
270 
271     /**
272      * Indicates whether aspect ratio is suggested or not. When enabled, the
273      * estimator will attempt to enforce suggested value in an iterative manner
274      * starting from an initially estimated camera.
275      * Even when suggestion is enabled, the iterative algorithm might not reach
276      * suggested value if the initial value largely differs from the suggested
277      * value.
278      */
279     protected boolean suggestAspectRatioEnabled = DEFAULT_SUGGEST_ASPECT_RATIO_ENABLED;
280 
281     /**
282      * Suggested aspect ratio value to be reached when suggestion is enabled.
283      * Suggested value should be close to the initially estimated value
284      * otherwise the iterative refinement might not converge to provided value.
285      */
286     protected double suggestedAspectRatioValue = DEFAULT_SUGGESTED_ASPECT_RATIO_VALUE;
287 
288     /**
289      * Indicates whether principal point is suggested or not. When enabled, the
290      * estimator will attempt to enforce suggested value in an iterative manner
291      * starting from an initially estimated camera.
292      * Even when suggestion is enabled, the iterative algorithm might not reach
293      * suggested value if the initial value largely differs from the suggested
294      * value.
295      */
296     protected boolean suggestPrincipalPointEnabled = DEFAULT_SUGGEST_PRINCIPAL_POINT_ENABLED;
297 
298     /**
299      * Suggested principal point value to be reached when suggestion is enabled.
300      * Suggested value should be close to the initially estimated value
301      * otherwise the iterative refinement might not converge to provided value.
302      */
303     protected InhomogeneousPoint2D suggestedPrincipalPointValue;
304 
305     /**
306      * Indicates whether camera rotation is suggested or not. When enabled, the
307      * estimator will attempt to enforce suggested value in an iterative manner
308      * starting from an initially estimated camera.
309      * Even when suggestion is enabled, the iterative algorithm might not reach
310      * suggested value if the initial value largely differs from the suggested
311      * value.
312      */
313     protected boolean suggestRotationEnabled = DEFAULT_SUGGEST_ROTATION_ENABLED;
314 
315     /**
316      * Suggested rotation to be reached when suggestion is enabled.
317      * Suggested value should be close to the initially estimated value
318      * otherwise the iterative refinement might not converge to provided value.
319      */
320     protected Quaternion suggestedRotationValue;
321 
322     /**
323      * Indicates whether camera center is suggested or not. When enabled, the
324      * estimator will attempt to enforce suggested value in an iterative manner
325      * starting from an initially estimated camera.
326      * Even when suggestion is enabled, the iterative algorithm might not reach
327      * suggested value if the initial value largely differs from the suggested
328      * value.
329      */
330     protected boolean suggestCenterEnabled;
331 
332     /**
333      * Suggested center to be reached when suggestion is enabled.
334      * Suggested value should be close to the initially estimated value
335      * otherwise the iterative refinement might not converge to provided value.
336      */
337     protected InhomogeneousPoint3D suggestedCenterValue;
338 
339     /**
340      * Constructor.
341      */
342     protected PinholeCameraRobustEstimator() {
343         progressDelta = DEFAULT_PROGRESS_DELTA;
344         confidence = DEFAULT_CONFIDENCE;
345         maxIterations = DEFAULT_MAX_ITERATIONS;
346         refineResult = DEFAULT_REFINE_RESULT;
347         keepCovariance = DEFAULT_KEEP_COVARIANCE;
348     }
349 
350     /**
351      * Constructor.
352      *
353      * @param listener listener to be notified of events such as when estimation
354      *                 starts, ends or its progress significantly changes.
355      */
356     protected PinholeCameraRobustEstimator(final PinholeCameraRobustEstimatorListener listener) {
357         this.listener = listener;
358         progressDelta = DEFAULT_PROGRESS_DELTA;
359         confidence = DEFAULT_CONFIDENCE;
360         maxIterations = DEFAULT_MAX_ITERATIONS;
361         refineResult = DEFAULT_REFINE_RESULT;
362         keepCovariance = DEFAULT_KEEP_COVARIANCE;
363     }
364 
365     /**
366      * Returns reference to listener to be notified of events such as when
367      * estimation starts, ends or its progress significantly changes.
368      *
369      * @return listener to be notified of events.
370      */
371     public PinholeCameraRobustEstimatorListener getListener() {
372         return listener;
373     }
374 
375     /**
376      * Sets listener to be notified of events such as when estimation starts,
377      * ends or its progress significantly changes.
378      *
379      * @param listener listener to be notified of events.
380      * @throws LockedException if robust estimator is locked.
381      */
382     public void setListener(final PinholeCameraRobustEstimatorListener listener) throws LockedException {
383         if (isLocked()) {
384             throw new LockedException();
385         }
386         this.listener = listener;
387     }
388 
389     /**
390      * Indicates whether listener has been provided and is available for
391      * retrieval.
392      *
393      * @return true if available, false otherwise.
394      */
395     public boolean isListenerAvailable() {
396         return listener != null;
397     }
398 
399     /**
400      * Indicates whether skewness value is suggested or not. When enabled, the
401      * estimator will attempt to enforce suggested value in an iterative manner
402      * starting from an initially estimated camera.
403      * Even when suggestion is enabled, the iterative algorithm might not reach
404      * suggested value if the initial value largely differs from the suggested
405      * value.
406      *
407      * @return true if skewness value is suggested, false otherwise.
408      */
409     public boolean isSuggestSkewnessValueEnabled() {
410         return suggestSkewnessValueEnabled;
411     }
412 
413     /**
414      * Specifies whether skewness value is suggested or not. When enabled, the
415      * estimator will attempt to enforce suggested value in an iterative manner
416      * starting from an initially estimated camera.
417      * Even when suggestion is enabled, the iterative algorithm might not reach
418      * suggested value if the initial value largely differs from the suggested
419      * value.
420      *
421      * @param suggestSkewnessValueEnabled true if skewness value is suggested,
422      *                                    false otherwise.
423      * @throws LockedException if estimator is locked.
424      */
425     public void setSuggestSkewnessValueEnabled(final boolean suggestSkewnessValueEnabled) throws LockedException {
426         if (isLocked()) {
427             throw new LockedException();
428         }
429         this.suggestSkewnessValueEnabled = suggestSkewnessValueEnabled;
430     }
431 
432     /**
433      * Gets suggested skewness value to be reached when suggestion is enabled.
434      * Suggested value should be close to the initially estimated value
435      * otherwise the iterative refinement might not converge to provided value.
436      *
437      * @return suggested skewness value.
438      */
439     public double getSuggestedSkewnessValue() {
440         return suggestedSkewnessValue;
441     }
442 
443     /**
444      * Sets suggested skewness value to be reached when suggestion is enabled.
445      * Suggested value should be close to the initially estimated value
446      * otherwise the iterative refinement might not converge to provided value.
447      *
448      * @param suggestedSkewnessValue suggested skewness value.
449      * @throws LockedException if estimator is locked.
450      */
451     public void setSuggestedSkewnessValue(final double suggestedSkewnessValue) throws LockedException {
452         if (isLocked()) {
453             throw new LockedException();
454         }
455         this.suggestedSkewnessValue = suggestedSkewnessValue;
456     }
457 
458     /**
459      * Indicates whether horizontal focal length is suggested or not. When
460      * enabled, the estimator will attempt to enforce suggested value in an
461      * iterative manner starting from an initially estimated camera.
462      * Even when suggestion is enabled, the iterative algorithm might not reach
463      * suggested value if the initial value largely differs from the suggested
464      * value.
465      *
466      * @return true if horizontal focal length is suggested, false otherwise.
467      */
468     public boolean isSuggestHorizontalFocalLengthEnabled() {
469         return suggestHorizontalFocalLengthEnabled;
470     }
471 
472     /**
473      * Specifies whether horizontal focal length is suggested or not. When
474      * enabled, the estimator will attempt to enforce suggested value in an
475      * iterative manner starting from an initially estimated camera.
476      * Even when suggestion is enabled, the iterative algorithm might not reach
477      * suggested value if the initial value largely differs from the suggested
478      * value.
479      *
480      * @param suggestHorizontalFocalLengthEnabled true if horizontal focal
481      *                                            length is suggested, false otherwise.
482      * @throws LockedException if estimator is locked.
483      */
484     public void setSuggestHorizontalFocalLengthEnabled(final boolean suggestHorizontalFocalLengthEnabled)
485             throws LockedException {
486         if (isLocked()) {
487             throw new LockedException();
488         }
489         this.suggestHorizontalFocalLengthEnabled = suggestHorizontalFocalLengthEnabled;
490     }
491 
492     /**
493      * Gets suggested horizontal focal length value to be reached when
494      * suggestion is enabled.
495      * Suggested value should be close to the initially estimated value
496      * otherwise the iterative refinement might not converge to provided value.
497      *
498      * @return suggested horizontal focal length value.
499      */
500     public double getSuggestedHorizontalFocalLengthValue() {
501         return suggestedHorizontalFocalLengthValue;
502     }
503 
504     /**
505      * Sets suggested horizontal focal length value to be reached when
506      * suggestion is enabled.
507      * Suggested value should be close to the initially estimated value
508      * otherwise the iterative refinement might not converge to provided value.
509      *
510      * @param suggestedHorizontalFocalLengthValue suggested horizontal focal
511      *                                            length value.
512      * @throws LockedException if estimator is locked.
513      */
514     public void setSuggestedHorizontalFocalLengthValue(final double suggestedHorizontalFocalLengthValue)
515             throws LockedException {
516         if (isLocked()) {
517             throw new LockedException();
518         }
519         this.suggestedHorizontalFocalLengthValue = suggestedHorizontalFocalLengthValue;
520     }
521 
522     /**
523      * Indicates whether vertical focal length is suggested or not. When
524      * enabled, the estimator will attempt to enforce suggested value in an
525      * iterative manner starting from an initially estimated camera.
526      * Even when suggestion is enabled, the iterative algorithm might not reach
527      * suggested value if the initial value largely differs from the suggested
528      * value.
529      *
530      * @return true if vertical focal length is suggested, false otherwise.
531      */
532     public boolean isSuggestVerticalFocalLengthEnabled() {
533         return suggestVerticalFocalLengthEnabled;
534     }
535 
536     /**
537      * Specifies whether vertical focal length is suggested or not. When
538      * enabled, the estimator will attempt to enforce suggested value in an
539      * iterative manner starting from an initially estimated camera.
540      * Even when suggestion is enabled, the iterative algorithm might not reach
541      * suggested value if the initial value largely differs from the suggested
542      * value.
543      *
544      * @param suggestVerticalFocalLengthEnabled true if vertical focal length is
545      *                                          suggested, false otherwise.
546      * @throws LockedException if estimator is locked.
547      */
548     public void setSuggestVerticalFocalLengthEnabled(final boolean suggestVerticalFocalLengthEnabled)
549             throws LockedException {
550         if (isLocked()) {
551             throw new LockedException();
552         }
553         this.suggestVerticalFocalLengthEnabled = suggestVerticalFocalLengthEnabled;
554     }
555 
556     /**
557      * Gets suggested vertical focal length value to be reached when suggestion
558      * is enabled.
559      * Suggested value should be close to the initially estimated value
560      * otherwise the iterative refinement might not converge to provided value.
561      *
562      * @return suggested vertical focal length.
563      */
564     public double getSuggestedVerticalFocalLengthValue() {
565         return suggestedVerticalFocalLengthValue;
566     }
567 
568     /**
569      * Sets suggested vertical focal length value to be reached when suggestion
570      * is enabled.
571      * Suggested value should be close to the initially estimated value
572      * otherwise the iterative refinement might not converge to provided value.
573      *
574      * @param suggestedVerticalFocalLengthValue suggested vertical focal length.
575      * @throws LockedException if estimator is locked.
576      */
577     public void setSuggestedVerticalFocalLengthValue(final double suggestedVerticalFocalLengthValue)
578             throws LockedException {
579         if (isLocked()) {
580             throw new LockedException();
581         }
582         this.suggestedVerticalFocalLengthValue = suggestedVerticalFocalLengthValue;
583     }
584 
585     /**
586      * Indicates whether aspect ratio is suggested or not. When enabled, the
587      * estimator will attempt to enforce suggested value in an iterative manner
588      * starting from an initially estimated camera.
589      * Even when suggestion is enabled, the iterative algorithm might not reach
590      * suggested value if the initial value largely differs from the suggested
591      * value.
592      *
593      * @return true if aspect ratio is suggested, false otherwise.
594      */
595     public boolean isSuggestAspectRatioEnabled() {
596         return suggestAspectRatioEnabled;
597     }
598 
599     /**
600      * Specifies whether aspect ratio is suggested or not. When enabled, the
601      * estimator will attempt to enforce suggested value in an iterative manner
602      * starting from an initially estimated camera.
603      * Even when suggestion is enabled, the iterative algorithm might not reach
604      * suggested value if the initial value largely differs from the suggested
605      * value.
606      *
607      * @param suggestAspectRatioEnabled true if aspect ratio is suggested, false
608      *                                  otherwise.
609      * @throws LockedException if estimator is locked.
610      */
611     public void setSuggestAspectRatioEnabled(final boolean suggestAspectRatioEnabled) throws LockedException {
612         if (isLocked()) {
613             throw new LockedException();
614         }
615         this.suggestAspectRatioEnabled = suggestAspectRatioEnabled;
616     }
617 
618     /**
619      * Gets suggested aspect ratio value to be reached when suggestion is
620      * enabled. Suggested value should be close to the initially estimated value
621      * otherwise the iterative refinement might not converge to provided value.
622      *
623      * @return suggested aspect ratio value.
624      */
625     public double getSuggestedAspectRatioValue() {
626         return suggestedAspectRatioValue;
627     }
628 
629     /**
630      * Sets suggested aspect ratio value to be reached when suggestion is
631      * enabled. Suggested value should be close to the initially estimated value
632      * otherwise the iterative refinement might not converge to provided value.
633      *
634      * @param suggestedAspectRatioValue suggested aspect ratio value.
635      * @throws LockedException if estimator is locked.
636      */
637     public void setSuggestedAspectRatioValue(final double suggestedAspectRatioValue) throws LockedException {
638         if (isLocked()) {
639             throw new LockedException();
640         }
641         this.suggestedAspectRatioValue = suggestedAspectRatioValue;
642     }
643 
644     /**
645      * Indicates whether principal point is suggested or not. When enabled, the
646      * estimator will attempt to enforce suggested value in an iterative manner
647      * starting from an initially estimated camera.
648      * Even when suggestion is enabled, the iterative algorithm might not reach
649      * suggested value if the initial value largely differs from the suggested
650      * value.
651      *
652      * @return true if principal point is suggested, false otherwise.
653      */
654     public boolean isSuggestPrincipalPointEnabled() {
655         return suggestPrincipalPointEnabled;
656     }
657 
658     /**
659      * Specifies whether principal point is suggested or not. When enabled, the
660      * estimator will attempt to enforce suggested value in an iterative manner
661      * starting from an initially estimated camera.
662      * Even when suggestion is enabled, the iterative algorithm might not reach
663      * suggested value if the initial value largely differs from the suggested
664      * value.
665      *
666      * @param suggestPrincipalPointEnabled true if principal point is suggested,
667      *                                     false otherwise.
668      * @throws LockedException if estimator is locked.
669      */
670     public void setSuggestPrincipalPointEnabled(final boolean suggestPrincipalPointEnabled) throws LockedException {
671         if (isLocked()) {
672             throw new LockedException();
673         }
674         this.suggestPrincipalPointEnabled = suggestPrincipalPointEnabled;
675         if (suggestPrincipalPointEnabled && suggestedPrincipalPointValue == null) {
676             suggestedPrincipalPointValue = new InhomogeneousPoint2D();
677         }
678     }
679 
680     /**
681      * Gets suggested principal point value to be reached when suggestion is
682      * enabled. Suggested value should be close to the initially estimated value
683      * otherwise the iterative refinement might not converge to provided value.
684      *
685      * @return suggested principal point value to be reached when suggestion is
686      * enabled.
687      */
688     public InhomogeneousPoint2D getSuggestedPrincipalPointValue() {
689         return suggestedPrincipalPointValue;
690     }
691 
692     /**
693      * Sets suggested principal point value to be reached when suggestion is
694      * enabled. Suggested value should be close to the initially estimated value
695      * otherwise the iterative refinement might not converge to provided value.
696      *
697      * @param suggestedPrincipalPointValue suggested principal point value to be
698      *                                     reached when suggestion is enabled.
699      * @throws LockedException if estimator is locked.
700      */
701     public void setSuggestedPrincipalPointValue(final InhomogeneousPoint2D suggestedPrincipalPointValue)
702             throws LockedException {
703         if (isLocked()) {
704             throw new LockedException();
705         }
706         this.suggestedPrincipalPointValue = suggestedPrincipalPointValue;
707     }
708 
709     /**
710      * Indicates whether camera rotation is suggested or not. When enabled, the
711      * estimator will attempt to enforce suggested value in an iterative manner
712      * starting from an initially estimated camera.
713      * Even when suggestion is enabled, the iterative algorithm might not reach
714      * suggested value if the initial value largely differs from the suggested
715      * value.
716      *
717      * @return true if camera rotation is suggested, false otherwise.
718      */
719     public boolean isSuggestRotationEnabled() {
720         return suggestRotationEnabled;
721     }
722 
723     /**
724      * Specifies whether camera rotation is suggested or not. When enabled, the
725      * estimator will attempt to enforce suggested value in an iterative manner
726      * starting from an initially estimated camera.
727      * Even when suggestion is enabled, the iterative algorithm might not reach
728      * suggested value if the initial value largely differs from the suggested
729      * value.
730      *
731      * @param suggestRotationEnabled true if camera rotation is suggested, false
732      *                               otherwise.
733      * @throws LockedException if estimator is locked.
734      */
735     public void setSuggestRotationEnabled(final boolean suggestRotationEnabled) throws LockedException {
736         if (isLocked()) {
737             throw new LockedException();
738         }
739         this.suggestRotationEnabled = suggestRotationEnabled;
740         if (suggestRotationEnabled && suggestedRotationValue == null) {
741             suggestedRotationValue = new Quaternion();
742         }
743 
744     }
745 
746     /**
747      * Gets suggested rotation to be reached when suggestion is enabled.
748      * Suggested value should be close to the initially estimated value
749      * otherwise the iterative refinement might not converge to provided value.
750      *
751      * @return suggested rotation to be reached when suggestion is enabled.
752      */
753     public Quaternion getSuggestedRotationValue() {
754         return suggestedRotationValue;
755     }
756 
757     /**
758      * Sets suggested rotation to be reached when suggestion is enabled.
759      * Suggested value should be close to the initially estimated value
760      * otherwise the iterative refinement might not converge to provided value.
761      *
762      * @param suggestedRotationValue suggested rotation to be reached when
763      *                               suggestion is enabled.
764      * @throws LockedException if estimator is locked.
765      */
766     public void setSuggestedRotationValue(final Quaternion suggestedRotationValue) throws LockedException {
767         if (isLocked()) {
768             throw new LockedException();
769         }
770         this.suggestedRotationValue = suggestedRotationValue;
771     }
772 
773     /**
774      * Indicates whether camera center is suggested or not. When enabled, the
775      * estimator will attempt to enforce suggested value in an iterative manner
776      * starting from an initially estimated camera.
777      * Even when suggestion is enabled, the iterative algorithm might not reach
778      * suggested value if the initial value largely differs from the suggested
779      * value.
780      *
781      * @return true if camera center is suggested, false otherwise.
782      */
783     public boolean isSuggestCenterEnabled() {
784         return suggestCenterEnabled;
785     }
786 
787     /**
788      * Specifies whether camera center is suggested or not. When enabled, the
789      * estimator will attempt to enforce suggested value in an iterative manner
790      * starting from an initially estimated camera.
791      * Even when suggestion is enabled, the iterative algorithm might not reach
792      * suggested value if the initial value largely differs from the suggested
793      * value.
794      *
795      * @param suggestCenterEnabled true if camera is suggested, false otherwise.
796      * @throws LockedException if estimator is locked.
797      */
798     public void setSuggestCenterEnabled(final boolean suggestCenterEnabled) throws LockedException {
799         if (isLocked()) {
800             throw new LockedException();
801         }
802         this.suggestCenterEnabled = suggestCenterEnabled;
803         if (suggestCenterEnabled && suggestedCenterValue == null) {
804             suggestedCenterValue = new InhomogeneousPoint3D();
805         }
806     }
807 
808     /**
809      * Gets suggested center to be reached when suggestion is enabled.
810      * Suggested value should be close to the initially estimated value
811      * otherwise the iterative refinement might not converge to provided value.
812      *
813      * @return suggested center to be reached when suggestion is enabled.
814      */
815     public InhomogeneousPoint3D getSuggestedCenterValue() {
816         return suggestedCenterValue;
817     }
818 
819     /**
820      * Sets suggested center to be reached when suggestion is enabled.
821      * Suggested value should be close to the initially estimated value
822      * otherwise the iterative refinement might not converge to provided value.
823      *
824      * @param suggestedCenterValue suggested center to be reached when
825      *                             suggestion is enabled.
826      * @throws LockedException if estimator is locked.
827      */
828     public void setSuggestedCenterValue(final InhomogeneousPoint3D suggestedCenterValue) throws LockedException {
829         if (isLocked()) {
830             throw new LockedException();
831         }
832         this.suggestedCenterValue = suggestedCenterValue;
833     }
834 
835     /**
836      * Indicates if this instance is locked because estimation is being
837      * computed.
838      *
839      * @return true if locked, false otherwise.
840      */
841     public boolean isLocked() {
842         return locked;
843     }
844 
845     /**
846      * Returns amount of progress variation before notifying a progress change
847      * during estimation.
848      *
849      * @return amount of progress variation before notifying a progress change
850      * during estimation.
851      */
852     public float getProgressDelta() {
853         return progressDelta;
854     }
855 
856     /**
857      * Sets amount of progress variation before notifying a progress change
858      * during estimation.
859      *
860      * @param progressDelta amount of progress variation before notifying a
861      *                      progress change during estimation.
862      * @throws IllegalArgumentException if progress delta is less than zero or
863      *                                  greater than 1.
864      * @throws LockedException          if this estimator is locked because an estimation
865      *                                  is being computed.
866      */
867     public void setProgressDelta(final float progressDelta) throws LockedException {
868         if (isLocked()) {
869             throw new LockedException();
870         }
871         if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
872             throw new IllegalArgumentException();
873         }
874         this.progressDelta = progressDelta;
875     }
876 
877     /**
878      * Returns amount of confidence expressed as a value between 0.0 and 1.0
879      * (which is equivalent to 100%). The amount of confidence indicates the
880      * probability that the estimated result is correct. Usually this value will
881      * be close to 1.0, but not exactly 1.0.
882      *
883      * @return amount of confidence as a value between 0.0 and 1.0.
884      */
885     public double getConfidence() {
886         return confidence;
887     }
888 
889     /**
890      * Sets amount of confidence expressed as a value between 0.0 and 1.0 (which
891      * is equivalent to 100%). The amount of confidence indicates the
892      * probability that the estimated result is correct. Usually this value will
893      * be close to 1.0, but not exactly 1.0.
894      *
895      * @param confidence confidence to be set as a value between 0.0 and 1.0.
896      * @throws IllegalArgumentException if provided value is not between 0.0 and
897      *                                  1.0.
898      * @throws LockedException          if this estimator is locked because an estimator
899      *                                  is being computed.
900      */
901     public void setConfidence(final double confidence) throws LockedException {
902         if (isLocked()) {
903             throw new LockedException();
904         }
905         if (confidence < MIN_CONFIDENCE || confidence > MAX_CONFIDENCE) {
906             throw new IllegalArgumentException();
907         }
908         this.confidence = confidence;
909     }
910 
911     /**
912      * Returns maximum allowed number of iterations. If maximum allowed number
913      * of iterations is achieved without converging to a result when calling
914      * estimate(), a RobustEstimatorException will be raised.
915      *
916      * @return maximum allowed number of iterations.
917      */
918     public int getMaxIterations() {
919         return maxIterations;
920     }
921 
922     /**
923      * Sets maximum allowed number of iterations. When the maximum number of
924      * iterations is exceeded, result will not be available, however an
925      * approximate result will be available for retrieval.
926      *
927      * @param maxIterations maximum allowed number of iterations to be set.
928      * @throws IllegalArgumentException if provided value is less than 1.
929      * @throws LockedException          if this estimator is locked because an estimation
930      *                                  is being computed.
931      */
932     public void setMaxIterations(final int maxIterations) throws LockedException {
933         if (isLocked()) {
934             throw new LockedException();
935         }
936         if (maxIterations < MIN_ITERATIONS) {
937             throw new IllegalArgumentException();
938         }
939         this.maxIterations = maxIterations;
940     }
941 
942     /**
943      * Gets data related to inliers found after estimation.
944      *
945      * @return data related to inliers found after estimation.
946      */
947     public InliersData getInliersData() {
948         return inliersData;
949     }
950 
951     /**
952      * Indicates whether result must be refined using Levenberg-Marquardt
953      * fitting algorithm over found inliers.
954      * If true, inliers will be computed and kept in any implementation
955      * regardless of the settings.
956      *
957      * @return true to refine result, false to simply use result found by
958      * robust estimator without further refining.
959      */
960     public boolean isResultRefined() {
961         return refineResult;
962     }
963 
964     /**
965      * Specifies whether result must be refined using Levenberg-Marquardt
966      * fitting algorithm over found inliers.
967      *
968      * @param refineResult true to refine result, false to simply use result
969      *                     found by robust estimator without further refining.
970      * @throws LockedException if estimator is locked.
971      */
972     public void setResultRefined(final boolean refineResult) throws LockedException {
973         if (isLocked()) {
974             throw new LockedException();
975         }
976         this.refineResult = refineResult;
977     }
978 
979     /**
980      * Indicates whether covariance must be kept after refining result.
981      * This setting is only taken into account if result is refined.
982      *
983      * @return true if covariance must be kept after refining result, false
984      * otherwise.
985      */
986     public boolean isCovarianceKept() {
987         return keepCovariance;
988     }
989 
990     /**
991      * Specifies whether covariance must be kept after refining result.
992      * This setting is only taken into account if result is refined.
993      *
994      * @param keepCovariance true if covariance must be kept after refining
995      *                       result, false otherwise.
996      * @throws LockedException if estimator is locked.
997      */
998     public void setCovarianceKept(final boolean keepCovariance) throws LockedException {
999         if (isLocked()) {
1000             throw new LockedException();
1001         }
1002         this.keepCovariance = keepCovariance;
1003     }
1004 
1005     /**
1006      * Indicates whether fast refinement must be used or not.
1007      * When true Levenberg/Marquardt refinement will be used, when false
1008      * an initial Powell optimization is done and then Levenberg/Marquard is
1009      * used for covariance estimation if needed.
1010      * Fast refinement requires less computing time, but it is more likely to
1011      * fail than slow one.
1012      *
1013      * @return true to use fast refinement, false to use a slow but more
1014      * accurate and stable refinement.
1015      */
1016     public boolean isFastRefinementUsed() {
1017         return useFastRefinement;
1018     }
1019 
1020     /**
1021      * Specifies whether fast refinement must be used or not.
1022      * When true Levenberg/Marquardt refinement will be used, when false
1023      * an initial Powell optimization is done and then Levenberg/Marquard is
1024      * used for covariance estimation if needed.
1025      * Fast refinement requires less computing time, but it is more likely to
1026      * fail than slow one.
1027      *
1028      * @param useFastRefinement true to use fast refinement, false to use a slow
1029      *                          but more accurate and stable refinement.
1030      * @throws LockedException if estimator is locked.
1031      */
1032     public void setFastRefinementUsed(final boolean useFastRefinement) throws LockedException {
1033         if (isLocked()) {
1034             throw new LockedException();
1035         }
1036         this.useFastRefinement = useFastRefinement;
1037     }
1038 
1039     /**
1040      * Gets estimated covariance of estimated pinhole camera if available.
1041      * This is only available when result has been refined and covariance is
1042      * kept.
1043      *
1044      * @return estimated covariance or null.
1045      */
1046     public Matrix getCovariance() {
1047         return covariance;
1048     }
1049 
1050     /**
1051      * Estimates a pinhole camera using a robust estimator and
1052      * the best set of matched 2D/3D point correspondences or 2D line/3D plane
1053      * correspondences found using the robust estimator.
1054      *
1055      * @return a pinhole camera.
1056      * @throws LockedException          if robust estimator is locked because an
1057      *                                  estimation is already in progress.
1058      * @throws NotReadyException        if provided input data is not enough to start
1059      *                                  the estimation.
1060      * @throws RobustEstimatorException if estimation fails for any reason
1061      *                                  (i.e. numerical instability, no solution available, etc).
1062      */
1063     public abstract PinholeCamera estimate() throws LockedException, NotReadyException, RobustEstimatorException;
1064 
1065     /**
1066      * Returns method being used for robust estimation.
1067      *
1068      * @return method being used for robust estimation.
1069      */
1070     public abstract RobustEstimatorMethod getMethod();
1071 
1072     /**
1073      * Gets standard deviation used for Levenberg-Marquardt fitting during
1074      * refinement.
1075      * Returned value gives an indication of how much variance each residual
1076      * has.
1077      * Typically, this value is related to the threshold used on each robust
1078      * estimation, since residuals of found inliers are within the range of
1079      * such threshold.
1080      *
1081      * @return standard deviation used for refinement.
1082      */
1083     protected abstract double getRefinementStandardDeviation();
1084 
1085     /**
1086      * Creates a pinhole camera robust estimator based on 2D/3D point
1087      * correspondences and using provided robust estimator method.
1088      *
1089      * @param points3D list of 3D points used to estimate a pinhole camera.
1090      * @param points2D list of corresponding projected 2D points used to
1091      *                 estimate a pinhole camera.
1092      * @param method   method of a robust estimator algorithm to estimate the best
1093      *                 pinhole camera.
1094      * @return an instance of a pinhole camera robust estimator.
1095      * @throws IllegalArgumentException if provided lists of points don't have
1096      *                                  the same size or their size is smaller than required minimum size
1097      *                                  (6 correspondences).
1098      */
1099     public static PinholeCameraRobustEstimator createFromPoints(
1100             final List<Point3D> points3D, final List<Point2D> points2D, final RobustEstimatorMethod method) {
1101         return PointCorrespondencePinholeCameraRobustEstimator.create(points3D, points2D, method);
1102     }
1103 
1104     /**
1105      * Creates a pinhole camera robust estimator based on 2D/3D point
1106      * correspondences and using provided listener and robust estimator method.
1107      *
1108      * @param listener listener to be notified of events such as when estimation
1109      *                 starts, ends or its progress significantly changes.
1110      * @param points3D list of 3D points used to estimate a pinhole camera.
1111      * @param points2D list of corresponding projected 2D points used to
1112      *                 estimate a pinhole camera.
1113      * @param method   method of a robust estimator algorithm to estimate the best
1114      *                 pinhole camera.
1115      * @return an instance of a pinhole camera robust estimator.
1116      * @throws IllegalArgumentException if provided lists of points don't have
1117      *                                  the same size or their size is smaller than required minimum size
1118      *                                  (6 correspondences).
1119      */
1120     public static PinholeCameraRobustEstimator createFromPoints(
1121             final PinholeCameraRobustEstimatorListener listener,
1122             final List<Point3D> points3D, final List<Point2D> points2D, final RobustEstimatorMethod method) {
1123         return PointCorrespondencePinholeCameraRobustEstimator.create(listener, points3D, points2D, method);
1124     }
1125 
1126     /**
1127      * Creates a pinhole camera robust estimator based on 2D/3D point
1128      * correspondences and using provided quality scores and robust estimator
1129      * method.
1130      *
1131      * @param points3D      list of 3D points used to estimate a pinhole camera.
1132      * @param points2D      list of corresponding projected 2D points used to
1133      *                      estimate a pinhole camera.
1134      * @param qualityScores quality scores corresponding to each pair of matched
1135      *                      points.
1136      * @param method        method of a robust estimator algorithm to estimate the best
1137      *                      pinhole camera.
1138      * @return an instance of a pinhole camera robust estimator.
1139      * @throws IllegalArgumentException if provided lists of points and quality
1140      *                                  scores don't have the same size  or their size is smaller than required
1141      *                                  minimum size (6 correspondences).
1142      */
1143     public static PinholeCameraRobustEstimator createFromPoints(
1144             final List<Point3D> points3D, List<Point2D> points2D, final double[] qualityScores,
1145             final RobustEstimatorMethod method) {
1146         return PointCorrespondencePinholeCameraRobustEstimator.create(points3D, points2D, qualityScores, method);
1147     }
1148 
1149     /**
1150      * Creates a pinhole camera robust estimator based on 2D/3D point
1151      * correspondences and using provided listener, quality scores and robust
1152      * estimator method.
1153      *
1154      * @param listener      listener to be notified of events such as when estimation
1155      *                      starts, ends or its progress significantly changes.
1156      * @param points3D      list of 3D points used to estimate a pinhole camera.
1157      * @param points2D      list of corresponding projected 2D points used to
1158      *                      estimate a pinhole camera.
1159      * @param qualityScores quality scores corresponding to each pair of matched
1160      *                      points.
1161      * @param method        method of a robust estimator algorithm to estimate the best
1162      *                      pinhole camera.
1163      * @return an instance of a pinhole camera robust estimator.
1164      * @throws IllegalArgumentException if provided lists of points and quality
1165      *                                  scores don't have the same size  or their size is smaller than required
1166      *                                  minimum size (6 correspondences).
1167      */
1168     public static PinholeCameraRobustEstimator createFromPoints(
1169             final PinholeCameraRobustEstimatorListener listener, final List<Point3D> points3D,
1170             final List<Point2D> points2D, final double[] qualityScores, final RobustEstimatorMethod method) {
1171         return PointCorrespondencePinholeCameraRobustEstimator.create(listener, points3D, points2D, qualityScores,
1172                 method);
1173     }
1174 
1175     /**
1176      * Creates a pinhole camera robust estimator based on 2D/3D point
1177      * correspondences and using default robust estimator method.
1178      *
1179      * @param points3D list of 3D points used to estimate a pinhole camera.
1180      * @param points2D list of corresponding projected 2D points used to
1181      *                 estimate a pinhole camera.
1182      * @return an instance of a pinhole camera robust estimator.
1183      * @throws IllegalArgumentException if provided lists of points don't have
1184      *                                  the same size or their size is smaller than required minimum size
1185      *                                  (6 correspondences).
1186      */
1187     public static PinholeCameraRobustEstimator createFromPoints(
1188             final List<Point3D> points3D, final List<Point2D> points2D) {
1189         return PointCorrespondencePinholeCameraRobustEstimator.create(points3D, points2D);
1190     }
1191 
1192     /**
1193      * Creates a pinhole camera robust estimator based on 2D/3D point
1194      * correspondences and using provided listener and default robust estimator
1195      * method.
1196      *
1197      * @param listener listener to be notified of events such as when estimation
1198      *                 starts, ends or its progress significantly changes.
1199      * @param points3D list of 3D points used to estimate a pinhole camera.
1200      * @param points2D list of corresponding projected 2D points used to
1201      *                 estimate a pinhole camera.
1202      * @return an instance of a pinhole camera robust estimator.
1203      * @throws IllegalArgumentException if provided lists of points don't have
1204      *                                  the same size or their size is smaller than required minimum size
1205      *                                  (6 correspondences).
1206      */
1207     public static PinholeCameraRobustEstimator createFromPoints(
1208             final PinholeCameraRobustEstimatorListener listener,
1209             final List<Point3D> points3D, final List<Point2D> points2D) {
1210         return PointCorrespondencePinholeCameraRobustEstimator.create(listener, points3D, points2D);
1211     }
1212 
1213     /**
1214      * Creates a pinhole camera robust estimator based on 2D/3D point
1215      * correspondences and using provided quality scores and default robust
1216      * estimator method.
1217      *
1218      * @param points3D      list of 3D points used to estimate a pinhole camera.
1219      * @param points2D      list of corresponding projected 2D points used to
1220      *                      estimate a pinhole camera.
1221      * @param qualityScores quality scores corresponding to each pair of matched
1222      *                      points.
1223      * @return an instance of a pinhole camera robust estimator.
1224      * @throws IllegalArgumentException if provided lists of points and quality
1225      *                                  scores don't have the same size  or their size is smaller than required
1226      *                                  minimum size (6 correspondences).
1227      */
1228     public static PinholeCameraRobustEstimator createFromPoints(
1229             final List<Point3D> points3D, final List<Point2D> points2D, final double[] qualityScores) {
1230         return PointCorrespondencePinholeCameraRobustEstimator.create(points3D, points2D, qualityScores);
1231     }
1232 
1233     /**
1234      * Creates a pinhole camera robust estimator based on 2D/3D point
1235      * correspondences and using provided listener, quality scores and default
1236      * robust estimator method.
1237      *
1238      * @param listener      listener to be notified of events such as when estimation
1239      *                      starts, ends or its progress significantly changes.
1240      * @param points3D      list of 3D points used to estimate a pinhole camera.
1241      * @param points2D      list of corresponding projected 2D points used to
1242      *                      estimate a pinhole camera.
1243      * @param qualityScores quality scores corresponding to each pair of matched
1244      *                      points.
1245      * @return an instance of a pinhole camera robust estimator.
1246      * @throws IllegalArgumentException if provided lists of points and quality
1247      *                                  scores don't have the same size  or their size is smaller than required
1248      *                                  minimum size (6 correspondences).
1249      */
1250     public static PinholeCameraRobustEstimator createFromPoints(
1251             final PinholeCameraRobustEstimatorListener listener, final List<Point3D> points3D,
1252             final List<Point2D> points2D, final double[] qualityScores) {
1253         return PointCorrespondencePinholeCameraRobustEstimator.create(listener, points3D, points2D, qualityScores);
1254     }
1255 
1256     /**
1257      * Creates a pinhole camera robust estimator based on 2D/3D point
1258      * correspondences and using provided robust estimator method.
1259      *
1260      * @param intrinsic intrinsic parameters of camera to be estimated.
1261      * @param points3D  list of 3D points used to estimate a pinhole camera.
1262      * @param points2D  list of corresponding projected 2D points used to
1263      *                  estimate a pinhole camera.
1264      * @param method    method of a robust estimator algorithm to estimate the best
1265      *                  pinhole camera.
1266      * @return an instance of a pinhole camera robust estimator.
1267      * @throws IllegalArgumentException if provided lists of points don't have
1268      *                                  the same size or their size is smaller than required minimum size
1269      *                                  (6 correspondences).
1270      */
1271     public static PinholeCameraRobustEstimator createFromPoints(
1272             final PinholeCameraIntrinsicParameters intrinsic, final List<Point3D> points3D,
1273             final List<Point2D> points2D, final RobustEstimatorMethod method) {
1274         return PointCorrespondencePinholeCameraRobustEstimator.create(intrinsic, points3D, points2D, method);
1275     }
1276 
1277     /**
1278      * Creates a pinhole camera robust estimator based on 2D/3D point
1279      * correspondences and using provided listener and robust estimator method.
1280      *
1281      * @param listener  listener to be notified of events such as when estimation
1282      *                  starts, ends or its progress significantly changes.
1283      * @param intrinsic intrinsic parameters of camera to be estimated.
1284      * @param points3D  list of 3D points used to estimate a pinhole camera.
1285      * @param points2D  list of corresponding projected 2D points used to
1286      *                  estimate a pinhole camera.
1287      * @param method    method of a robust estimator algorithm to estimate the best
1288      *                  pinhole camera.
1289      * @return an instance of a pinhole camera robust estimator.
1290      * @throws IllegalArgumentException if provided lists of points don't have
1291      *                                  the same size or their size is smaller than required minimum size
1292      *                                  (6 correspondences).
1293      */
1294     public static PinholeCameraRobustEstimator createFromPoints(
1295             final PinholeCameraRobustEstimatorListener listener, final PinholeCameraIntrinsicParameters intrinsic,
1296             final List<Point3D> points3D, final List<Point2D> points2D, final RobustEstimatorMethod method) {
1297         return PointCorrespondencePinholeCameraRobustEstimator.create(listener, intrinsic, points3D, points2D, method);
1298     }
1299 
1300     /**
1301      * Creates a pinhole camera robust estimator based on 2D/3D point
1302      * correspondences and using provided quality scores and robust estimator
1303      * method.
1304      *
1305      * @param intrinsic     intrinsic parameters of camera to be estimated.
1306      * @param points3D      list of 3D points used to estimate a pinhole camera.
1307      * @param points2D      list of corresponding projected 2D points used to
1308      *                      estimate a pinhole camera.
1309      * @param qualityScores quality scores corresponding to each pair of matched
1310      *                      points.
1311      * @param method        method of a robust estimator algorithm to estimate the best
1312      *                      pinhole camera.
1313      * @return an instance of a pinhole camera robust estimator.
1314      * @throws IllegalArgumentException if provided lists of points and quality
1315      *                                  scores don't have the same size  or their size is smaller than required
1316      *                                  minimum size (6 correspondences).
1317      */
1318     public static PinholeCameraRobustEstimator createFromPoints(
1319             final PinholeCameraIntrinsicParameters intrinsic, final List<Point3D> points3D,
1320             final List<Point2D> points2D, final double[] qualityScores, final RobustEstimatorMethod method) {
1321         return PointCorrespondencePinholeCameraRobustEstimator.create(intrinsic, points3D, points2D, qualityScores,
1322                 method);
1323     }
1324 
1325     /**
1326      * Creates a pinhole camera robust estimator based on 2D/3D point
1327      * correspondences and using provided listener, quality scores and robust
1328      * estimator method.
1329      *
1330      * @param listener      listener to be notified of events such as when estimation
1331      *                      starts, ends or its progress significantly changes.
1332      * @param intrinsic     intrinsic parameters of camera to be estimated.
1333      * @param points3D      list of 3D points used to estimate a pinhole camera.
1334      * @param points2D      list of corresponding projected 2D points used to
1335      *                      estimate a pinhole camera.
1336      * @param qualityScores quality scores corresponding to each pair of matched
1337      *                      points.
1338      * @param method        method of a robust estimator algorithm to estimate the best
1339      *                      pinhole camera.
1340      * @return an instance of a pinhole camera robust estimator.
1341      * @throws IllegalArgumentException if provided lists of points and quality
1342      *                                  scores don't have the same size  or their size is smaller than required
1343      *                                  minimum size (6 correspondences).
1344      */
1345     public static PinholeCameraRobustEstimator createFromPoints(
1346             final PinholeCameraRobustEstimatorListener listener, final PinholeCameraIntrinsicParameters intrinsic,
1347             final List<Point3D> points3D, final List<Point2D> points2D, final double[] qualityScores,
1348             final RobustEstimatorMethod method) {
1349         return PointCorrespondencePinholeCameraRobustEstimator.create(listener, intrinsic, points3D, points2D,
1350                 qualityScores, method);
1351     }
1352 
1353     /**
1354      * Creates a pinhole camera robust estimator based on 2D/3D point
1355      * correspondences and using default robust estimator method.
1356      *
1357      * @param intrinsic intrinsic parameters of camera to be estimated.
1358      * @param points3D  list of 3D points used to estimate a pinhole camera.
1359      * @param points2D  list of corresponding projected 2D points used to
1360      *                  estimate a pinhole camera.
1361      * @return an instance of a pinhole camera robust estimator.
1362      * @throws IllegalArgumentException if provided lists of points don't have
1363      *                                  the same size or their size is smaller than required minimum size
1364      *                                  (6 correspondences).
1365      */
1366     public static PinholeCameraRobustEstimator createFromPoints(
1367             final PinholeCameraIntrinsicParameters intrinsic, final List<Point3D> points3D,
1368             final List<Point2D> points2D) {
1369         return PointCorrespondencePinholeCameraRobustEstimator.create(intrinsic, points3D, points2D);
1370     }
1371 
1372     /**
1373      * Creates a pinhole camera robust estimator based on 2D/3D point
1374      * correspondences and using provided listener and default robust estimator
1375      * method.
1376      *
1377      * @param listener  listener to be notified of events such as when estimation
1378      *                  starts, ends or its progress significantly changes.
1379      * @param intrinsic intrinsic parameters of camera to be estimated.
1380      * @param points3D  list of 3D points used to estimate a pinhole camera.
1381      * @param points2D  list of corresponding projected 2D points used to
1382      *                  estimate a pinhole camera.
1383      * @return an instance of a pinhole camera robust estimator.
1384      * @throws IllegalArgumentException if provided lists of points don't have
1385      *                                  the same size or their size is smaller than required minimum size
1386      *                                  (6 correspondences).
1387      */
1388     public static PinholeCameraRobustEstimator createFromPoints(
1389             final PinholeCameraRobustEstimatorListener listener, final PinholeCameraIntrinsicParameters intrinsic,
1390             final List<Point3D> points3D, final List<Point2D> points2D) {
1391         return PointCorrespondencePinholeCameraRobustEstimator.create(listener, intrinsic, points3D, points2D);
1392     }
1393 
1394     /**
1395      * Creates a pinhole camera robust estimator based on 2D/3D point
1396      * correspondences and using provided quality scores and default robust
1397      * estimator method.
1398      *
1399      * @param intrinsic     intrinsic parameters of camera to be estimated.
1400      * @param points3D      list of 3D points used to estimate a pinhole camera.
1401      * @param points2D      list of corresponding projected 2D points used to
1402      *                      estimate a pinhole camera.
1403      * @param qualityScores quality scores corresponding to each pair of matched
1404      *                      points.
1405      * @return an instance of a pinhole camera robust estimator.
1406      * @throws IllegalArgumentException if provided lists of points and quality
1407      *                                  scores don't have the same size  or their size is smaller than required
1408      *                                  minimum size (6 correspondences).
1409      */
1410     public static PinholeCameraRobustEstimator createFromPoints(
1411             final PinholeCameraIntrinsicParameters intrinsic, final List<Point3D> points3D,
1412             final List<Point2D> points2D, final double[] qualityScores) {
1413         return PointCorrespondencePinholeCameraRobustEstimator.create(intrinsic, points3D, points2D, qualityScores);
1414     }
1415 
1416     /**
1417      * Creates a pinhole camera robust estimator based on 2D/3D point
1418      * correspondences and using provided listener, quality scores and default
1419      * robust estimator method.
1420      *
1421      * @param listener      listener to be notified of events such as when estimation
1422      *                      starts, ends or its progress significantly changes.
1423      * @param intrinsic     intrinsic parameters of camera to be estimated.
1424      * @param points3D      list of 3D points used to estimate a pinhole camera.
1425      * @param points2D      list of corresponding projected 2D points used to
1426      *                      estimate a pinhole camera.
1427      * @param qualityScores quality scores corresponding to each pair of matched
1428      *                      points.
1429      * @return an instance of a pinhole camera robust estimator.
1430      * @throws IllegalArgumentException if provided lists of points and quality
1431      *                                  scores don't have the same size  or their size is smaller than required
1432      *                                  minimum size (6 correspondences).
1433      */
1434     public static PinholeCameraRobustEstimator createFromPoints(
1435             final PinholeCameraRobustEstimatorListener listener, final PinholeCameraIntrinsicParameters intrinsic,
1436             final List<Point3D> points3D, final List<Point2D> points2D, final double[] qualityScores) {
1437         return PointCorrespondencePinholeCameraRobustEstimator.create(listener, intrinsic, points3D, points2D,
1438                 qualityScores);
1439     }
1440 
1441     /**
1442      * Creates a pinhole camera robust estimator based on 2D/3D point
1443      * correspondences and using provided robust estimator method.
1444      *
1445      * @param skewness                 skewness value of intrinsic parameters of camera to be
1446      *                                 estimated.
1447      * @param horizontalPrincipalPoint horizontal principal point value of
1448      *                                 intrinsic parameters of camera to be estimated.
1449      * @param verticalPrincipalPoint   vertical principal point value of
1450      *                                 intrinsic parameters of camera to be estimated.
1451      * @param points3D                 list of 3D points used to estimate a pinhole camera.
1452      * @param points2D                 list of corresponding projected 2D points used to
1453      *                                 estimate a pinhole camera.
1454      * @param method                   method of a robust estimator algorithm to estimate the best
1455      *                                 pinhole camera.
1456      * @return an instance of a pinhole camera robust estimator.
1457      * @throws IllegalArgumentException if provided lists of points don't have
1458      *                                  the same size or their size is smaller than required minimum size
1459      *                                  (6 correspondences).
1460      */
1461     public static PinholeCameraRobustEstimator createFromPoints(
1462             final double skewness, final double horizontalPrincipalPoint, final double verticalPrincipalPoint,
1463             final List<Point3D> points3D, final List<Point2D> points2D, final RobustEstimatorMethod method) {
1464         return PointCorrespondencePinholeCameraRobustEstimator.create(skewness, horizontalPrincipalPoint,
1465                 verticalPrincipalPoint, points3D, points2D, method);
1466     }
1467 
1468     /**
1469      * Creates a pinhole camera robust estimator based on 2D/3D point
1470      * correspondences and using provided listener and robust estimator method.
1471      *
1472      * @param listener                 listener to be notified of events such as when estimation
1473      *                                 starts, ends or its progress significantly changes.
1474      * @param skewness                 skewness value of intrinsic parameters of camera to be
1475      *                                 estimated.
1476      * @param horizontalPrincipalPoint horizontal principal point value of
1477      *                                 intrinsic parameters of camera to be estimated.
1478      * @param verticalPrincipalPoint   vertical principal point value of
1479      *                                 intrinsic parameters of camera to be estimated.
1480      * @param points3D                 list of 3D points used to estimate a pinhole camera.
1481      * @param points2D                 list of corresponding projected 2D points used to
1482      *                                 estimate a pinhole camera.
1483      * @param method                   method of a robust estimator algorithm to estimate the best
1484      *                                 pinhole camera.
1485      * @return an instance of a pinhole camera robust estimator.
1486      * @throws IllegalArgumentException if provided lists of points don't have
1487      *                                  the same size or their size is smaller than required minimum size
1488      *                                  (6 correspondences).
1489      */
1490     public static PinholeCameraRobustEstimator createFromPoints(
1491             final PinholeCameraRobustEstimatorListener listener, final double skewness,
1492             final double horizontalPrincipalPoint, final double verticalPrincipalPoint, final List<Point3D> points3D,
1493             final List<Point2D> points2D, final RobustEstimatorMethod method) {
1494         return PointCorrespondencePinholeCameraRobustEstimator.create(listener, skewness, horizontalPrincipalPoint,
1495                 verticalPrincipalPoint, points3D, points2D, method);
1496     }
1497 
1498     /**
1499      * Creates a pinhole camera robust estimator based on 2D/3D point
1500      * correspondences and using provided quality scores and robust estimator
1501      * method.
1502      *
1503      * @param skewness                 skewness value of intrinsic parameters of camera to be
1504      *                                 estimated.
1505      * @param horizontalPrincipalPoint horizontal principal point value of
1506      *                                 intrinsic parameters of camera to be estimated.
1507      * @param verticalPrincipalPoint   vertical principal point value of
1508      *                                 intrinsic parameters of camera to be estimated.
1509      * @param points3D                 list of 3D points used to estimate a pinhole camera.
1510      * @param points2D                 list of corresponding projected 2D points used to
1511      *                                 estimate a pinhole camera.
1512      * @param qualityScores            quality scores corresponding to each pair of matched
1513      *                                 points.
1514      * @param method                   method of a robust estimator algorithm to estimate the best
1515      *                                 pinhole camera.
1516      * @return an instance of a pinhole camera robust estimator.
1517      * @throws IllegalArgumentException if provided lists of points and quality
1518      *                                  scores don't have the same size  or their size is smaller than required
1519      *                                  minimum size (6 correspondences).
1520      */
1521     public static PinholeCameraRobustEstimator createFromPoints(
1522             final double skewness, final double horizontalPrincipalPoint, final double verticalPrincipalPoint,
1523             final List<Point3D> points3D, final List<Point2D> points2D, final double[] qualityScores,
1524             final RobustEstimatorMethod method) {
1525         return PointCorrespondencePinholeCameraRobustEstimator.create(skewness, horizontalPrincipalPoint,
1526                 verticalPrincipalPoint, points3D, points2D, qualityScores, method);
1527     }
1528 
1529     /**
1530      * Creates a pinhole camera robust estimator based on 2D/3D point
1531      * correspondences and using provided listener, quality scores and robust
1532      * estimator method.
1533      *
1534      * @param listener                 listener to be notified of events such as when estimation
1535      *                                 starts, ends or its progress significantly changes.
1536      * @param skewness                 skewness value of intrinsic parameters of camera to be
1537      *                                 estimated.
1538      * @param horizontalPrincipalPoint horizontal principal point value of
1539      *                                 intrinsic parameters of camera to be estimated.
1540      * @param verticalPrincipalPoint   vertical principal point value of
1541      *                                 intrinsic parameters of camera to be estimated.
1542      * @param points3D                 list of 3D points used to estimate a pinhole camera.
1543      * @param points2D                 list of corresponding projected 2D points used to
1544      *                                 estimate a pinhole camera.
1545      * @param qualityScores            quality scores corresponding to each pair of matched
1546      *                                 points.
1547      * @param method                   method of a robust estimator algorithm to estimate the best
1548      *                                 pinhole camera.
1549      * @return an instance of a pinhole camera robust estimator.
1550      * @throws IllegalArgumentException if provided lists of points and quality
1551      *                                  scores don't have the same size  or their size is smaller than required
1552      *                                  minimum size (6 correspondences).
1553      */
1554     public static PinholeCameraRobustEstimator createFromPoints(
1555             final PinholeCameraRobustEstimatorListener listener, final double skewness,
1556             final double horizontalPrincipalPoint, final double verticalPrincipalPoint, final List<Point3D> points3D,
1557             final List<Point2D> points2D, final double[] qualityScores, final RobustEstimatorMethod method) {
1558         return PointCorrespondencePinholeCameraRobustEstimator.create(listener, skewness, horizontalPrincipalPoint,
1559                 verticalPrincipalPoint, points3D, points2D, qualityScores, method);
1560     }
1561 
1562     /**
1563      * Creates a pinhole camera robust estimator based on 2D/3D point
1564      * correspondences and using default robust estimator method.
1565      *
1566      * @param skewness                 skewness value of intrinsic parameters of camera to be
1567      *                                 estimated.
1568      * @param horizontalPrincipalPoint horizontal principal point value of
1569      *                                 intrinsic parameters of camera to be estimated.
1570      * @param verticalPrincipalPoint   vertical principal point value of
1571      *                                 intrinsic parameters of camera to be estimated.
1572      * @param points3D                 list of 3D points used to estimate a pinhole camera.
1573      * @param points2D                 list of corresponding projected 2D points used to
1574      *                                 estimate a pinhole camera.
1575      * @return an instance of a pinhole camera robust estimator.
1576      * @throws IllegalArgumentException if provided lists of points don't have
1577      *                                  the same size or their size is smaller than required minimum size
1578      *                                  (6 correspondences).
1579      */
1580     public static PinholeCameraRobustEstimator createFromPoints(
1581             final double skewness, final double horizontalPrincipalPoint, final double verticalPrincipalPoint,
1582             final List<Point3D> points3D, final List<Point2D> points2D) {
1583         return PointCorrespondencePinholeCameraRobustEstimator.create(skewness, horizontalPrincipalPoint,
1584                 verticalPrincipalPoint, points3D, points2D);
1585     }
1586 
1587     /**
1588      * Creates a pinhole camera robust estimator based on 2D/3D point
1589      * correspondences and using provided listener and default robust estimator
1590      * method.
1591      *
1592      * @param listener                 listener to be notified of events such as when estimation
1593      *                                 starts, ends or its progress significantly changes.
1594      * @param skewness                 skewness value of intrinsic parameters of camera to be
1595      *                                 estimated.
1596      * @param horizontalPrincipalPoint horizontal principal point value of
1597      *                                 intrinsic parameters of camera to be estimated.
1598      * @param verticalPrincipalPoint   vertical principal point value of
1599      *                                 intrinsic parameters of camera to be estimated.
1600      * @param points3D                 list of 3D points used to estimate a pinhole camera.
1601      * @param points2D                 list of corresponding projected 2D points used to
1602      *                                 estimate a pinhole camera.
1603      * @return an instance of a pinhole camera robust estimator.
1604      * @throws IllegalArgumentException if provided lists of points don't have
1605      *                                  the same size or their size is smaller than required minimum size
1606      *                                  (6 correspondences).
1607      */
1608     public static PinholeCameraRobustEstimator createFromPoints(
1609             final PinholeCameraRobustEstimatorListener listener, final double skewness,
1610             final double horizontalPrincipalPoint, final double verticalPrincipalPoint, final List<Point3D> points3D,
1611             final List<Point2D> points2D) {
1612         return PointCorrespondencePinholeCameraRobustEstimator.create(listener, skewness, horizontalPrincipalPoint,
1613                 verticalPrincipalPoint, points3D, points2D);
1614     }
1615 
1616     /**
1617      * Creates a pinhole camera robust estimator based on 2D/3D point
1618      * correspondences and using provided quality scores and default robust
1619      * estimator method.
1620      *
1621      * @param skewness                 skewness value of intrinsic parameters of camera to be
1622      *                                 estimated.
1623      * @param horizontalPrincipalPoint horizontal principal point value of
1624      *                                 intrinsic parameters of camera to be estimated.
1625      * @param verticalPrincipalPoint   vertical principal point value of
1626      *                                 intrinsic parameters of camera to be estimated.
1627      * @param points3D                 list of 3D points used to estimate a pinhole camera.
1628      * @param points2D                 list of corresponding projected 2D points used to
1629      *                                 estimate a pinhole camera.
1630      * @param qualityScores            quality scores corresponding to each pair of matched
1631      *                                 points.
1632      * @return an instance of a pinhole camera robust estimator.
1633      * @throws IllegalArgumentException if provided lists of points and quality
1634      *                                  scores don't have the same size  or their size is smaller than required
1635      *                                  minimum size (6 correspondences).
1636      */
1637     public static PinholeCameraRobustEstimator createFromPoints(
1638             final double skewness, final double horizontalPrincipalPoint, final double verticalPrincipalPoint,
1639             final List<Point3D> points3D, final List<Point2D> points2D, final double[] qualityScores) {
1640         return PointCorrespondencePinholeCameraRobustEstimator.create(skewness, horizontalPrincipalPoint,
1641                 verticalPrincipalPoint, points3D, points2D, qualityScores);
1642     }
1643 
1644     /**
1645      * Creates a pinhole camera robust estimator based on 2D/3D point
1646      * correspondences and using provided listener, quality scores and default
1647      * robust estimator method.
1648      *
1649      * @param listener                 listener to be notified of events such as when estimation
1650      *                                 starts, ends or its progress significantly changes.
1651      * @param skewness                 skewness value of intrinsic parameters of camera to be
1652      *                                 estimated.
1653      * @param horizontalPrincipalPoint horizontal principal point value of
1654      *                                 intrinsic parameters of camera to be estimated.
1655      * @param verticalPrincipalPoint   vertical principal point value of
1656      *                                 intrinsic parameters of camera to be estimated.
1657      * @param points3D                 list of 3D points used to estimate a pinhole camera.
1658      * @param points2D                 list of corresponding projected 2D points used to
1659      *                                 estimate a pinhole camera.
1660      * @param qualityScores            quality scores corresponding to each pair of matched
1661      *                                 points.
1662      * @return an instance of a pinhole camera robust estimator.
1663      * @throws IllegalArgumentException if provided lists of points and quality
1664      *                                  scores don't have the same size  or their size is smaller than required
1665      *                                  minimum size (6 correspondences).
1666      */
1667     public static PinholeCameraRobustEstimator createFromPoints(
1668             final PinholeCameraRobustEstimatorListener listener, final double skewness,
1669             final double horizontalPrincipalPoint, final double verticalPrincipalPoint, final List<Point3D> points3D,
1670             final List<Point2D> points2D, final double[] qualityScores) {
1671         return PointCorrespondencePinholeCameraRobustEstimator.create(listener, skewness, horizontalPrincipalPoint,
1672                 verticalPrincipalPoint, points3D, points2D, qualityScores);
1673     }
1674 
1675     /**
1676      * Creates a pinhole camera robust estimator based on 3D plane/2D line
1677      * correspondences and using provided robust estimator method.
1678      *
1679      * @param planes list of 3D planes used to estimate a pinhole camera.
1680      * @param lines  list of corresponding projected 2D lines used to estimate
1681      *               a pinhole camera.
1682      * @param method method of a robust estimator algorithm to estimate the best
1683      *               pinhole camera.
1684      * @return an instance of a pinhole camera robust estimator.
1685      * @throws IllegalArgumentException if provided lists of planes/lines don't
1686      *                                  have the same size or their size is smaller than required minimum size (4
1687      *                                  correspondences).
1688      */
1689     public static PinholeCameraRobustEstimator createFromPlanesAndLines(
1690             final List<Plane> planes, final List<Line2D> lines, final RobustEstimatorMethod method) {
1691         return LinePlaneCorrespondencePinholeCameraRobustEstimator.create(planes, lines, method);
1692     }
1693 
1694     /**
1695      * Creates a pinhole camera robust estimator based on 3D plane/2D line
1696      * correspondences and using provided listener and robust estimator method.
1697      *
1698      * @param listener listener to be notified of events such as when estimation
1699      *                 starts, ends or its progress significantly changes.
1700      * @param planes   list of 3D planes used to estimate a pinhole camera.
1701      * @param lines    list of corresponding projected 2D lines used to estimate
1702      *                 a pinhole camera.
1703      * @param method   method of a robust estimator algorithm to estimate the best
1704      *                 pinhole camera.
1705      * @return an instance of a pinhole camera robust estimator.
1706      * @throws IllegalArgumentException if provided lists of planes/lines don't
1707      *                                  have the same size or their size is smaller than required minimum size (4
1708      *                                  correspondences).
1709      */
1710     public static PinholeCameraRobustEstimator createFromPlanesAndLines(
1711             final PinholeCameraRobustEstimatorListener listener, final List<Plane> planes, final List<Line2D> lines,
1712             final RobustEstimatorMethod method) {
1713         return LinePlaneCorrespondencePinholeCameraRobustEstimator.create(listener, planes, lines, method);
1714     }
1715 
1716     /**
1717      * Creates a pinhole camera robust estimator based on 3D plane/2D line
1718      * correspondences and using provided quality scores and robust estimator
1719      * method.
1720      *
1721      * @param planes        list of 3D planes used to estimate a pinhole camera.
1722      * @param lines         list of corresponding projected 2D lines used to estimate
1723      *                      a pinhole camera.
1724      * @param qualityScores quality scores corresponding to each pair of matched
1725      *                      samples.
1726      * @param method        method of a robust estimator algorithm to estimate the best
1727      *                      pinhole camera.
1728      * @return an instance of a pinhole camera robust estimator.
1729      * @throws IllegalArgumentException if provided lists of planes/lines and
1730      *                                  quality scores don't have the same size or their size is smaller than
1731      *                                  required minimum size (4 correspondences).
1732      */
1733     public static PinholeCameraRobustEstimator createFromPlanesAndLines(
1734             final List<Plane> planes, final List<Line2D> lines, final double[] qualityScores,
1735             final RobustEstimatorMethod method) {
1736         return LinePlaneCorrespondencePinholeCameraRobustEstimator.create(planes, lines, qualityScores, method);
1737     }
1738 
1739     /**
1740      * Creates a pinhole camera robust estimator based on 3D plane/2D line
1741      * correspondences and using provided listener, quality scores and robust
1742      * estimator method.
1743      *
1744      * @param listener      listener to be notified of events such as when estimation
1745      *                      starts, ends or its progress significantly changes.
1746      * @param planes        list of 3D planes used to estimate a pinhole camera.
1747      * @param lines         list of corresponding projected 2D lines used to estimate
1748      *                      a pinhole camera.
1749      * @param qualityScores quality scores corresponding to each pair of matched
1750      *                      samples.
1751      * @param method        method of a robust estimator algorithm to estimate the best
1752      *                      pinhole camera.
1753      * @return an instance of a pinhole camera robust estimator.
1754      * @throws IllegalArgumentException if provided lists of planes/lines and
1755      *                                  quality scores don't have the same size or their size is smaller than
1756      *                                  required minimum size (4 correspondences).
1757      */
1758     public static PinholeCameraRobustEstimator createFromPlanesAndLines(
1759             final PinholeCameraRobustEstimatorListener listener, final List<Plane> planes, final List<Line2D> lines,
1760             final double[] qualityScores, final RobustEstimatorMethod method) {
1761         return LinePlaneCorrespondencePinholeCameraRobustEstimator.create(listener, planes, lines, qualityScores,
1762                 method);
1763     }
1764 
1765     /**
1766      * Creates a pinhole camera robust estimator based on 3D plane/2D line
1767      * correspondences and using default robust estimator method.
1768      *
1769      * @param planes list of 3D planes used to estimate a pinhole camera.
1770      * @param lines  list of corresponding projected 2D lines used to estimate
1771      *               a pinhole camera.
1772      * @return an instance of a pinhole camera robust estimator.
1773      * @throws IllegalArgumentException if provided lists of planes/lines don't
1774      *                                  have the same size or their size is smaller than required minimum size (4
1775      *                                  correspondences).
1776      */
1777     public static PinholeCameraRobustEstimator createFromPlanesAndLines(
1778             final List<Plane> planes, final List<Line2D> lines) {
1779         return LinePlaneCorrespondencePinholeCameraRobustEstimator.create(planes, lines);
1780     }
1781 
1782     /**
1783      * Creates a pinhole camera robust estimator based on 3D plane/2D line
1784      * correspondences and using provided listener and default robust estimator
1785      * method.
1786      *
1787      * @param listener listener to be notified of events such as when estimation
1788      *                 starts, ends or its progress significantly changes.
1789      * @param planes   list of 3D planes used to estimate a pinhole camera.
1790      * @param lines    list of corresponding projected 2D lines used to estimate
1791      *                 a pinhole camera.
1792      * @return an instance of a pinhole camera robust estimator.
1793      * @throws IllegalArgumentException if provided lists of planes/lines don't
1794      *                                  have the same size or their size is smaller than required minimum size (4
1795      *                                  correspondences).
1796      */
1797     public static PinholeCameraRobustEstimator createFromPlanesAndLines(
1798             final PinholeCameraRobustEstimatorListener listener, final List<Plane> planes, final List<Line2D> lines) {
1799         return LinePlaneCorrespondencePinholeCameraRobustEstimator.create(listener, planes, lines);
1800     }
1801 
1802     /**
1803      * Creates a pinhole camera robust estimator based on 3D plane/2D line
1804      * correspondences and using provided quality scores and default robust
1805      * estimator method.
1806      *
1807      * @param planes        list of 3D planes used to estimate a pinhole camera.
1808      * @param lines         list of corresponding projected 2D lines used to estimate
1809      *                      a pinhole camera.
1810      * @param qualityScores quality scores corresponding to each pair of matched
1811      *                      samples.
1812      * @return an instance of a pinhole camera robust estimator.
1813      * @throws IllegalArgumentException if provided lists of planes/lines and
1814      *                                  quality scores don't have the same size or their size is smaller than
1815      *                                  required minimum size (4 correspondences).
1816      */
1817     public static PinholeCameraRobustEstimator createFromPlanesAndLines(
1818             final List<Plane> planes, final List<Line2D> lines, final double[] qualityScores) {
1819         return LinePlaneCorrespondencePinholeCameraRobustEstimator.create(planes, lines, qualityScores);
1820     }
1821 
1822     /**
1823      * Creates a pinhole camera robust estimator based on 3D plane/2D line
1824      * correspondences and using provided listener, quality scores and default
1825      * robust estimator method.
1826      *
1827      * @param listener      listener to be notified of events such as when estimation
1828      *                      starts, ends or its progress significantly changes.
1829      * @param planes        list of 3D planes used to estimate a pinhole camera.
1830      * @param lines         list of corresponding projected 2D lines used to estimate
1831      *                      a pinhole camera.
1832      * @param qualityScores quality scores corresponding to each pair of matched
1833      *                      samples.
1834      * @return an instance of a pinhole camera robust estimator.
1835      * @throws IllegalArgumentException if provided lists of planes/lines and
1836      *                                  quality scores don't have the same size or their size is smaller than
1837      *                                  required minimum size (4 correspondences).
1838      */
1839     public static PinholeCameraRobustEstimator createFromPlanesAndLines(
1840             final PinholeCameraRobustEstimatorListener listener, final List<Plane> planes,
1841             final List<Line2D> lines, final double[] qualityScores) {
1842         return LinePlaneCorrespondencePinholeCameraRobustEstimator.create(listener, planes, lines, qualityScores);
1843     }
1844 
1845     /**
1846      * Indicates whether obtained solution requires refinement to apply provided
1847      * suggestions.
1848      *
1849      * @return true if solution requires refinement to apply provided
1850      * suggestions, false otherwise.
1851      */
1852     protected boolean hasSuggestions() {
1853         return hasIntrinsicSuggestions() || hasExtrinsicSuggestions();
1854     }
1855 
1856     /**
1857      * Indicates whether suggestions for any intrinsic parameter are required
1858      * or not.
1859      *
1860      * @return true if suggestions for any intrinsic parameters are required,
1861      * false otherwise.
1862      */
1863     private boolean hasIntrinsicSuggestions() {
1864         return suggestSkewnessValueEnabled || suggestHorizontalFocalLengthEnabled || suggestVerticalFocalLengthEnabled
1865                 || suggestAspectRatioEnabled;
1866     }
1867 
1868     /**
1869      * Indicates whether suggestions for any extrinsic parameter are required
1870      * or not.
1871      *
1872      * @return true if suggestions for any extrinsic parameter are required,
1873      * false otherwise.
1874      */
1875     private boolean hasExtrinsicSuggestions() {
1876         return suggestPrincipalPointEnabled || suggestRotationEnabled || suggestCenterEnabled;
1877     }
1878 }