View Javadoc
1   /*
2    * Copyright (C) 2017 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.geometry.Point2D;
19  import com.irurueta.geometry.Point3D;
20  import com.irurueta.numerical.robust.RobustEstimatorMethod;
21  
22  import java.util.List;
23  
24  /**
25   * Base abstract class for algorithms to robustly find the best pinhole camera
26   * for collections of matched 3D/2D points using UPnP (Uncalibrated
27   * Perspective-n-Point) algorithm.
28   * Implementations of this class should be able to detect and discard outliers
29   * in order to find the best solution.
30   */
31  public abstract class UPnPPointCorrespondencePinholeCameraRobustEstimator extends
32          PointCorrespondencePinholeCameraRobustEstimator {
33  
34      /**
35       * Indicates whether planar configuration is checked to determine whether
36       * point correspondences are in such configuration and find a specific
37       * solution for such case.
38       */
39      protected boolean planarConfigurationAllowed =
40              UPnPPointCorrespondencePinholeCameraEstimator.DEFAULT_PLANAR_CONFIGURATION_ALLOWED;
41  
42      /**
43       * Indicates whether the case where a dimension 2 null-space is allowed.
44       * When allowed, additional constraints are taken into account to ensure
45       * equality of scales so that less point correspondences are required.
46       * Enabling this parameter is usually ok.
47       */
48      protected boolean nullspaceDimension2Allowed =
49              UPnPPointCorrespondencePinholeCameraEstimator.DEFAULT_NULLSPACE_DIMENSION2_ALLOWED;
50  
51      /**
52       * Threshold to determine whether 3D matched points are in a planar
53       * configuration.
54       * Points are considered to be laying in a plane when the smallest singular
55       * value of their covariance matrix has a value much smaller than the
56       * largest one as many times as this value.
57       */
58      protected double planarThreshold = UPnPPointCorrespondencePinholeCameraEstimator.DEFAULT_PLANAR_THRESHOLD;
59  
60      /**
61       * Skewness value of intrinsic parameters to be used on estimated camera.
62       */
63      protected double skewness = UPnPPointCorrespondencePinholeCameraEstimator.DEFAULT_SKEWNESS;
64  
65      /**
66       * Horizontal coordinate of principal point on intrinsic parameters to be
67       * used on estimated camera.
68       */
69      protected double horizontalPrincipalPoint =
70              UPnPPointCorrespondencePinholeCameraEstimator.DEFAULT_HORIZONTAL_PRINCIPAL_POINT;
71  
72      /**
73       * Vertical coordinate of principal point on intrinsic parameters to be used
74       * on estimated camera.
75       */
76      protected double verticalPrincipalPoint =
77              UPnPPointCorrespondencePinholeCameraEstimator.DEFAULT_VERTICAL_PRINCIPAL_POINT;
78  
79      /**
80       * Constructor.
81       */
82      protected UPnPPointCorrespondencePinholeCameraRobustEstimator() {
83          super();
84      }
85  
86      /**
87       * Constructor with listener.
88       *
89       * @param listener listener to be notified of events such as when estimation
90       *                 starts, ends or its progress significantly changes.
91       */
92      protected UPnPPointCorrespondencePinholeCameraRobustEstimator(final PinholeCameraRobustEstimatorListener listener) {
93          super(listener);
94      }
95  
96      /**
97       * Constructor with lists of points to be used to estimate a pinhole camera.
98       * Points in the lists located at the same position are considered to be
99       * matched. Hence, both lists must have the same size and their size must
100      * be greater or equal than MIN_NUMBER_OF_POINT_CORRESPONDENCES (6 points).
101      *
102      * @param points3D list of 3D points used to estimate a pinhole camera.
103      * @param points2D list of corresponding projected 2D points used to
104      *                 estimate a pinhole camera.
105      * @throws IllegalArgumentException if provided lists of points don't have
106      *                                  the same size or their size is smaller than required minimum size (6
107      *                                  correspondences).
108      */
109     protected UPnPPointCorrespondencePinholeCameraRobustEstimator(
110             final List<Point3D> points3D, final List<Point2D> points2D) {
111         super(points3D, points2D);
112     }
113 
114     /**
115      * Constructor with listener and lists of points to be used to estimate a
116      * pinhole camera.
117      * Points in the lists located at the same position are considered to be
118      * matched. Hence, both lists must have the same size, and their size must
119      * be greater or equal than MIN_NUMBER_OF_POINT_CORRESPONDENCES (6 points).
120      *
121      * @param listener listener to be notified of events such as when estimation
122      *                 starts, ends or its progress significantly changes.
123      * @param points3D list of 3D points used to estimate a pinhole camera.
124      * @param points2D list of corresponding projected 2D points used to
125      *                 estimate a pinhole camera.
126      * @throws IllegalArgumentException if provided lists of points don't have
127      *                                  the same size or their size is smaller than required minimum size (6
128      *                                  correspondences).
129      */
130     protected UPnPPointCorrespondencePinholeCameraRobustEstimator(
131             final PinholeCameraRobustEstimatorListener listener,
132             final List<Point3D> points3D, final List<Point2D> points2D) {
133         super(listener, points3D, points2D);
134     }
135 
136     /**
137      * Indicates whether planar configuration is checked to determine whether
138      * point correspondences are in such configuration and find a specific
139      * solution for such case.
140      *
141      * @return true to allow specific solutions for planar configurations,
142      * false to always find a solution assuming the general case.
143      */
144     public boolean isPlanarConfigurationAllowed() {
145         return planarConfigurationAllowed;
146     }
147 
148     /**
149      * Specifies whether planar configuration is checked to determine whether
150      * point correspondences are in such configuration and find a specific
151      * solution for such case.
152      *
153      * @param planarConfigurationAllowed true to allow specific solutions for
154      *                                   planar configurations, false to always find a solution assuming the
155      *                                   general case.
156      * @throws LockedException if estimator is locked.
157      */
158     public void setPlanarConfigurationAllowed(final boolean planarConfigurationAllowed) throws LockedException {
159         if (isLocked()) {
160             throw new LockedException();
161         }
162         this.planarConfigurationAllowed = planarConfigurationAllowed;
163     }
164 
165     /**
166      * Indicates whether the case where a dimension 2 null-space is allowed.
167      * When allowed, additional constraints are taken into account to ensure
168      * equality of scales so that less point correspondences are required.
169      * Enabling this parameter is usually ok.
170      *
171      * @return true to allow 2-dimensional null-space, false otherwise.
172      */
173     public boolean isNullspaceDimension2Allowed() {
174         return nullspaceDimension2Allowed;
175     }
176 
177     /**
178      * Specifies whether the case where a dimension 2 null-space is allowed.
179      * When allowed, additional constraints are taken into account to ensure
180      * equality of scales so that less point correspondences are required.
181      * Enabling this parameter is usually ok.
182      *
183      * @param nullspaceDimension2Allowed true to allow 2-dimensional null-space,
184      *                                   false otherwise.
185      * @throws LockedException if estimator is locked.
186      */
187     public void setNullspaceDimension2Allowed(final boolean nullspaceDimension2Allowed) throws LockedException {
188         if (isLocked()) {
189             throw new LockedException();
190         }
191         this.nullspaceDimension2Allowed = nullspaceDimension2Allowed;
192     }
193 
194     /**
195      * Gets threshold to determine whether 3D matched points are in a planar
196      * configuration.
197      * Points are considered to be laying in a plane when the smallest singular
198      * value of their covariance matrix has a value much smaller than the
199      * largest one as many times as this value.
200      *
201      * @return threshold to determine whether 3D matched points are in a planar
202      * configuration.
203      */
204     public double getPlanarThreshold() {
205         return planarThreshold;
206     }
207 
208     /**
209      * Sets threshold to determine whether 3D matched points are in a planar
210      * configuration.
211      * Points are considered to be laying in a plane when the smallest singular
212      * value of their covariance matrix has a value much smaller than the
213      * largest one as many times as this value.
214      *
215      * @param planarThreshold threshold to determine whether 3D matched points
216      *                        are in a planar configuration.
217      * @throws IllegalArgumentException if provided threshold is negative.
218      * @throws LockedException          if estimator is locked.
219      */
220     public void setPlanarThreshold(final double planarThreshold) throws LockedException {
221         if (isLocked()) {
222             throw new LockedException();
223         }
224         if (planarThreshold < 0.0) {
225             throw new IllegalArgumentException();
226         }
227         this.planarThreshold = planarThreshold;
228     }
229 
230     /**
231      * Gets skewness value of intrinsic parameters to be used on estimated
232      * camera.
233      *
234      * @return skewness value of intrinsic parameters to be used on estimated
235      * camera.
236      */
237     public double getSkewness() {
238         return skewness;
239     }
240 
241     /**
242      * Sets skewness value of intrinsic parameters to be used on estimated
243      * camera.
244      *
245      * @param skewness skewness value of intrinsic parameters to be used on
246      *                 estimated camera.
247      * @throws LockedException if estimator is locked.
248      */
249     public void setSkewness(final double skewness) throws LockedException {
250         if (isLocked()) {
251             throw new LockedException();
252         }
253         this.skewness = skewness;
254     }
255 
256     /**
257      * Gets horizontal coordinate of principal point on intrinsic parameters to
258      * be used on estimated camera.
259      *
260      * @return horizontal coordinate of principal point.
261      */
262     public double getHorizontalPrincipalPoint() {
263         return horizontalPrincipalPoint;
264     }
265 
266     /**
267      * Sets horizontal coordinate of principal point on intrinsic parameters to
268      * be used on estimated camera.
269      *
270      * @param horizontalPrincipalPoint horizontal coordinate of principal point.
271      * @throws LockedException if estimator is locked.
272      */
273     public void setHorizontalPrincipalPoint(final double horizontalPrincipalPoint) throws LockedException {
274         if (isLocked()) {
275             throw new LockedException();
276         }
277         this.horizontalPrincipalPoint = horizontalPrincipalPoint;
278     }
279 
280     /**
281      * Gets vertical coordinate of principal point on intrinsic parameters to
282      * be used on estimated camera.
283      *
284      * @return vertical coordinate of principal point.
285      */
286     public double getVerticalPrincipalPoint() {
287         return verticalPrincipalPoint;
288     }
289 
290     /**
291      * Sets vertical coordinate of principal point on intrinsic parameters to
292      * be used on estimated camera.
293      *
294      * @param verticalPrincipalPoint vertical coordinate of principal point.
295      * @throws LockedException if estimator is locked.
296      */
297     public void setVerticalPrincipalPoint(final double verticalPrincipalPoint) throws LockedException {
298         if (isLocked()) {
299             throw new LockedException();
300         }
301         this.verticalPrincipalPoint = verticalPrincipalPoint;
302     }
303 
304     /**
305      * Returns value indicating if each picked subset point correspondences are
306      * normalized to increase the accuracy of the estimation.
307      *
308      * @return true if each picked subset point correspondences are normalized,
309      * false otherwise.
310      */
311     @Override
312     public boolean isNormalizeSubsetPointCorrespondences() {
313         return false;
314     }
315 
316     /**
317      * Sets value indicating if each picked subset point correspondences are
318      * normalized to increase the accuracy of the estimation.
319      *
320      * @param normalizeSubsetPointCorrespondences true if each picked subset
321      *                                            point correspondences are normalized, false otherwise.
322      * @throws LockedException if robust estimator is locked because an
323      *                         estimation is already in progress.
324      */
325     @Override
326     public void setNormalizeSubsetPointCorrespondences(final boolean normalizeSubsetPointCorrespondences)
327             throws LockedException {
328         if (isLocked()) {
329             throw new LockedException();
330         }
331     }
332 
333     /**
334      * Creates a pinhole camera robust estimator based on point correspondences
335      * and using provided robust estimator method.
336      *
337      * @param method method of a robust estimator algorithm to estimate the best
338      *               pinhole camera.
339      * @return an instance of a pinhole camera robust estimator.
340      */
341     public static UPnPPointCorrespondencePinholeCameraRobustEstimator create(final RobustEstimatorMethod method) {
342         return switch (method) {
343             case LMEDS -> new LMedSUPnPPointCorrespondencePinholeCameraRobustEstimator();
344             case MSAC -> new MSACUPnPPointCorrespondencePinholeCameraRobustEstimator();
345             case PROSAC -> new PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator();
346             case PROMEDS -> new PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator();
347             default -> new RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator();
348         };
349     }
350 
351     /**
352      * Creates a pinhole camera robust estimator based on point correspondences
353      * and using provided 2D/3D points and robust estimator method.
354      *
355      * @param points3D list of 3D points used to estimate a pinhole camera.
356      * @param points2D list of corresponding projected 2D points used to
357      *                 estimate a pinhole camera.
358      * @param method   method of a robust estimator algorithm to estimate the best
359      *                 pinhole camera.
360      * @return an instance of a pinhole camera robust estimator.
361      * @throws IllegalArgumentException if provided lists of points don't have
362      *                                  the same size or their size is smaller than required minimum size (6
363      *                                  correspondences).
364      */
365     public static UPnPPointCorrespondencePinholeCameraRobustEstimator create(
366             final List<Point3D> points3D, final List<Point2D> points2D, final RobustEstimatorMethod method) {
367         return switch (method) {
368             case LMEDS -> new LMedSUPnPPointCorrespondencePinholeCameraRobustEstimator(points3D, points2D);
369             case MSAC -> new MSACUPnPPointCorrespondencePinholeCameraRobustEstimator(points3D, points2D);
370             case PROSAC -> new PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator(points3D, points2D);
371             case PROMEDS -> new PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator(points3D, points2D);
372             default -> new RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator(points3D, points2D);
373         };
374     }
375 
376     /**
377      * Creates a pinhole camera robust estimator based on point correspondences
378      * and using provided listener.
379      *
380      * @param listener listener to be notified of events such as when estimation
381      *                 starts, ends or its progress significantly changes.
382      * @param method   method of a robust estimator algorithm to estimate the best
383      *                 pinhole camera.
384      * @return an instance of a pinhole camera robust estimator.
385      */
386     public static UPnPPointCorrespondencePinholeCameraRobustEstimator create(
387             final PinholeCameraRobustEstimatorListener listener, final RobustEstimatorMethod method) {
388         return switch (method) {
389             case LMEDS -> new LMedSUPnPPointCorrespondencePinholeCameraRobustEstimator(listener);
390             case MSAC -> new MSACUPnPPointCorrespondencePinholeCameraRobustEstimator(listener);
391             case PROSAC -> new PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator(listener);
392             case PROMEDS -> new PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator(listener);
393             default -> new RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator(listener);
394         };
395     }
396 
397     /**
398      * Creates a pinhole camera robust estimator based on point correspondences
399      * and using provided listener, 2D/3D points and robust estimator method.
400      *
401      * @param listener listener to be notified of events such as when estimation
402      *                 starts, ends or its progress significantly changes.
403      * @param points3D list of 3D points used to estimate a pinhole camera.
404      * @param points2D list of corresponding projected 2D points used to
405      *                 estimate a pinhole camera.
406      * @param method   method of a robust estimator algorithm to estimate the best
407      *                 pinhole camera.
408      * @return an instance of a pinhole camera robust estimator.
409      * @throws IllegalArgumentException if provided lists of points don't have
410      *                                  the same size or their size is smaller than required minimum size (6
411      *                                  correspondences).
412      */
413     public static UPnPPointCorrespondencePinholeCameraRobustEstimator create(
414             final PinholeCameraRobustEstimatorListener listener,
415             final List<Point3D> points3D, final List<Point2D> points2D, final RobustEstimatorMethod method) {
416         return switch (method) {
417             case LMEDS -> new LMedSUPnPPointCorrespondencePinholeCameraRobustEstimator(listener, points3D, points2D);
418             case MSAC -> new MSACUPnPPointCorrespondencePinholeCameraRobustEstimator(listener, points3D, points2D);
419             case PROSAC -> new PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator(listener, points3D, points2D);
420             case PROMEDS -> new PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator(
421                     listener, points3D, points2D);
422             default -> new RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator(listener, points3D, points2D);
423         };
424     }
425 
426     /**
427      * Creates a pinhole camera robust estimator based on point correspondences
428      * and using provided quality scores and robust estimator method.
429      *
430      * @param qualityScores quality scores corresponding to each pair of matched
431      *                      points.
432      * @param method        method of a robust estimator algorithm to estimate the best
433      *                      pinhole camera.
434      * @return an instance of a pinhole camera robust estimator.
435      * @throws IllegalArgumentException if provided quality scores length is
436      *                                  smaller than required minimum size (6 samples).
437      */
438     public static UPnPPointCorrespondencePinholeCameraRobustEstimator create(
439             final double[] qualityScores, final RobustEstimatorMethod method) {
440         return switch (method) {
441             case LMEDS -> new LMedSUPnPPointCorrespondencePinholeCameraRobustEstimator();
442             case MSAC -> new MSACUPnPPointCorrespondencePinholeCameraRobustEstimator();
443             case PROSAC -> new PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator(qualityScores);
444             case PROMEDS -> new PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator(qualityScores);
445             default -> new RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator();
446         };
447     }
448 
449     /**
450      * Creates a pinhole camera robust estimator based on point correspondences
451      * and using provided 2D/3D points, quality scores and robust estimator
452      * method.
453      *
454      * @param points3D      list of 3D points used to estimate a pinhole camera.
455      * @param points2D      list of corresponding projected 2D points used to
456      *                      estimate a pinhole camera.
457      * @param qualityScores quality scores corresponding to each pair of matched
458      *                      points.
459      * @param method        method of a robust estimator algorithm to estimate the best
460      *                      pinhole camera.
461      * @return an instance of a pinhole camera robust estimator.
462      * @throws IllegalArgumentException if provided lists of points and quality
463      *                                  scores don't have the same size or their size is smaller than required
464      *                                  minimum size (6 correspondences).
465      */
466     public static UPnPPointCorrespondencePinholeCameraRobustEstimator create(
467             final List<Point3D> points3D, final List<Point2D> points2D,
468             final double[] qualityScores, final RobustEstimatorMethod method) {
469         return switch (method) {
470             case LMEDS -> new LMedSUPnPPointCorrespondencePinholeCameraRobustEstimator(points3D, points2D);
471             case MSAC -> new MSACUPnPPointCorrespondencePinholeCameraRobustEstimator(points3D, points2D);
472             case PROSAC -> new PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator(
473                     points3D, points2D, qualityScores);
474             case PROMEDS -> new PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator(
475                     points3D, points2D, qualityScores);
476             default -> new RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator(points3D, points2D);
477         };
478     }
479 
480     /**
481      * Creates a pinhole camera robust estimator based on point correspondences
482      * and using provided listener and quality scores.
483      *
484      * @param listener      listener to be notified of events such as when estimation
485      *                      starts, ends or its progress significantly changes.
486      * @param qualityScores quality scores corresponding to each pair of matched
487      *                      points.
488      * @param method        method of a robust estimator algorithm to estimate the best
489      *                      pinhole camera.
490      * @return an instance of a pinhole camera robust estimator.
491      * @throws IllegalArgumentException if provided quality scores don't have
492      *                                  the required minimum size (6 correspondences).
493      */
494     public static UPnPPointCorrespondencePinholeCameraRobustEstimator create(
495             final PinholeCameraRobustEstimatorListener listener, final double[] qualityScores,
496             final RobustEstimatorMethod method) {
497         return switch (method) {
498             case LMEDS -> new LMedSUPnPPointCorrespondencePinholeCameraRobustEstimator(listener);
499             case MSAC -> new MSACUPnPPointCorrespondencePinholeCameraRobustEstimator(listener);
500             case PROSAC -> new PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator(listener, qualityScores);
501             case PROMEDS -> new PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator(listener, qualityScores);
502             default -> new RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator(listener);
503         };
504     }
505 
506     /**
507      * Creates a pinhole camera robust estimator based on point correspondences
508      * and using provided listener, 2D/3D points, quality scores and robust
509      * estimator method.
510      *
511      * @param listener      listener to be notified of events such as when estimation
512      *                      starts, ends or its progress significantly changes.
513      * @param points3D      list of 3D points used to estimate a pinhole camera.
514      * @param points2D      list of corresponding projected 2D points used to
515      *                      estimate a pinhole camera.
516      * @param qualityScores quality scores corresponding to each pair of matched
517      *                      points.
518      * @param method        method of a robust estimator algorithm to estimate the best
519      *                      pinhole camera.
520      * @return an instance of a pinhole camera robust estimator.
521      * @throws IllegalArgumentException if provided lists of points and quality
522      *                                  scores don't have the same size or their size is smaller than required
523      *                                  minimum size (6 correspondences).
524      */
525     public static UPnPPointCorrespondencePinholeCameraRobustEstimator create(
526             final PinholeCameraRobustEstimatorListener listener,
527             final List<Point3D> points3D, final List<Point2D> points2D, final double[] qualityScores,
528             final RobustEstimatorMethod method) {
529         return switch (method) {
530             case LMEDS -> new LMedSUPnPPointCorrespondencePinholeCameraRobustEstimator(listener, points3D, points2D);
531             case MSAC -> new MSACUPnPPointCorrespondencePinholeCameraRobustEstimator(listener, points3D, points2D);
532             case PROSAC -> new PROSACUPnPPointCorrespondencePinholeCameraRobustEstimator(
533                     listener, points3D, points2D, qualityScores);
534             case PROMEDS -> new PROMedSUPnPPointCorrespondencePinholeCameraRobustEstimator(
535                     listener, points3D, points2D, qualityScores);
536             default -> new RANSACUPnPPointCorrespondencePinholeCameraRobustEstimator(listener, points3D, points2D);
537         };
538     }
539 
540     /**
541      * Creates a pinhole camera robust estimator based on point correspondences
542      * and using default robust estimator method.
543      *
544      * @return an instance of a pinhole camera robust estimator.
545      */
546     public static UPnPPointCorrespondencePinholeCameraRobustEstimator create() {
547         return create(DEFAULT_ROBUST_METHOD);
548     }
549 
550     /**
551      * Creates a pinhole camera robust estimator based on point correspondences
552      * and using provided 2D/3D points and default robust estimator method.
553      *
554      * @param points3D list of 3D points used to estimate a pinhole camera.
555      * @param points2D list of corresponding projected 2D points used to
556      *                 estimate a pinhole camera.
557      * @return an instance of a pinhole camera robust estimator.
558      * @throws IllegalArgumentException if provided lists of points don't have
559      *                                  the same size or their size is smaller than required minimum size
560      *                                  (6 correspondences).
561      */
562     public static UPnPPointCorrespondencePinholeCameraRobustEstimator create(
563             final List<Point3D> points3D, final List<Point2D> points2D) {
564         return create(points3D, points2D, DEFAULT_ROBUST_METHOD);
565     }
566 
567     /**
568      * Creates a pinhole camera robust estimator based on point
569      * correspondences and using provided listener and default robust estimator
570      * method.
571      *
572      * @param listener listener to be notified of events such as when estimation
573      *                 starts, ends or its progress significantly changes.
574      * @return an instance of a pinhole camera robust estimator.
575      */
576     public static UPnPPointCorrespondencePinholeCameraRobustEstimator create(
577             final PinholeCameraRobustEstimatorListener listener) {
578         return create(listener, DEFAULT_ROBUST_METHOD);
579     }
580 
581     /**
582      * Creates a pinhole camera robust estimator based on point correspondences
583      * and using provided listener, 2D/3D points and default robust estimator
584      * method.
585      *
586      * @param listener listener to be notified of events such as when estimation
587      *                 starts, ends or its progress significantly changes.
588      * @param points3D list of 3D points used to estimate a pinhole camera.
589      * @param points2D list of corresponding projected 2D points used to
590      *                 estimate a pinhole camera.
591      * @return an instance of a pinhole camera robust estimator.
592      * @throws IllegalArgumentException if provided lists of points don't have
593      *                                  the same size or their size is smaller than required minimum size
594      *                                  (6 correspondences).
595      */
596     public static UPnPPointCorrespondencePinholeCameraRobustEstimator create(
597             final PinholeCameraRobustEstimatorListener listener,
598             final List<Point3D> points3D, final List<Point2D> points2D) {
599         return create(listener, points3D, points2D, DEFAULT_ROBUST_METHOD);
600     }
601 
602     /**
603      * Creates a pinhole camera robust estimator based on point correspondences
604      * and using provided quality scores and default robust estimator method.
605      *
606      * @param qualityScores quality scores corresponding to each pair of matched
607      *                      points.
608      * @return an instance of a pinhole camera robust estimator.
609      * @throws IllegalArgumentException if provided quality scores length is
610      *                                  smaller than required minimum size (6 samples).
611      */
612     public static UPnPPointCorrespondencePinholeCameraRobustEstimator create(final double[] qualityScores) {
613         return create(qualityScores, DEFAULT_ROBUST_METHOD);
614     }
615 
616     /**
617      * Creates a pinhole camera robust estimator based on point correspondences
618      * and using provided 2D/3D points, quality scores and default robust
619      * estimator method.
620      *
621      * @param points3D      list of 3D points used to estimate a pinhole camera.
622      * @param points2D      list of corresponding projected 2D points used to
623      *                      estimate a pinhole camera.
624      * @param qualityScores quality scores corresponding to each pair of matched
625      *                      points.
626      * @return an instance of a pinhole camera robust estimator.
627      * @throws IllegalArgumentException if provided lists of points and quality
628      *                                  scores don't have the same size or their size is smaller than required
629      *                                  minimum size (6 correspondences).
630      */
631     public static UPnPPointCorrespondencePinholeCameraRobustEstimator create(
632             final List<Point3D> points3D, final List<Point2D> points2D, final double[] qualityScores) {
633         return create(points3D, points2D, qualityScores, DEFAULT_ROBUST_METHOD);
634     }
635 
636     /**
637      * Creates a pinhole camera robust estimator based on point
638      * correspondences and using provided listener, quality scores and default
639      * robust estimator method.
640      *
641      * @param listener      listener to be notified of events such as when estimation
642      *                      starts, ends or its progress significantly changes.
643      * @param qualityScores quality scores corresponding to each pair of matched
644      *                      points.
645      * @return an instance of a pinhole camera robust estimator.
646      * @throws IllegalArgumentException if provided quality scores don't have
647      *                                  the required minimum size (6 correspondences).
648      */
649     public static UPnPPointCorrespondencePinholeCameraRobustEstimator create(
650             final PinholeCameraRobustEstimatorListener listener, final double[] qualityScores) {
651         return create(listener, qualityScores, DEFAULT_ROBUST_METHOD);
652     }
653 
654     /**
655      * Creates a pinhole camera robust estimator based on point correspondences
656      * and using provided listener, 2D/3D points, quality scores and default
657      * robust estimator method.
658      *
659      * @param listener      listener to be notified of events such as when estimation
660      *                      starts, ends or its progress significantly changes.
661      * @param points3D      list of 3D points used to estimate a pinhole camera.
662      * @param points2D      list of corresponding projected 2D points used to
663      *                      estimate a pinhole camera.
664      * @param qualityScores quality scores corresponding to each pair of matched
665      *                      points.
666      * @return an instance of a pinhole camera robust estimator.
667      * @throws IllegalArgumentException if provided lists of points and quality
668      *                                  scores don't have the same size or their size is smaller than required
669      *                                  minimum size (6 correspondences).
670      */
671     public static UPnPPointCorrespondencePinholeCameraRobustEstimator create(
672             final PinholeCameraRobustEstimatorListener listener,
673             final List<Point3D> points3D, final List<Point2D> points2D, final double[] qualityScores) {
674         return create(listener, points3D, points2D, qualityScores, DEFAULT_ROBUST_METHOD);
675     }
676 }