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.geometry.PinholeCamera;
19  import com.irurueta.geometry.PinholeCameraIntrinsicParameters;
20  import com.irurueta.geometry.Point2D;
21  import com.irurueta.geometry.Point3D;
22  import com.irurueta.geometry.refiners.DecomposedPointCorrespondencePinholeCameraRefiner;
23  import com.irurueta.geometry.refiners.NonDecomposedPointCorrespondencePinholeCameraRefiner;
24  import com.irurueta.numerical.robust.InliersData;
25  import com.irurueta.numerical.robust.RobustEstimatorMethod;
26  
27  import java.util.List;
28  
29  /**
30   * This is an abstract class for algorithms to robustly find the best pinhole
31   * camera for collections of matched 3D/2D points.
32   * Implementations of this class should be able to detect and discard outliers
33   * in order to find the best solution.
34   */
35  @SuppressWarnings("DuplicatedCode")
36  public abstract class PointCorrespondencePinholeCameraRobustEstimator extends PinholeCameraRobustEstimator {
37  
38      /**
39       * Minimum number of required point correspondences to estimate a pinhole
40       * camera.
41       */
42      public static final int MIN_NUMBER_OF_POINT_CORRESPONDENCES = 6;
43  
44      /**
45       * Indicates if by default point correspondences for each picked subset of
46       * samples is normalized to increase the accuracy of the estimation.
47       */
48      public static final boolean DEFAULT_NORMALIZE_SUBSET_POINT_CORRESPONDENCES = true;
49  
50      /**
51       * Default robust estimator method when none is provided.
52       */
53      public static final RobustEstimatorMethod DEFAULT_ROBUST_METHOD = RobustEstimatorMethod.PROMEDS;
54  
55      /**
56       * List of matched 3D points.
57       */
58      protected List<Point3D> points3D;
59  
60      /**
61       * List of matched 2D points.
62       */
63      protected List<Point2D> points2D;
64  
65      /**
66       * Indicates if each picked subset point correspondences are normalized to
67       * increase the accuracy of the estimation.
68       */
69      protected boolean normalizeSubsetPointCorrespondences;
70  
71      /**
72       * Constructor.
73       */
74      protected PointCorrespondencePinholeCameraRobustEstimator() {
75          super();
76          normalizeSubsetPointCorrespondences = DEFAULT_NORMALIZE_SUBSET_POINT_CORRESPONDENCES;
77      }
78  
79      /**
80       * Constructor with lists of points to be used to estimate a pinhole camera.
81       * Points in the lists located at the same position are considered to be
82       * matched. Hence, both lists must have the same size, and their size must
83       * be greater or equal than MIN_NUMBER_OF_POINT_CORRESPONDENCES (6 points).
84       *
85       * @param points3D list of 3D points used to estimate a pinhole camera.
86       * @param points2D list of corresponding projected 2D points used to
87       *                 estimate a pinhole camera.
88       * @throws IllegalArgumentException if provided lists of points don't have
89       *                                  the same size or their size is smaller than required minimum size
90       *                                  (6 correspondences).
91       */
92      protected PointCorrespondencePinholeCameraRobustEstimator(
93              final List<Point3D> points3D, final List<Point2D> points2D) {
94          super();
95          normalizeSubsetPointCorrespondences = DEFAULT_NORMALIZE_SUBSET_POINT_CORRESPONDENCES;
96          internalSetPoints(points3D, points2D);
97      }
98  
99      /**
100      * Constructor with listener.
101      *
102      * @param listener listener to be notified of events such as when estimation
103      *                 starts, ends or its progress significantly changes.
104      */
105     protected PointCorrespondencePinholeCameraRobustEstimator(final PinholeCameraRobustEstimatorListener listener) {
106         super(listener);
107         normalizeSubsetPointCorrespondences = DEFAULT_NORMALIZE_SUBSET_POINT_CORRESPONDENCES;
108     }
109 
110     /**
111      * Constructor with listener and lists of points to be used to estimate a
112      * pinhole camera.
113      * Points in the lists located at the same position are considered to be
114      * matched. Hence, both lists must have the same size, and their size must
115      * be greater or equal than MIN_NUMBER_OF_POINT_CORRESPONDENCES (6 points).
116      *
117      * @param listener listener to be notified of events such as when estimation
118      *                 starts, ends or its progress significantly changes.
119      * @param points3D list of 3D points used to estimate a pinhole camera.
120      * @param points2D list of corresponding projected 2D points used to
121      *                 estimate a pinhole camera.
122      * @throws IllegalArgumentException if provided lists of points don't have
123      *                                  the same size or their size is smaller than required minimum size
124      *                                  (6 correspondences).
125      */
126     protected PointCorrespondencePinholeCameraRobustEstimator(
127             final PinholeCameraRobustEstimatorListener listener,
128             final List<Point3D> points3D, final List<Point2D> points2D) {
129         super(listener);
130         normalizeSubsetPointCorrespondences = DEFAULT_NORMALIZE_SUBSET_POINT_CORRESPONDENCES;
131         internalSetPoints(points3D, points2D);
132     }
133 
134     /**
135      * Returns list of 3D points to be used to estimate a pinhole camera.
136      * Each point in the list of 3D points must be matched with the
137      * corresponding 2D point in the list of projected 2D points located at the
138      * same position. Hence, both 2D and 3D points lists must have the same
139      * size, and their size must be greater or equal than
140      * MIN_NUMBER_OF_POINT_CORRESPONDENCES (6 points).
141      *
142      * @return list of 3D points to be used to estimate a pinhole camera.
143      */
144     public List<Point3D> getPoints3D() {
145         return points3D;
146     }
147 
148     /**
149      * Returns list of 2D points ot be used to estimate a pinhole camera.
150      * Each point in the list of 2D points must be matched with the
151      * corresponding 3D point in the list of 3D points that can be projected
152      * into a 2D point using a pinhole camera. Hence, both 2D and 3D points
153      * lists must have the same size, and their size must be greater or equal
154      * than MIN_NUMBER_OF_POINT_CORRESPONDENCES (6 points).
155      *
156      * @return list of 2D points to be used to estimate a pinhole camera.
157      */
158     public List<Point2D> getPoints2D() {
159         return points2D;
160     }
161 
162     /**
163      * Sets lists of 3D/2D points to be used to estimate a pinhole camera.
164      * Points in the list located at the same position are considered to be
165      * matched. Hence, both lists must have the same size, and their size must
166      * be greater or equal than MIN_NUMBER_OF_POINT_CORRESPONDENCES.
167      *
168      * @param points3D list of 3D points used to estimate a pinhole camera.
169      * @param points2D list of corresponding projected 2D points used to
170      *                 estimate a pinhole camera.
171      * @throws IllegalArgumentException if provided lists of points don't have
172      *                                  the same size or their size is smaller than required minimum size
173      *                                  (6 correspondences).
174      * @throws LockedException          if estimator is locked because a computation is
175      *                                  already in progress.
176      */
177     public final void setPoints(final List<Point3D> points3D, final List<Point2D> points2D) throws LockedException {
178         if (isLocked()) {
179             throw new LockedException();
180         }
181         internalSetPoints(points3D, points2D);
182     }
183 
184     /**
185      * Indicates if estimator is ready to start the pinhole camera estimation.
186      * This is true when input data (i.e. lists of 2D/3D matched points) are
187      * provided and a minimum of MIN_NUMBER_OF_POINT_CORRESPONDENCES are
188      * available.
189      *
190      * @return true if estimator is ready, false otherwise.
191      */
192     public boolean isReady() {
193         return points3D != null && points2D != null && points3D.size() == points2D.size()
194                 && points3D.size() >= MIN_NUMBER_OF_POINT_CORRESPONDENCES;
195     }
196 
197     /**
198      * Returns quality scores corresponding to each pair of matched points.
199      * The larger the score value the better the quality of the matching.
200      * This implementation always returns null.
201      * Subclasses using quality scores must implement proper behaviour.
202      *
203      * @return quality scores corresponding to each pair of matched points.
204      */
205     public double[] getQualityScores() {
206         return null;
207     }
208 
209     /**
210      * Sets quality scores corresponding to each pair of matched points.
211      * The larger the score value the better the quality of the matching.
212      * This implementation makes no action.
213      * Subclasses using quality scores must implement proper behaviour.
214      *
215      * @param qualityScores quality scores corresponding to each pair of matched
216      *                      points.
217      * @throws LockedException          if robust estimator is locked because an
218      *                                  estimation is already in progress.
219      * @throws IllegalArgumentException if provided quality scores length is
220      *                                  smaller than MIN_NUMBER_OF_POINT_CORRESPONDENCES (i.e. 6 samples).
221      */
222     public void setQualityScores(final double[] qualityScores) throws LockedException {
223     }
224 
225     /**
226      * Returns value indicating if each picked subset point correspondences are
227      * normalized to increase the accuracy of the estimation.
228      *
229      * @return true if each picked subset point correspondences are normalized,
230      * false otherwise.
231      */
232     public boolean isNormalizeSubsetPointCorrespondences() {
233         return normalizeSubsetPointCorrespondences;
234     }
235 
236     /**
237      * Sets value indicating if each picked subset point correspondences are
238      * normalized to increase the accuracy of the estimation.
239      *
240      * @param normalizeSubsetPointCorrespondences true if each picked subset
241      *                                            point correspondences are normalized, false otherwise.
242      * @throws LockedException if robust estimator is locked because an
243      *                         estimation is already in progress.
244      */
245     public void setNormalizeSubsetPointCorrespondences(final boolean normalizeSubsetPointCorrespondences)
246             throws LockedException {
247         if (isLocked()) {
248             throw new LockedException();
249         }
250         this.normalizeSubsetPointCorrespondences = normalizeSubsetPointCorrespondences;
251     }
252 
253     /**
254      * Creates a pinhole camera robust estimator based on point correspondences
255      * and using provided robust estimator method + DLT.
256      *
257      * @param method method of a robust estimator algorithm to estimate the best
258      *               pinhole camera.
259      * @return an instance of a pinhole camera robust estimator.
260      */
261     public static PointCorrespondencePinholeCameraRobustEstimator create(final RobustEstimatorMethod method) {
262         return DLTPointCorrespondencePinholeCameraRobustEstimator.create(method);
263     }
264 
265     /**
266      * Creates a pinhole camera robust estimator based on point correspondences
267      * and using provided 2D/3D points and robust estimator method + DLT.
268      *
269      * @param points3D list of 3D points used to estimate a pinhole camera.
270      * @param points2D list of corresponding projected 2D points used to
271      *                 estimate a pinhole camera.
272      * @param method   method of a robust estimator algorithm to estimate the best
273      *                 pinhole camera.
274      * @return an instance of a pinhole camera robust estimator.
275      * @throws IllegalArgumentException if provided lists of points don't have
276      *                                  the same size or their size is smaller than required minimum size
277      *                                  (6 correspondences).
278      */
279     public static PointCorrespondencePinholeCameraRobustEstimator create(
280             final List<Point3D> points3D, final List<Point2D> points2D, final RobustEstimatorMethod method) {
281         return DLTPointCorrespondencePinholeCameraRobustEstimator.create(points3D, points2D, method);
282     }
283 
284     /**
285      * Creates a pinhole camera robust estimator based on point
286      * correspondences and using provided listener and robust estimator method
287      * + DLT.
288      *
289      * @param listener listener to be notified of events such as when estimation
290      *                 starts, ends or its progress significantly changes.
291      * @param method   method of a robust estimator algorithm to estimate the best
292      *                 pinhole camera.
293      * @return an instance of a pinhole camera robust estimator.
294      */
295     public static PointCorrespondencePinholeCameraRobustEstimator create(
296             final PinholeCameraRobustEstimatorListener listener, final RobustEstimatorMethod method) {
297         return DLTPointCorrespondencePinholeCameraRobustEstimator.create(listener, method);
298     }
299 
300     /**
301      * Creates a pinhole camera robust estimator based on point correspondences
302      * and using provided listener, 2D/3D points and robust estimator method +
303      * DLT.
304      *
305      * @param listener listener to be notified of events such as when estimation
306      *                 starts, ends or its progress significantly changes.
307      * @param points3D list of 3D points used to estimate a pinhole camera.
308      * @param points2D list of corresponding projected 2D points used to
309      *                 estimate a pinhole camera.
310      * @param method   method of a robust estimator algorithm to estimate the best
311      *                 pinhole camera.
312      * @return an instance of a pinhole camera robust estimator.
313      * @throws IllegalArgumentException if provided lists of points don't have
314      *                                  the same size or their size is smaller than required minimum size
315      *                                  (6 correspondences).
316      */
317     public static PointCorrespondencePinholeCameraRobustEstimator create(
318             final PinholeCameraRobustEstimatorListener listener, final List<Point3D> points3D,
319             final List<Point2D> points2D, final RobustEstimatorMethod method) {
320         return DLTPointCorrespondencePinholeCameraRobustEstimator.create(listener, points3D, points2D, method);
321     }
322 
323     /**
324      * Creates a pinhole camera robust estimator based on point correspondences
325      * and using provided quality scores and robust estimator method + DLT.
326      *
327      * @param qualityScores quality scores corresponding to each pair of matched
328      *                      points.
329      * @param method        method of a robust estimator algorithm to estimate the best
330      *                      pinhole camera.
331      * @return an instance of a pinhole camera robust estimator.
332      * @throws IllegalArgumentException if provided quality scores length is
333      *                                  smaller than required minimum size (6 samples).
334      */
335     public static PointCorrespondencePinholeCameraRobustEstimator create(
336             final double[] qualityScores, final RobustEstimatorMethod method) {
337         return DLTPointCorrespondencePinholeCameraRobustEstimator.create(qualityScores, method);
338     }
339 
340     /**
341      * Creates a pinhole camera robust estimator based on point correspondences
342      * and using provided 2D/3D points, quality scores and robust estimator
343      * method + DLT.
344      *
345      * @param points3D      list of 3D points used to estimate a pinhole camera.
346      * @param points2D      list of corresponding projected 2D points used to
347      *                      estimate a pinhole camera.
348      * @param qualityScores quality scores corresponding to each pair of matched
349      *                      points.
350      * @param method        method of a robust estimator algorithm to estimate the best
351      *                      pinhole camera.
352      * @return an instance of a pinhole camera robust estimator.
353      * @throws IllegalArgumentException if provided lists of points and quality
354      *                                  scores don't have the same size or their size is smaller than required
355      *                                  minimum size (6 correspondences).
356      */
357     public static PointCorrespondencePinholeCameraRobustEstimator create(
358             final List<Point3D> points3D, final List<Point2D> points2D, final double[] qualityScores,
359             final RobustEstimatorMethod method) {
360         return DLTPointCorrespondencePinholeCameraRobustEstimator.create(points3D, points2D, qualityScores, method);
361     }
362 
363     /**
364      * Creates a pinhole camera robust estimator based on point
365      * correspondences and using provided listener and quality scores and robust
366      * estimator method + DLT.
367      *
368      * @param listener      listener to be notified of events such as when estimation
369      *                      starts, ends or its progress significantly changes.
370      * @param qualityScores quality scores corresponding to each pair of matched
371      *                      points.
372      * @param method        method of a robust estimator algorithm to estimate the best
373      *                      pinhole camera.
374      * @return an instance of a pinhole camera robust estimator.
375      * @throws IllegalArgumentException if provided quality scores don't have
376      *                                  the required minimum size (6 correspondences).
377      */
378     public static PointCorrespondencePinholeCameraRobustEstimator create(
379             final PinholeCameraRobustEstimatorListener listener, final double[] qualityScores,
380             final RobustEstimatorMethod method) {
381         return DLTPointCorrespondencePinholeCameraRobustEstimator.create(listener, qualityScores, method);
382     }
383 
384     /**
385      * Creates a pinhole camera robust estimator based on point correspondences
386      * and using provided listener, 2D/3D points, quality scores and robust
387      * estimator method + DLT.
388      *
389      * @param listener      listener to be notified of events such as when estimation
390      *                      starts, ends or its progress significantly changes.
391      * @param points3D      list of 3D points used to estimate a pinhole camera.
392      * @param points2D      list of corresponding projected 2D points used to
393      *                      estimate a pinhole camera.
394      * @param qualityScores quality scores corresponding to each pair of matched
395      *                      points.
396      * @param method        method of a robust estimator algorithm to estimate the best
397      *                      pinhole camera.
398      * @return an instance of a pinhole camera robust estimator.
399      * @throws IllegalArgumentException if provided lists of points and quality
400      *                                  scores don't have the same size or their size is smaller than required
401      *                                  minimum size (6 correspondences).
402      */
403     public static PointCorrespondencePinholeCameraRobustEstimator create(
404             final PinholeCameraRobustEstimatorListener listener, final List<Point3D> points3D,
405             final List<Point2D> points2D, final double[] qualityScores, final RobustEstimatorMethod method) {
406         return DLTPointCorrespondencePinholeCameraRobustEstimator.create(listener, points3D, points2D, qualityScores,
407                 method);
408     }
409 
410     /**
411      * Creates a pinhole camera robust estimator based on point correspondences
412      * and using provided robust estimator method + EPnP.
413      *
414      * @param intrinsic intrinsic parameters of camera to be estimated.
415      * @param method    method of a robust estimator algorithm to estimate the best
416      *                  pinhole camera.
417      * @return an instance of a pinhole camera robust estimator.
418      */
419     public static PointCorrespondencePinholeCameraRobustEstimator create(
420             final PinholeCameraIntrinsicParameters intrinsic, final RobustEstimatorMethod method) {
421         return EPnPPointCorrespondencePinholeCameraRobustEstimator.create(intrinsic, method);
422     }
423 
424     /**
425      * Creates a pinhole camera robust estimator based on point correspondences
426      * and using provided 2D/3D points and robust estimator method + EPnP.
427      *
428      * @param intrinsic intrinsic parameters of camera to be estimated.
429      * @param points3D  list of 3D points used to estimate a pinhole camera.
430      * @param points2D  list of corresponding projected 2D points used to
431      *                  estimate a pinhole camera.
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 lists of points don't have
436      *                                  the same size or their size is smaller than required minimum size
437      *                                  (6 correspondences).
438      */
439     public static PointCorrespondencePinholeCameraRobustEstimator create(
440             final PinholeCameraIntrinsicParameters intrinsic, final List<Point3D> points3D,
441             final List<Point2D> points2D, final RobustEstimatorMethod method) {
442         return EPnPPointCorrespondencePinholeCameraRobustEstimator.create(intrinsic, points3D, points2D, method);
443     }
444 
445     /**
446      * Creates a pinhole camera robust estimator based on point
447      * correspondences and using provided listener and robust estimator method
448      * + EPnP.
449      *
450      * @param listener  listener to be notified of events such as when estimation
451      *                  starts, ends or its progress significantly changes.
452      * @param intrinsic intrinsic parameters of camera to be estimated.
453      * @param method    method of a robust estimator algorithm to estimate the best
454      *                  pinhole camera.
455      * @return an instance of a pinhole camera robust estimator.
456      */
457     public static PointCorrespondencePinholeCameraRobustEstimator create(
458             final PinholeCameraRobustEstimatorListener listener, final PinholeCameraIntrinsicParameters intrinsic,
459             final RobustEstimatorMethod method) {
460         return EPnPPointCorrespondencePinholeCameraRobustEstimator.create(listener, intrinsic, method);
461     }
462 
463     /**
464      * Creates a pinhole camera robust estimator based on point correspondences
465      * and using provided listener, 2D/3D points and robust estimator method +
466      * EPnP.
467      *
468      * @param listener  listener to be notified of events such as when estimation
469      *                  starts, ends or its progress significantly changes.
470      * @param intrinsic intrinsic parameters of camera to be estimated.
471      * @param points3D  list of 3D points used to estimate a pinhole camera.
472      * @param points2D  list of corresponding projected 2D points used to
473      *                  estimate a pinhole camera.
474      * @param method    method of a robust estimator algorithm to estimate the best
475      *                  pinhole camera.
476      * @return an instance of a pinhole camera robust estimator.
477      * @throws IllegalArgumentException if provided lists of points don't have
478      *                                  the same size or their size is smaller than required minimum size
479      *                                  (6 correspondences).
480      */
481     public static PointCorrespondencePinholeCameraRobustEstimator create(
482             final PinholeCameraRobustEstimatorListener listener, final PinholeCameraIntrinsicParameters intrinsic,
483             final List<Point3D> points3D, final List<Point2D> points2D, final RobustEstimatorMethod method) {
484         return EPnPPointCorrespondencePinholeCameraRobustEstimator.create(listener, intrinsic, points3D, points2D,
485                 method);
486     }
487 
488     /**
489      * Creates a pinhole camera robust estimator based on point correspondences
490      * and using provided quality scores and robust estimator method + EPnP.
491      *
492      * @param intrinsic     intrinsic parameters of camera to be estimated.
493      * @param qualityScores quality scores corresponding to each pair of matched
494      *                      points.
495      * @param method        method of a robust estimator algorithm to estimate the best
496      *                      pinhole camera.
497      * @return an instance of a pinhole camera robust estimator.
498      * @throws IllegalArgumentException if provided quality scores length is
499      *                                  smaller than required minimum size (6 samples).
500      */
501     public static PointCorrespondencePinholeCameraRobustEstimator create(
502             final PinholeCameraIntrinsicParameters intrinsic, final double[] qualityScores,
503             final RobustEstimatorMethod method) {
504         return EPnPPointCorrespondencePinholeCameraRobustEstimator.create(intrinsic, qualityScores, method);
505     }
506 
507     /**
508      * Creates a pinhole camera robust estimator based on point correspondences
509      * and using provided 2D/3D points, quality scores and robust estimator
510      * method + EPnP.
511      *
512      * @param intrinsic     intrinsic parameters of camera to be estimated.
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 PointCorrespondencePinholeCameraRobustEstimator create(
526             final PinholeCameraIntrinsicParameters intrinsic, final List<Point3D> points3D,
527             final List<Point2D> points2D, final double[] qualityScores, final RobustEstimatorMethod method) {
528         return EPnPPointCorrespondencePinholeCameraRobustEstimator.create(intrinsic, points3D, points2D, qualityScores,
529                 method);
530     }
531 
532     /**
533      * Creates a pinhole camera robust estimator based on point
534      * correspondences and using provided listener and quality scores and
535      * a robust estimation method + EPnP.
536      *
537      * @param listener      listener to be notified of events such as when estimation
538      *                      starts, ends or its progress significantly changes.
539      * @param intrinsic     intrinsic parameters of camera to be estimated.
540      * @param qualityScores quality scores corresponding to each pair of matched
541      *                      points.
542      * @param method        method of a robust estimator algorithm to estimate the best
543      *                      pinhole camera.
544      * @return an instance of a pinhole camera robust estimator.
545      * @throws IllegalArgumentException if provided quality scores don't have
546      *                                  the required minimum size (6 correspondences).
547      */
548     public static PointCorrespondencePinholeCameraRobustEstimator create(
549             final PinholeCameraRobustEstimatorListener listener, final PinholeCameraIntrinsicParameters intrinsic,
550             final double[] qualityScores, final RobustEstimatorMethod method) {
551         return EPnPPointCorrespondencePinholeCameraRobustEstimator.create(listener, intrinsic, qualityScores, method);
552     }
553 
554     /**
555      * Creates a pinhole camera robust estimator based on point correspondences
556      * and using provided listener, 2D/3D points, quality scores and robust
557      * estimator method + EPnP.
558      *
559      * @param listener      listener to be notified of events such as when estimation
560      *                      starts, ends or its progress significantly changes.
561      * @param intrinsic     intrinsic parameters of camera to be estimated.
562      * @param points3D      list of 3D points used to estimate a pinhole camera.
563      * @param points2D      list of corresponding projected 2D points used to
564      *                      estimate a pinhole camera.
565      * @param qualityScores quality scores corresponding to each pair of matched
566      *                      points.
567      * @param method        method of a robust estimator algorithm to estimate the best
568      *                      pinhole camera.
569      * @return an instance of a pinhole camera robust estimator.
570      * @throws IllegalArgumentException if provided lists of points and quality
571      *                                  scores don't have the same size or their size is smaller than required
572      *                                  minimum size (6 correspondences).
573      */
574     public static PointCorrespondencePinholeCameraRobustEstimator create(
575             final PinholeCameraRobustEstimatorListener listener, final PinholeCameraIntrinsicParameters intrinsic,
576             final List<Point3D> points3D, final List<Point2D> points2D, final double[] qualityScores,
577             final RobustEstimatorMethod method) {
578         return EPnPPointCorrespondencePinholeCameraRobustEstimator.create(listener, intrinsic, points3D, points2D,
579                 qualityScores, method);
580     }
581 
582     /**
583      * Creates a pinhole camera robust estimator based on point correspondences
584      * and using provided robust estimator method + UPnP.
585      *
586      * @param skewness                 skewness value of intrinsic parameters of camera to be
587      *                                 estimated.
588      * @param horizontalPrincipalPoint horizontal principal point value of
589      *                                 intrinsic parameters of camera to be estimated.
590      * @param verticalPrincipalPoint   vertical principal point value of
591      *                                 intrinsic parameters of camera to be estimated.
592      * @param method                   method of a robust estimator algorithm to estimate the best
593      *                                 pinhole camera.
594      * @return an instance of a pinhole camera robust estimator.
595      */
596     public static PointCorrespondencePinholeCameraRobustEstimator create(
597             final double skewness, final double horizontalPrincipalPoint, final double verticalPrincipalPoint,
598             final RobustEstimatorMethod method) {
599         final var estimator = UPnPPointCorrespondencePinholeCameraRobustEstimator.create(method);
600         try {
601             estimator.setSkewness(skewness);
602             estimator.setHorizontalPrincipalPoint(horizontalPrincipalPoint);
603             estimator.setVerticalPrincipalPoint(verticalPrincipalPoint);
604         } catch (final LockedException ignore) {
605             // ignore
606         }
607         return estimator;
608     }
609 
610     /**
611      * Creates a pinhole camera robust estimator based on point correspondences
612      * and using provided 2D/3D points and robust estimator method + UPnP.
613      *
614      * @param skewness                 skewness value of intrinsic parameters of camera to be
615      *                                 estimated.
616      * @param horizontalPrincipalPoint horizontal principal point value of
617      *                                 intrinsic parameters of camera to be estimated.
618      * @param verticalPrincipalPoint   vertical principal point value of
619      *                                 intrinsic parameters of camera to be estimated.
620      * @param points3D                 list of 3D points used to estimate a pinhole camera.
621      * @param points2D                 list of corresponding projected 2D points used to
622      *                                 estimate a pinhole camera.
623      * @param method                   method of a robust estimator algorithm to estimate the best
624      *                                 pinhole camera.
625      * @return an instance of a pinhole camera robust estimator.
626      * @throws IllegalArgumentException if provided lists of points don't have
627      *                                  the same size or their size is smaller than required minimum size
628      *                                  (6 correspondences).
629      */
630     public static PointCorrespondencePinholeCameraRobustEstimator create(
631             final double skewness, final double horizontalPrincipalPoint, final double verticalPrincipalPoint,
632             final List<Point3D> points3D, final List<Point2D> points2D, final RobustEstimatorMethod method) {
633         final var estimator = UPnPPointCorrespondencePinholeCameraRobustEstimator.create(points3D, points2D, method);
634         try {
635             estimator.setSkewness(skewness);
636             estimator.setHorizontalPrincipalPoint(horizontalPrincipalPoint);
637             estimator.setVerticalPrincipalPoint(verticalPrincipalPoint);
638         } catch (final LockedException ignore) {
639             // ignore
640         }
641         return estimator;
642     }
643 
644     /**
645      * Creates a pinhole camera robust estimator based on point
646      * correspondences and using provided listener and robust method + UPnP.
647      *
648      * @param listener                 listener to be notified of events such as when estimation
649      *                                 starts, ends or its progress significantly changes.
650      * @param skewness                 skewness value of intrinsic parameters of camera to be
651      *                                 estimated.
652      * @param horizontalPrincipalPoint horizontal principal point value of
653      *                                 intrinsic parameters of camera to be estimated.
654      * @param verticalPrincipalPoint   vertical principal point value of
655      *                                 intrinsic parameters of camera to be estimated.
656      * @param method                   method of a robust estimator algorithm to estimate the best
657      *                                 pinhole camera.
658      * @return an instance of a pinhole camera robust estimator.
659      */
660     public static PointCorrespondencePinholeCameraRobustEstimator create(
661             final PinholeCameraRobustEstimatorListener listener, final double skewness,
662             final double horizontalPrincipalPoint, final double verticalPrincipalPoint,
663             final RobustEstimatorMethod method) {
664         final var estimator = UPnPPointCorrespondencePinholeCameraRobustEstimator.create(listener, method);
665         try {
666             estimator.setSkewness(skewness);
667             estimator.setHorizontalPrincipalPoint(horizontalPrincipalPoint);
668             estimator.setVerticalPrincipalPoint(verticalPrincipalPoint);
669         } catch (final LockedException ignore) {
670             // ignore
671         }
672         return estimator;
673     }
674 
675     /**
676      * Creates a pinhole camera robust estimator based on point correspondences
677      * and using provided listener, 2D/3D points and robust estimator method +
678      * UPnP.
679      *
680      * @param listener                 listener to be notified of events such as when estimation
681      *                                 starts, ends or its progress significantly changes.
682      * @param skewness                 skewness value of intrinsic parameters of camera to be
683      *                                 estimated.
684      * @param horizontalPrincipalPoint horizontal principal point value of
685      *                                 intrinsic parameters of camera to be estimated.
686      * @param verticalPrincipalPoint   vertical principal point value of
687      *                                 intrinsic parameters of camera to be estimated.
688      * @param points3D                 list of 3D points used to estimate a pinhole camera.
689      * @param points2D                 list of corresponding projected 2D points used to
690      *                                 estimate a pinhole camera.
691      * @param method                   method of a robust estimator algorithm to estimate the best
692      *                                 pinhole camera.
693      * @return an instance of a pinhole camera robust estimator.
694      * @throws IllegalArgumentException if provided lists of points don't have
695      *                                  the same size or their size is smaller than required minimum size
696      *                                  (6 correspondences).
697      */
698     public static PointCorrespondencePinholeCameraRobustEstimator create(
699             final PinholeCameraRobustEstimatorListener listener, final double skewness,
700             final double horizontalPrincipalPoint, final double verticalPrincipalPoint, final List<Point3D> points3D,
701             final List<Point2D> points2D, final RobustEstimatorMethod method) {
702         final var estimator = UPnPPointCorrespondencePinholeCameraRobustEstimator.create(listener, points3D, points2D,
703                 method);
704         try {
705             estimator.setSkewness(skewness);
706             estimator.setHorizontalPrincipalPoint(horizontalPrincipalPoint);
707             estimator.setVerticalPrincipalPoint(verticalPrincipalPoint);
708         } catch (final LockedException ignore) {
709             // ignore
710         }
711         return estimator;
712     }
713 
714     /**
715      * Creates a pinhole camera robust estimator based on point correspondences
716      * and using provided quality scores and robust estimator method + UPnP.
717      *
718      * @param skewness                 skewness value of intrinsic parameters of camera to be
719      *                                 estimated.
720      * @param horizontalPrincipalPoint horizontal principal point value of
721      *                                 intrinsic parameters of camera to be estimated.
722      * @param verticalPrincipalPoint   vertical principal point value of
723      *                                 intrinsic parameters of camera to be estimated.
724      * @param qualityScores            quality scores corresponding to each pair of matched
725      *                                 points.
726      * @param method                   method of a robust estimator algorithm to estimate the best
727      *                                 pinhole camera.
728      * @return an instance of a pinhole camera robust estimator.
729      * @throws IllegalArgumentException if provided quality scores length is
730      *                                  smaller than required minimum size (6 samples).
731      */
732     public static PointCorrespondencePinholeCameraRobustEstimator create(
733             final double skewness, final double horizontalPrincipalPoint, final double verticalPrincipalPoint,
734             final double[] qualityScores, final RobustEstimatorMethod method) {
735         final var estimator = UPnPPointCorrespondencePinholeCameraRobustEstimator.create(qualityScores, method);
736         try {
737             estimator.setSkewness(skewness);
738             estimator.setHorizontalPrincipalPoint(horizontalPrincipalPoint);
739             estimator.setVerticalPrincipalPoint(verticalPrincipalPoint);
740         } catch (final LockedException ignore) {
741             // ignore
742         }
743         return estimator;
744     }
745 
746     /**
747      * Creates a pinhole camera robust estimator based on point correspondences
748      * and using provided 2D/3D points, quality scores and robust estimator
749      * method + UPnP.
750      *
751      * @param skewness                 skewness value of intrinsic parameters of camera to be
752      *                                 estimated.
753      * @param horizontalPrincipalPoint horizontal principal point value of
754      *                                 intrinsic parameters of camera to be estimated.
755      * @param verticalPrincipalPoint   vertical principal point value of
756      *                                 intrinsic parameters of camera to be estimated.
757      * @param points3D                 list of 3D points used to estimate a pinhole camera.
758      * @param points2D                 list of corresponding projected 2D points used to
759      *                                 estimate a pinhole camera.
760      * @param qualityScores            quality scores corresponding to each pair of matched
761      *                                 points.
762      * @param method                   method of a robust estimator algorithm to estimate the best
763      *                                 pinhole camera.
764      * @return an instance of a pinhole camera robust estimator.
765      * @throws IllegalArgumentException if provided lists of points and quality
766      *                                  scores don't have the same size or their size is smaller than required
767      *                                  minimum size (6 correspondences).
768      */
769     public static PointCorrespondencePinholeCameraRobustEstimator create(
770             final double skewness, final double horizontalPrincipalPoint, final double verticalPrincipalPoint,
771             final List<Point3D> points3D, final List<Point2D> points2D, final double[] qualityScores,
772             final RobustEstimatorMethod method) {
773         final var estimator = UPnPPointCorrespondencePinholeCameraRobustEstimator.create(points3D, points2D,
774                 qualityScores, method);
775         try {
776             estimator.setSkewness(skewness);
777             estimator.setHorizontalPrincipalPoint(horizontalPrincipalPoint);
778             estimator.setVerticalPrincipalPoint(verticalPrincipalPoint);
779         } catch (final LockedException ignore) {
780             // ignore
781         }
782         return estimator;
783     }
784 
785     /**
786      * Creates a pinhole camera robust estimator based on point
787      * correspondences and using provided listener and quality scores and robust
788      * method + UPnP.
789      *
790      * @param listener                 listener to be notified of events such as when estimation
791      *                                 starts, ends or its progress significantly changes.
792      * @param skewness                 skewness value of intrinsic parameters of camera to be
793      *                                 estimated.
794      * @param horizontalPrincipalPoint horizontal principal point value of
795      *                                 intrinsic parameters of camera to be estimated.
796      * @param verticalPrincipalPoint   vertical principal point value of
797      *                                 intrinsic parameters of camera to be estimated.
798      * @param qualityScores            quality scores corresponding to each pair of matched
799      *                                 points.
800      * @param method                   method of a robust estimator algorithm to estimate the best
801      *                                 pinhole camera.
802      * @return an instance of a pinhole camera robust estimator.
803      * @throws IllegalArgumentException if provided quality scores don't have
804      *                                  the required minimum size (6 correspondences).
805      */
806     public static PointCorrespondencePinholeCameraRobustEstimator create(
807             final PinholeCameraRobustEstimatorListener listener, final double skewness,
808             final double horizontalPrincipalPoint, final double verticalPrincipalPoint, final double[] qualityScores,
809             final RobustEstimatorMethod method) {
810         final var estimator = UPnPPointCorrespondencePinholeCameraRobustEstimator.create(listener, qualityScores,
811                 method);
812         try {
813             estimator.setSkewness(skewness);
814             estimator.setHorizontalPrincipalPoint(horizontalPrincipalPoint);
815             estimator.setVerticalPrincipalPoint(verticalPrincipalPoint);
816         } catch (final LockedException ignore) {
817             // ignore
818         }
819         return estimator;
820     }
821 
822     /**
823      * Creates a pinhole camera robust estimator based on point correspondences
824      * and using provided listener, 2D/3D points, quality scores and robust
825      * estimator method + UPnP.
826      *
827      * @param listener                 listener to be notified of events such as when estimation
828      *                                 starts, ends or its progress significantly changes.
829      * @param skewness                 skewness value of intrinsic parameters of camera to be
830      *                                 estimated.
831      * @param horizontalPrincipalPoint horizontal principal point value of
832      *                                 intrinsic parameters of camera to be estimated.
833      * @param verticalPrincipalPoint   vertical principal point value of
834      *                                 intrinsic parameters of camera to be estimated.
835      * @param points3D                 list of 3D points used to estimate a pinhole camera.
836      * @param points2D                 list of corresponding projected 2D points used to
837      *                                 estimate a pinhole camera.
838      * @param qualityScores            quality scores corresponding to each pair of matched
839      *                                 points.
840      * @param method                   method of a robust estimator algorithm to estimate the best
841      *                                 pinhole camera.
842      * @return an instance of a pinhole camera robust estimator.
843      * @throws IllegalArgumentException if provided lists of points and quality
844      *                                  scores don't have the same size or their size is smaller than required
845      *                                  minimum size (6 correspondences).
846      */
847     public static PointCorrespondencePinholeCameraRobustEstimator create(
848             final PinholeCameraRobustEstimatorListener listener, final double skewness,
849             final double horizontalPrincipalPoint, final double verticalPrincipalPoint, final List<Point3D> points3D,
850             final List<Point2D> points2D, final double[] qualityScores, final RobustEstimatorMethod method) {
851         final var estimator = UPnPPointCorrespondencePinholeCameraRobustEstimator.create(listener, points3D, points2D,
852                 qualityScores, method);
853         try {
854             estimator.setSkewness(skewness);
855             estimator.setHorizontalPrincipalPoint(horizontalPrincipalPoint);
856             estimator.setVerticalPrincipalPoint(verticalPrincipalPoint);
857         } catch (final LockedException ignore) {
858             // ignore
859         }
860         return estimator;
861     }
862 
863     /**
864      * Creates a pinhole camera robust estimator based on point correspondences
865      * and using default robust estimator method + DLT.
866      *
867      * @return an instance of a pinhole camera robust estimator.
868      */
869     public static PointCorrespondencePinholeCameraRobustEstimator create() {
870         return create(DEFAULT_ROBUST_METHOD);
871     }
872 
873     /**
874      * Creates a pinhole camera robust estimator based on point correspondences
875      * and using provided 2D/3D points and default robust estimator method +
876      * DLT.
877      *
878      * @param points3D list of 3D points used to estimate a pinhole camera.
879      * @param points2D list of corresponding projected 2D points used to
880      *                 estimate a pinhole camera.
881      * @return an instance of a pinhole camera robust estimator.
882      * @throws IllegalArgumentException if provided lists of points don't have
883      *                                  the same size or their size is smaller than required minimum size
884      *                                  (6 correspondences).
885      */
886     public static PointCorrespondencePinholeCameraRobustEstimator create(
887             final List<Point3D> points3D, final List<Point2D> points2D) {
888         return create(points3D, points2D, DEFAULT_ROBUST_METHOD);
889     }
890 
891     /**
892      * Creates a pinhole camera robust estimator based on point
893      * correspondences and using provided listener and default robust estimator
894      * method + DLT.
895      *
896      * @param listener listener to be notified of events such as when estimation
897      *                 starts, ends or its progress significantly changes.
898      * @return an instance of a pinhole camera robust estimator.
899      */
900     public static PointCorrespondencePinholeCameraRobustEstimator create(
901             final PinholeCameraRobustEstimatorListener listener) {
902         return create(listener, DEFAULT_ROBUST_METHOD);
903     }
904 
905     /**
906      * Creates a pinhole camera robust estimator based on point correspondences
907      * and using provided listener, 2D/3D points and default robust estimator
908      * method + DLT.
909      *
910      * @param listener listener to be notified of events such as when estimation
911      *                 starts, ends or its progress significantly changes.
912      * @param points3D list of 3D points used to estimate a pinhole camera.
913      * @param points2D list of corresponding projected 2D points used to
914      *                 estimate a pinhole camera.
915      * @return an instance of a pinhole camera robust estimator.
916      * @throws IllegalArgumentException if provided lists of points don't have
917      *                                  the same size or their size is smaller than required minimum size
918      *                                  (6 correspondences).
919      */
920     public static PointCorrespondencePinholeCameraRobustEstimator create(
921             final PinholeCameraRobustEstimatorListener listener, final List<Point3D> points3D,
922             final List<Point2D> points2D) {
923         return create(listener, points3D, points2D, DEFAULT_ROBUST_METHOD);
924     }
925 
926     /**
927      * Creates a pinhole camera robust estimator based on point correspondences
928      * and using provided quality scores and default robust estimator method +
929      * DLT.
930      *
931      * @param qualityScores quality scores corresponding to each pair of matched
932      *                      points.
933      * @return an instance of a pinhole camera robust estimator.
934      * @throws IllegalArgumentException if provided quality scores length is
935      *                                  smaller than required minimum size (6 samples).
936      */
937     public static PointCorrespondencePinholeCameraRobustEstimator create(final double[] qualityScores) {
938         return create(qualityScores, DEFAULT_ROBUST_METHOD);
939     }
940 
941     /**
942      * Creates a pinhole camera robust estimator based on point correspondences
943      * and using provided 2D/3D points, quality scores and default robust
944      * estimator method + DLT.
945      *
946      * @param points3D      list of 3D points used to estimate a pinhole camera.
947      * @param points2D      list of corresponding projected 2D points used to
948      *                      estimate a pinhole camera.
949      * @param qualityScores quality scores corresponding to each pair of matched
950      *                      points.
951      * @return an instance of a pinhole camera robust estimator.
952      * @throws IllegalArgumentException if provided lists of points and quality
953      *                                  scores don't have the same size or their size is smaller than required
954      *                                  minimum size (6 correspondences).
955      */
956     public static PointCorrespondencePinholeCameraRobustEstimator create(
957             final List<Point3D> points3D, final List<Point2D> points2D, final double[] qualityScores) {
958         return create(points3D, points2D, qualityScores, DEFAULT_ROBUST_METHOD);
959     }
960 
961     /**
962      * Creates a pinhole camera robust estimator based on point
963      * correspondences and using provided listener, quality scores and default
964      * robust estimator method + DLT.
965      *
966      * @param listener      listener to be notified of events such as when estimation
967      *                      starts, ends or its progress significantly changes.
968      * @param qualityScores quality scores corresponding to each pair of matched
969      *                      points.
970      * @return an instance of a pinhole camera robust estimator.
971      * @throws IllegalArgumentException if provided quality scores don't have
972      *                                  the required minimum size (6 correspondences).
973      */
974     public static PointCorrespondencePinholeCameraRobustEstimator create(
975             final PinholeCameraRobustEstimatorListener listener, final double[] qualityScores) {
976         return create(listener, qualityScores, DEFAULT_ROBUST_METHOD);
977     }
978 
979     /**
980      * Creates a pinhole camera robust estimator based on point correspondences
981      * and using provided listener, 2D/3D points, quality scores and default
982      * robust estimator method + DLT.
983      *
984      * @param listener      listener to be notified of events such as when estimation
985      *                      starts, ends or its progress significantly changes.
986      * @param points3D      list of 3D points used to estimate a pinhole camera.
987      * @param points2D      list of corresponding projected 2D points used to
988      *                      estimate a pinhole camera.
989      * @param qualityScores quality scores corresponding to each pair of matched
990      *                      points.
991      * @return an instance of a pinhole camera robust estimator.
992      * @throws IllegalArgumentException if provided lists of points and quality
993      *                                  scores don't have the same size or their size is smaller than required
994      *                                  minimum size (6 correspondences).
995      */
996     public static PointCorrespondencePinholeCameraRobustEstimator create(
997             final PinholeCameraRobustEstimatorListener listener, final List<Point3D> points3D,
998             final List<Point2D> points2D, final double[] qualityScores) {
999         return create(listener, points3D, points2D, qualityScores, DEFAULT_ROBUST_METHOD);
1000     }
1001 
1002     /**
1003      * Creates a pinhole camera robust estimator based on point correspondences
1004      * and using default robust estimator method + EPnP.
1005      *
1006      * @param intrinsic intrinsic parameters of camera to be estimated.
1007      * @return an instance of a pinhole camera robust estimator.
1008      */
1009     public static PointCorrespondencePinholeCameraRobustEstimator create(
1010             final PinholeCameraIntrinsicParameters intrinsic) {
1011         return create(intrinsic, DEFAULT_ROBUST_METHOD);
1012     }
1013 
1014     /**
1015      * Creates a pinhole camera robust estimator based on point correspondences
1016      * and using provided 2D/3D points and default robust estimator method +
1017      * EPnP.
1018      *
1019      * @param intrinsic intrinsic parameters of camera to be estimated.
1020      * @param points3D  list of 3D points used to estimate a pinhole camera.
1021      * @param points2D  list of corresponding projected 2D points used to
1022      *                  estimate a pinhole camera.
1023      * @return an instance of a pinhole camera robust estimator.
1024      * @throws IllegalArgumentException if provided lists of points don't have
1025      *                                  the same size or their size is smaller than required minimum size
1026      *                                  (6 correspondences).
1027      */
1028     public static PointCorrespondencePinholeCameraRobustEstimator create(
1029             final PinholeCameraIntrinsicParameters intrinsic, final List<Point3D> points3D,
1030             final List<Point2D> points2D) {
1031         return create(intrinsic, points3D, points2D, DEFAULT_ROBUST_METHOD);
1032     }
1033 
1034     /**
1035      * Creates a pinhole camera robust estimator based on point
1036      * correspondences and using provided listener and default robust estimator
1037      * method + EPnP.
1038      *
1039      * @param listener  listener to be notified of events such as when estimation
1040      *                  starts, ends or its progress significantly changes.
1041      * @param intrinsic intrinsic parameters of camera to be estimated.
1042      * @return an instance of a pinhole camera robust estimator.
1043      */
1044     public static PointCorrespondencePinholeCameraRobustEstimator create(
1045             final PinholeCameraRobustEstimatorListener listener, final PinholeCameraIntrinsicParameters intrinsic) {
1046         return create(listener, intrinsic, DEFAULT_ROBUST_METHOD);
1047     }
1048 
1049     /**
1050      * Creates a pinhole camera robust estimator based on point correspondences
1051      * and using provided listener, 2D/3D points and default robust estimator
1052      * method + EPnP.
1053      *
1054      * @param listener  listener to be notified of events such as when estimation
1055      *                  starts, ends or its progress significantly changes.
1056      * @param intrinsic intrinsic parameters of camera to be estimated.
1057      * @param points3D  list of 3D points used to estimate a pinhole camera.
1058      * @param points2D  list of corresponding projected 2D points used to
1059      *                  estimate a pinhole camera.
1060      * @return an instance of a pinhole camera robust estimator.
1061      * @throws IllegalArgumentException if provided lists of points don't have
1062      *                                  the same size or their size is smaller than required minimum size
1063      *                                  (6 correspondences).
1064      */
1065     public static PointCorrespondencePinholeCameraRobustEstimator create(
1066             final PinholeCameraRobustEstimatorListener listener, final PinholeCameraIntrinsicParameters intrinsic,
1067             final List<Point3D> points3D, final List<Point2D> points2D) {
1068         return create(listener, intrinsic, points3D, points2D, DEFAULT_ROBUST_METHOD);
1069     }
1070 
1071     /**
1072      * Creates a pinhole camera robust estimator based on point correspondences
1073      * and using provided quality scores and default robust estimator method +
1074      * EPnP.
1075      *
1076      * @param intrinsic     intrinsic parameters of camera to be estimated.
1077      * @param qualityScores quality scores corresponding to each pair of matched
1078      *                      points.
1079      * @return an instance of a pinhole camera robust estimator.
1080      * @throws IllegalArgumentException if provided quality scores length is
1081      *                                  smaller than required minimum size (6 samples).
1082      */
1083     public static PointCorrespondencePinholeCameraRobustEstimator create(
1084             final PinholeCameraIntrinsicParameters intrinsic, final double[] qualityScores) {
1085         return create(intrinsic, qualityScores, DEFAULT_ROBUST_METHOD);
1086     }
1087 
1088     /**
1089      * Creates a pinhole camera robust estimator based on point correspondences
1090      * and using provided 2D/3D points, quality scores and default robust
1091      * estimator method + EPnP.
1092      *
1093      * @param intrinsic     intrinsic parameters of camera to be estimated.
1094      * @param points3D      list of 3D points used to estimate a pinhole camera.
1095      * @param points2D      list of corresponding projected 2D points used to
1096      *                      estimate a pinhole camera.
1097      * @param qualityScores quality scores corresponding to each pair of matched
1098      *                      points.
1099      * @return an instance of a pinhole camera robust estimator.
1100      * @throws IllegalArgumentException if provided lists of points and quality
1101      *                                  scores don't have the same size or their size is smaller than required
1102      *                                  minimum size (6 correspondences).
1103      */
1104     public static PointCorrespondencePinholeCameraRobustEstimator create(
1105             final PinholeCameraIntrinsicParameters intrinsic, final List<Point3D> points3D,
1106             final List<Point2D> points2D, final double[] qualityScores) {
1107         return create(intrinsic, points3D, points2D, qualityScores, DEFAULT_ROBUST_METHOD);
1108     }
1109 
1110     /**
1111      * Creates a pinhole camera robust estimator based on point
1112      * correspondences and using provided listener, quality scores and default
1113      * robust estimator method + EPnP.
1114      *
1115      * @param listener      listener to be notified of events such as when estimation
1116      *                      starts, ends or its progress significantly changes.
1117      * @param intrinsic     intrinsic parameters of camera to be estimated.
1118      * @param qualityScores quality scores corresponding to each pair of matched
1119      *                      points.
1120      * @return an instance of a pinhole camera robust estimator.
1121      * @throws IllegalArgumentException if provided quality scores don't have
1122      *                                  the required minimum size (6 correspondences).
1123      */
1124     public static PointCorrespondencePinholeCameraRobustEstimator create(
1125             final PinholeCameraRobustEstimatorListener listener, final PinholeCameraIntrinsicParameters intrinsic,
1126             final double[] qualityScores) {
1127         return create(listener, intrinsic, qualityScores, DEFAULT_ROBUST_METHOD);
1128     }
1129 
1130     /**
1131      * Creates a pinhole camera robust estimator based on point correspondences
1132      * and using provided listener, 2D/3D points, quality scores and default
1133      * robust estimator method + EPnP.
1134      *
1135      * @param listener      listener to be notified of events such as when estimation
1136      *                      starts, ends or its progress significantly changes.
1137      * @param intrinsic     intrinsic parameters of camera to be estimated.
1138      * @param points3D      list of 3D points used to estimate a pinhole camera.
1139      * @param points2D      list of corresponding projected 2D points used to
1140      *                      estimate a pinhole camera.
1141      * @param qualityScores quality scores corresponding to each pair of matched
1142      *                      points.
1143      * @return an instance of a pinhole camera robust estimator.
1144      * @throws IllegalArgumentException if provided lists of points and quality
1145      *                                  scores don't have the same size or their size is smaller than required
1146      *                                  minimum size (6 correspondences).
1147      */
1148     public static PointCorrespondencePinholeCameraRobustEstimator create(
1149             final PinholeCameraRobustEstimatorListener listener, final PinholeCameraIntrinsicParameters intrinsic,
1150             final List<Point3D> points3D, List<Point2D> points2D, final double[] qualityScores) {
1151         return create(listener, intrinsic, points3D, points2D, qualityScores, DEFAULT_ROBUST_METHOD);
1152     }
1153 
1154     /**
1155      * Creates a pinhole camera robust estimator based on point correspondences
1156      * and using default robust estimator method + UPnP.
1157      *
1158      * @param skewness                 skewness value of intrinsic parameters of camera to be
1159      *                                 estimated.
1160      * @param horizontalPrincipalPoint horizontal principal point value of
1161      *                                 intrinsic parameters of camera to be estimated.
1162      * @param verticalPrincipalPoint   vertical principal point value of
1163      *                                 intrinsic parameters of camera to be estimated.
1164      * @return an instance of a pinhole camera robust estimator.
1165      */
1166     public static PointCorrespondencePinholeCameraRobustEstimator create(
1167             final double skewness, final double horizontalPrincipalPoint, final double verticalPrincipalPoint) {
1168         return create(skewness, horizontalPrincipalPoint, verticalPrincipalPoint, DEFAULT_ROBUST_METHOD);
1169     }
1170 
1171     /**
1172      * Creates a pinhole camera robust estimator based on point correspondences
1173      * and using provided 2D/3D points and default robust estimator method +
1174      * EPnP.
1175      *
1176      * @param skewness                 skewness value of intrinsic parameters of camera to be
1177      *                                 estimated.
1178      * @param horizontalPrincipalPoint horizontal principal point value of
1179      *                                 intrinsic parameters of camera to be estimated.
1180      * @param verticalPrincipalPoint   vertical principal point value of
1181      *                                 intrinsic parameters of camera to be estimated.
1182      * @param points3D                 list of 3D points used to estimate a pinhole camera.
1183      * @param points2D                 list of corresponding projected 2D points used to
1184      *                                 estimate a pinhole camera.
1185      * @return an instance of a pinhole camera robust estimator.
1186      * @throws IllegalArgumentException if provided lists of points don't have
1187      *                                  the same size or their size is smaller than required minimum size
1188      *                                  (6 correspondences).
1189      */
1190     public static PointCorrespondencePinholeCameraRobustEstimator create(
1191             final double skewness, final double horizontalPrincipalPoint, final double verticalPrincipalPoint,
1192             final List<Point3D> points3D, final List<Point2D> points2D) {
1193         return create(skewness, horizontalPrincipalPoint, verticalPrincipalPoint, points3D, points2D,
1194                 DEFAULT_ROBUST_METHOD);
1195     }
1196 
1197     /**
1198      * Creates a pinhole camera robust estimator based on point
1199      * correspondences and using provided listener and default robust estimator
1200      * method + EPnP.
1201      *
1202      * @param listener                 listener to be notified of events such as when estimation
1203      *                                 starts, ends or its progress significantly changes.
1204      * @param skewness                 skewness value of intrinsic parameters of camera to be
1205      *                                 estimated.
1206      * @param horizontalPrincipalPoint horizontal principal point value of
1207      *                                 intrinsic parameters of camera to be estimated.
1208      * @param verticalPrincipalPoint   vertical principal point value of
1209      *                                 intrinsic parameters of camera to be estimated.
1210      * @return an instance of a pinhole camera robust estimator.
1211      */
1212     public static PointCorrespondencePinholeCameraRobustEstimator create(
1213             final PinholeCameraRobustEstimatorListener listener, final double skewness,
1214             final double horizontalPrincipalPoint, final double verticalPrincipalPoint) {
1215         return create(listener, skewness, horizontalPrincipalPoint, verticalPrincipalPoint, DEFAULT_ROBUST_METHOD);
1216     }
1217 
1218     /**
1219      * Creates a pinhole camera robust estimator based on point correspondences
1220      * and using provided listener, 2D/3D points and default robust estimator
1221      * method + UPnP.
1222      *
1223      * @param listener                 listener to be notified of events such as when estimation
1224      *                                 starts, ends or its progress significantly changes.
1225      * @param skewness                 skewness value of intrinsic parameters of camera to be
1226      *                                 estimated.
1227      * @param horizontalPrincipalPoint horizontal principal point value of
1228      *                                 intrinsic parameters of camera to be estimated.
1229      * @param verticalPrincipalPoint   vertical principal point value of
1230      *                                 intrinsic parameters of camera to be estimated.
1231      * @param points3D                 list of 3D points used to estimate a pinhole camera.
1232      * @param points2D                 list of corresponding projected 2D points used to
1233      *                                 estimate a pinhole camera.
1234      * @return an instance of a pinhole camera robust estimator.
1235      * @throws IllegalArgumentException if provided lists of points don't have
1236      *                                  the same size or their size is smaller than required minimum size
1237      *                                  (6 correspondences).
1238      */
1239     public static PointCorrespondencePinholeCameraRobustEstimator create(
1240             final PinholeCameraRobustEstimatorListener listener, final double skewness,
1241             final double horizontalPrincipalPoint, final double verticalPrincipalPoint, final List<Point3D> points3D,
1242             final List<Point2D> points2D) {
1243         return create(listener, skewness, horizontalPrincipalPoint, verticalPrincipalPoint, points3D, points2D,
1244                 DEFAULT_ROBUST_METHOD);
1245     }
1246 
1247     /**
1248      * Creates a pinhole camera robust estimator based on point correspondences
1249      * and using provided quality scores and default robust estimator method +
1250      * UPnP.
1251      *
1252      * @param skewness                 skewness value of intrinsic parameters of camera to be
1253      *                                 estimated.
1254      * @param horizontalPrincipalPoint horizontal principal point value of
1255      *                                 intrinsic parameters of camera to be estimated.
1256      * @param verticalPrincipalPoint   vertical principal point value of
1257      *                                 intrinsic parameters of camera to be estimated.
1258      * @param qualityScores            quality scores corresponding to each pair of matched
1259      *                                 points.
1260      * @return an instance of a pinhole camera robust estimator.
1261      * @throws IllegalArgumentException if provided quality scores length is
1262      *                                  smaller than required minimum size (6 samples).
1263      */
1264     public static PointCorrespondencePinholeCameraRobustEstimator create(
1265             final double skewness, final double horizontalPrincipalPoint, final double verticalPrincipalPoint,
1266             final double[] qualityScores) {
1267         return create(skewness, horizontalPrincipalPoint, verticalPrincipalPoint, qualityScores, DEFAULT_ROBUST_METHOD);
1268     }
1269 
1270     /**
1271      * Creates a pinhole camera robust estimator based on point correspondences
1272      * and using provided 2D/3D points, quality scores and default robust
1273      * estimator method + UPnP.
1274      *
1275      * @param skewness                 skewness value of intrinsic parameters of camera to be
1276      *                                 estimated.
1277      * @param horizontalPrincipalPoint horizontal principal point value of
1278      *                                 intrinsic parameters of camera to be estimated.
1279      * @param verticalPrincipalPoint   vertical principal point value of
1280      *                                 intrinsic parameters of camera to be estimated.
1281      * @param points3D                 list of 3D points used to estimate a pinhole camera.
1282      * @param points2D                 list of corresponding projected 2D points used to
1283      *                                 estimate a pinhole camera.
1284      * @param qualityScores            quality scores corresponding to each pair of matched
1285      *                                 points.
1286      * @return an instance of a pinhole camera robust estimator.
1287      * @throws IllegalArgumentException if provided lists of points and quality
1288      *                                  scores don't have the same size or their size is smaller than required
1289      *                                  minimum size (6 correspondences).
1290      */
1291     public static PointCorrespondencePinholeCameraRobustEstimator create(
1292             final double skewness, final double horizontalPrincipalPoint, final double verticalPrincipalPoint,
1293             final List<Point3D> points3D, final List<Point2D> points2D, final double[] qualityScores) {
1294         return create(skewness, horizontalPrincipalPoint, verticalPrincipalPoint, points3D, points2D, qualityScores,
1295                 DEFAULT_ROBUST_METHOD);
1296     }
1297 
1298     /**
1299      * Creates a pinhole camera robust estimator based on point
1300      * correspondences and using provided listener, quality scores and default
1301      * robust estimator method + UPnP.
1302      *
1303      * @param listener                 listener to be notified of events such as when estimation
1304      *                                 starts, ends or its progress significantly changes.
1305      * @param skewness                 skewness value of intrinsic parameters of camera to be
1306      *                                 estimated.
1307      * @param horizontalPrincipalPoint horizontal principal point value of
1308      *                                 intrinsic parameters of camera to be estimated.
1309      * @param verticalPrincipalPoint   vertical principal point value of
1310      *                                 intrinsic parameters of camera to be estimated.
1311      * @param qualityScores            quality scores corresponding to each pair of matched
1312      *                                 points.
1313      * @return an instance of a pinhole camera robust estimator.
1314      * @throws IllegalArgumentException if provided quality scores don't have
1315      *                                  the required minimum size (6 correspondences).
1316      */
1317     public static PointCorrespondencePinholeCameraRobustEstimator create(
1318             final PinholeCameraRobustEstimatorListener listener, final double skewness,
1319             final double horizontalPrincipalPoint, final double verticalPrincipalPoint, final double[] qualityScores) {
1320         return create(listener, skewness, horizontalPrincipalPoint, verticalPrincipalPoint, qualityScores,
1321                 DEFAULT_ROBUST_METHOD);
1322     }
1323 
1324     /**
1325      * Creates a pinhole camera robust estimator based on point correspondences
1326      * and using provided listener, 2D/3D points, quality scores and default
1327      * robust estimator method + UPnP.
1328      *
1329      * @param listener                 listener to be notified of events such as when estimation
1330      *                                 starts, ends or its progress significantly changes.
1331      * @param skewness                 skewness value of intrinsic parameters of camera to be
1332      *                                 estimated.
1333      * @param horizontalPrincipalPoint horizontal principal point value of
1334      *                                 intrinsic parameters of camera to be estimated.
1335      * @param verticalPrincipalPoint   vertical principal point value of
1336      *                                 intrinsic parameters of camera to be estimated.
1337      * @param points3D                 list of 3D points used to estimate a pinhole camera.
1338      * @param points2D                 list of corresponding projected 2D points used to
1339      *                                 estimate a pinhole camera.
1340      * @param qualityScores            quality scores corresponding to each pair of matched
1341      *                                 points.
1342      * @return an instance of a pinhole camera robust estimator.
1343      * @throws IllegalArgumentException if provided lists of points and quality
1344      *                                  scores don't have the same size or their size is smaller than required
1345      *                                  minimum size (6 correspondences).
1346      */
1347     public static PointCorrespondencePinholeCameraRobustEstimator create(
1348             final PinholeCameraRobustEstimatorListener listener, final double skewness,
1349             final double horizontalPrincipalPoint, final double verticalPrincipalPoint, final List<Point3D> points3D,
1350             final List<Point2D> points2D, final double[] qualityScores) {
1351         return create(listener, skewness, horizontalPrincipalPoint, verticalPrincipalPoint, points3D, points2D,
1352                 qualityScores, DEFAULT_ROBUST_METHOD);
1353     }
1354 
1355     /**
1356      * Attempts to refine provided camera.
1357      *
1358      * @param pinholeCamera camera to be refined.
1359      * @param weight        weight for suggestion residual.
1360      * @return refined camera or provided camera if anything fails.
1361      */
1362     protected PinholeCamera attemptRefine(final PinholeCamera pinholeCamera, final double weight) {
1363         if (hasSuggestions() && useFastRefinement) {
1364             return attemptFastRefine(pinholeCamera, weight);
1365         } else {
1366             return attemptSlowRefine(pinholeCamera, weight);
1367         }
1368     }
1369 
1370     /**
1371      * Internal method to set lists of points to be used to estimate a pinhole
1372      * camera.
1373      * This method does not check whether estimator is locked or not.
1374      *
1375      * @param points3D list of 3D points used to estimate a pinhole camera.
1376      * @param points2D list of corresponding projected 2D points used to
1377      *                 estimate a pinhole camera.
1378      * @throws IllegalArgumentException if provided lists of points don't have
1379      *                                  the same size or their size is smaller than required minimum size (6
1380      *                                  points).
1381      */
1382     private void internalSetPoints(final List<Point3D> points3D, final List<Point2D> points2D) {
1383         if (points3D.size() < MIN_NUMBER_OF_POINT_CORRESPONDENCES) {
1384             throw new IllegalArgumentException();
1385         }
1386         if (points3D.size() != points2D.size()) {
1387             throw new IllegalArgumentException();
1388         }
1389         this.points3D = points3D;
1390         this.points2D = points2D;
1391     }
1392 
1393     /**
1394      * Attempts to refine provided camera using a slow but more accurate and
1395      * stable algorithm by first doing a Powell optimization and then
1396      * obtaining covariance using Levenberg/Marquardt if needed.
1397      *
1398      * @param pinholeCamera camera to be refined.
1399      * @param weight        weight for suggestion residual.
1400      * @return refined camera or provided camera if anything fails.
1401      */
1402     private PinholeCamera attemptSlowRefine(final PinholeCamera pinholeCamera, final double weight) {
1403         final var inliersData = getInliersData();
1404         if ((refineResult || keepCovariance) && inliersData != null) {
1405             final var refiner = new DecomposedPointCorrespondencePinholeCameraRefiner(pinholeCamera, keepCovariance,
1406                     inliersData, points3D, points2D, getRefinementStandardDeviation());
1407             try {
1408                 if (refineResult) {
1409                     refiner.setMinSuggestionWeight(weight);
1410                     refiner.setMaxSuggestionWeight(weight);
1411 
1412                     refiner.setSuggestSkewnessValueEnabled(suggestSkewnessValueEnabled);
1413                     refiner.setSuggestedSkewnessValue(suggestedSkewnessValue);
1414                     refiner.setSuggestHorizontalFocalLengthEnabled(suggestHorizontalFocalLengthEnabled);
1415                     refiner.setSuggestedHorizontalFocalLengthValue(suggestedHorizontalFocalLengthValue);
1416                     refiner.setSuggestVerticalFocalLengthEnabled(suggestVerticalFocalLengthEnabled);
1417                     refiner.setSuggestedVerticalFocalLengthValue(suggestedVerticalFocalLengthValue);
1418                     refiner.setSuggestAspectRatioEnabled(suggestAspectRatioEnabled);
1419                     refiner.setSuggestedAspectRatioValue(suggestedAspectRatioValue);
1420                     refiner.setSuggestPrincipalPointEnabled(suggestPrincipalPointEnabled);
1421                     refiner.setSuggestedPrincipalPointValue(suggestedPrincipalPointValue);
1422                     refiner.setSuggestRotationEnabled(suggestRotationEnabled);
1423                     refiner.setSuggestedRotationValue(suggestedRotationValue);
1424                     refiner.setSuggestCenterEnabled(suggestCenterEnabled);
1425                     refiner.setSuggestedCenterValue(suggestedCenterValue);
1426                 }
1427 
1428                 final var result = new PinholeCamera();
1429                 final var improved = refiner.refine(result);
1430 
1431                 if (keepCovariance) {
1432                     // keep covariance
1433                     covariance = refiner.getCovariance();
1434                 }
1435 
1436                 return improved ? result : pinholeCamera;
1437 
1438             } catch (final Exception e) {
1439                 return pinholeCamera;
1440             }
1441         } else {
1442             covariance = null;
1443             return pinholeCamera;
1444         }
1445     }
1446 
1447     /**
1448      * Attempts to refine provided camera using a fast algorithm based on
1449      * Levenberg/Marquardt.
1450      *
1451      * @param pinholeCamera camera to be refined.
1452      * @param weight        weight for suggestion residual.
1453      * @return refined camera or provided camera if anything fails.
1454      */
1455     private PinholeCamera attemptFastRefine(final PinholeCamera pinholeCamera, final double weight) {
1456         final var inliersData = getInliersData();
1457         if (refineResult && inliersData != null) {
1458             final var refiner = new NonDecomposedPointCorrespondencePinholeCameraRefiner(pinholeCamera, keepCovariance,
1459                     inliersData, points3D, points2D, getRefinementStandardDeviation());
1460 
1461             try {
1462                 refiner.setSuggestionErrorWeight(weight);
1463 
1464                 refiner.setSuggestSkewnessValueEnabled(suggestSkewnessValueEnabled);
1465                 refiner.setSuggestedSkewnessValue(suggestedSkewnessValue);
1466                 refiner.setSuggestHorizontalFocalLengthEnabled(suggestHorizontalFocalLengthEnabled);
1467                 refiner.setSuggestedHorizontalFocalLengthValue(suggestedHorizontalFocalLengthValue);
1468                 refiner.setSuggestVerticalFocalLengthEnabled(suggestVerticalFocalLengthEnabled);
1469                 refiner.setSuggestedVerticalFocalLengthValue(suggestedVerticalFocalLengthValue);
1470                 refiner.setSuggestAspectRatioEnabled(suggestAspectRatioEnabled);
1471                 refiner.setSuggestedAspectRatioValue(suggestedAspectRatioValue);
1472                 refiner.setSuggestPrincipalPointEnabled(suggestPrincipalPointEnabled);
1473                 refiner.setSuggestedPrincipalPointValue(suggestedPrincipalPointValue);
1474                 refiner.setSuggestRotationEnabled(suggestRotationEnabled);
1475                 refiner.setSuggestedRotationValue(suggestedRotationValue);
1476                 refiner.setSuggestCenterEnabled(suggestCenterEnabled);
1477                 refiner.setSuggestedCenterValue(suggestedCenterValue);
1478 
1479                 final var result = new PinholeCamera();
1480                 final var improved = refiner.refine(result);
1481 
1482                 if (keepCovariance) {
1483                     // keep covariance
1484                     covariance = refiner.getCovariance();
1485                 }
1486 
1487                 return improved ? result : pinholeCamera;
1488             } catch (final Exception e) {
1489                 // refinement failed, so we return input value
1490                 return pinholeCamera;
1491             }
1492         } else {
1493             return pinholeCamera;
1494         }
1495     }
1496 }