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