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.Line2D;
19 import com.irurueta.geometry.ProjectiveTransformation2D;
20 import com.irurueta.geometry.refiners.LineCorrespondenceProjectiveTransformation2DRefiner;
21 import com.irurueta.numerical.robust.RobustEstimatorMethod;
22
23 import java.util.List;
24
25 /**
26 * This is an abstract class for algorithms to robustly find the best projective
27 * 2D transformation for collections of matching 2D lines.
28 * Implementations of this class should be able to detect and discard outliers
29 * in order to find the best solution.
30 */
31 public abstract class LineCorrespondenceProjectiveTransformation2DRobustEstimator extends
32 ProjectiveTransformation2DRobustEstimator {
33
34 /**
35 * Default robust estimator method when none is provided.
36 */
37 public static final RobustEstimatorMethod DEFAULT_ROBUST_METHOD = RobustEstimatorMethod.PROMEDS;
38
39 /**
40 * List of lines to be used to estimate a projective 2D transformation.
41 * Each line in the list of input lines must be matched with the
42 * corresponding line in the list of output lines located at the same
43 * position. Hence, both input lines and output lines must have the
44 * same size, and their size must be greater or equal than MINIMUM_SIZE.
45 */
46 protected List<Line2D> inputLines;
47
48 /**
49 * List of lines to be used to estimate a projective 2D transformation.
50 * Each point in the list of output lines must be matched with the
51 * corresponding line in the list of input lines located at the same
52 * position. Hence, both input lines and output lines must have the
53 * same size, and their size must be greater or equal than MINIMUM_SIZE.
54 */
55 protected List<Line2D> outputLines;
56
57 /**
58 * Constructor.
59 */
60 protected LineCorrespondenceProjectiveTransformation2DRobustEstimator() {
61 super();
62 }
63
64 /**
65 * Constructor with lists of lines to be used to estimate a projective 2D
66 * transformation.
67 * Lines in the list located at the same position are considered to be
68 * matched. Hence, both lists must have the same size, and their size must
69 * be greater or equal than MINIMUM_SIZE.
70 *
71 * @param inputLines list of input lines to be used to estimate a projective
72 * 2D transformation.
73 * @param outputLines list of output lines ot be used to estimate a
74 * projective 2D transformation.
75 * @throws IllegalArgumentException if provided lists of points don't have
76 * the same size or their size is smaller than MINIMUM_SIZE.
77 */
78 protected LineCorrespondenceProjectiveTransformation2DRobustEstimator(
79 final List<Line2D> inputLines, final List<Line2D> outputLines) {
80 super();
81 internalSetLines(inputLines, outputLines);
82 }
83
84 /**
85 * Constructor.
86 *
87 * @param listener listener to be notified of events such as when estimation
88 * starts, ends or its progress significantly changes.
89 */
90 protected LineCorrespondenceProjectiveTransformation2DRobustEstimator(
91 final ProjectiveTransformation2DRobustEstimatorListener listener) {
92 super(listener);
93 }
94
95 /**
96 * Constructor with listener and lists of lines to be used to estimate
97 * projective 2D transformation.
98 * Lines in the list located at the same position are considered to be
99 * matched. Hence, both lists must have the same size, and their size must
100 * be greater or equal than MINIMUM_SIZE.
101 *
102 * @param listener listener to be notified of events such as when estimation
103 * starts, ends or its progress significantly changes.
104 * @param inputLines list of input lines to be used to estimate a projective
105 * 2D transformation.
106 * @param outputLines list of output lines to be used to estimate a
107 * projective 2D transformation.
108 * @throws IllegalArgumentException if provided lists of lines don't have
109 * the same size or their size is smaller than MINIMUM_SIZE.
110 */
111 protected LineCorrespondenceProjectiveTransformation2DRobustEstimator(
112 final ProjectiveTransformation2DRobustEstimatorListener listener,
113 final List<Line2D> inputLines, final List<Line2D> outputLines) {
114 super(listener);
115 internalSetLines(inputLines, outputLines);
116 }
117
118 /**
119 * Returns list of input lines to be used to estimate a projective 2D
120 * transformation.
121 * Each line in the list of input lines must be matched with the
122 * corresponding line in the list of output lines located at the same
123 * position. Hence, both input lines and output lines must have the same
124 * size, and their size must be greater or equal than MINIMUM_SIZE.
125 *
126 * @return list of input lines to be used to estimate a projective 2D
127 * transformation.
128 */
129 public List<Line2D> getInputLines() {
130 return inputLines;
131 }
132
133 /**
134 * Returns list of output lines to be used to estimate a projective 2D
135 * transformation.
136 * Each line in the list of output lines must be matched with the
137 * corresponding line in the list of input lines located at the same
138 * position. Hence, both input lines and output lines must have the same
139 * size, and their size must be greater or equal than MINIMUM_SIZE.
140 *
141 * @return list of output lines to be used to estimate a projective 2D
142 * transformation.
143 */
144 public List<Line2D> getOutputLines() {
145 return outputLines;
146 }
147
148 /**
149 * Sets lists of lines to be used to estimate a projective 2D
150 * transformation.
151 * Lines in the list located at the same position are considered to be
152 * matched. Hence, both lists must have the same size, and their size must
153 * be greater or equal than MINIMUM_SIZE.
154 *
155 * @param inputLines list of input lines to be used to estimate a projective
156 * 2D transformation.
157 * @param outputLines list of output lines to be used to estimate a
158 * projective 2D transformation.
159 * @throws IllegalArgumentException if provided lists of lines don't have
160 * the same size or their size is smaller than MINIMUM_SIZE.
161 * @throws LockedException if estimator is locked because a computation is
162 * already in progress.
163 */
164 public final void setLines(final List<Line2D> inputLines, final List<Line2D> outputLines) throws LockedException {
165 if (isLocked()) {
166 throw new LockedException();
167 }
168 internalSetLines(inputLines, outputLines);
169 }
170
171 /**
172 * Indicates if estimator is ready to start the affine 2D transformation
173 * estimation.
174 * This is true when input data (i.e. lists of matched lines) are provided
175 * and a minimum of MINIMUM_SIZE lines are available.
176 *
177 * @return true if estimator is ready, false otherwise.
178 */
179 public boolean isReady() {
180 return inputLines != null && outputLines != null && inputLines.size() == outputLines.size()
181 && inputLines.size() >= MINIMUM_SIZE;
182 }
183
184 /**
185 * Returns quality scores corresponding to each pair of matched lines.
186 * The larger the score value the better the quality of the matching.
187 * This implementation always returns null.
188 * Subclasses using quality scores must implement proper behaviour.
189 *
190 * @return quality scores corresponding to each pair of matched points.
191 */
192 public double[] getQualityScores() {
193 return null;
194 }
195
196 /**
197 * Sets quality scores corresponding to each pair of matched lines.
198 * The larger the score value the better the quality of the matching.
199 * This implementation makes no action.
200 * Subclasses using quality scores must implement proper behaviour.
201 *
202 * @param qualityScores quality scores corresponding to each pair of matched
203 * points.
204 * @throws LockedException if robust estimator is locked because an
205 * estimation is already in progress.
206 * @throws IllegalArgumentException if provided quality scores length is
207 * smaller than MINIMUM_SIZE (i.e. 3 samples).
208 */
209 public void setQualityScores(final double[] qualityScores) throws LockedException {
210 }
211
212 /**
213 * Creates a projective 2D transformation estimator based on 2D line
214 * correspondences and using provided robust estimator method.
215 *
216 * @param method method of a robust estimator algorithm to estimate
217 * best projective 2D transformation.
218 * @return an instance of projective 2D transformation estimator.
219 */
220 public static LineCorrespondenceProjectiveTransformation2DRobustEstimator create(
221 final RobustEstimatorMethod method) {
222 return switch (method) {
223 case LMEDS -> new LMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator();
224 case MSAC -> new MSACLineCorrespondenceProjectiveTransformation2DRobustEstimator();
225 case PROSAC -> new PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator();
226 case PROMEDS -> new PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator();
227 default -> new RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator();
228 };
229 }
230
231 /**
232 * Creates a projective 2D transformation estimator based on 2D line
233 * correspondences and using provided robust estimator method.
234 *
235 * @param inputLines list of input lines to be used to estimate a
236 * projective 2D transformation.
237 * @param outputLines list of output lines to be used to estimate a
238 * projective 2D transformation.
239 * @param method method of a robust estimator algorithm to estimate
240 * best projective 2D transformation.
241 * @return an instance of projective 2D transformation estimator.
242 * @throws IllegalArgumentException if provided lists of lines don't have
243 * the same size or their size is smaller than MINIMUM_SIZE.
244 */
245 public static LineCorrespondenceProjectiveTransformation2DRobustEstimator create(
246 final List<Line2D> inputLines, final List<Line2D> outputLines, final RobustEstimatorMethod method) {
247 return switch (method) {
248 case LMEDS -> new LMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator(inputLines, outputLines);
249 case MSAC -> new MSACLineCorrespondenceProjectiveTransformation2DRobustEstimator(inputLines, outputLines);
250 case PROSAC -> new PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator(
251 inputLines, outputLines);
252 case PROMEDS -> new PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator(
253 inputLines, outputLines);
254 default -> new RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator(inputLines, outputLines);
255 };
256 }
257
258 /**
259 * Creates a projective 2D transformation estimator based on 2D line
260 * correspondences and using provided robust estimator method.
261 *
262 * @param listener listener to be notified of events such as when estimation
263 * starts, ends or its progress significantly changes.
264 * @param method method of a robust estimator algorithm to estimate best
265 * projective 2D transformation.
266 * @return an instance of projective 2D transformation estimator.
267 */
268 public static LineCorrespondenceProjectiveTransformation2DRobustEstimator create(
269 final ProjectiveTransformation2DRobustEstimatorListener listener, final RobustEstimatorMethod method) {
270 return switch (method) {
271 case LMEDS -> new LMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator(listener);
272 case MSAC -> new MSACLineCorrespondenceProjectiveTransformation2DRobustEstimator(listener);
273 case PROSAC -> new PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator(listener);
274 case PROMEDS -> new PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator(listener);
275 default -> new RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator(listener);
276 };
277 }
278
279 /**
280 * Creates a projective 2D transformation estimator based on 2D line
281 * correspondences and using provided robust estimator method.
282 *
283 * @param listener listener to be notified of events such as when estimation
284 * starts, ends or its progress significantly changes.
285 * @param inputLines list of input lines to be used to estimate a projective
286 * 2D transformation.
287 * @param outputLines list of output lines to be used to estimate a
288 * projective 2D transformation.
289 * @param method method of a robust estimator algorithm to estimate best
290 * projective 2D transformation.
291 * @return an instance of projective 2D transformation estimator.
292 * @throws IllegalArgumentException if provided lists of lines don't have
293 * the same size or their size is smaller than MINIMUM_SIZE.
294 */
295 public static LineCorrespondenceProjectiveTransformation2DRobustEstimator create(
296 final ProjectiveTransformation2DRobustEstimatorListener listener,
297 final List<Line2D> inputLines, final List<Line2D> outputLines, final RobustEstimatorMethod method) {
298 return switch (method) {
299 case LMEDS -> new LMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator(
300 listener, inputLines, outputLines);
301 case MSAC -> new MSACLineCorrespondenceProjectiveTransformation2DRobustEstimator(
302 listener, inputLines, outputLines);
303 case PROSAC -> new PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator(
304 listener, inputLines, outputLines);
305 case PROMEDS -> new PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator(
306 listener, inputLines, outputLines);
307 default -> new RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator(
308 listener, inputLines, outputLines);
309 };
310 }
311
312 /**
313 * Creates a projective 2D transformation estimator based on 2D line
314 * correspondences and using provided robust estimator method.
315 *
316 * @param qualityScores quality scores corresponding to each pair of matched
317 * points.
318 * @param method method of a robust estimator algorithm to estimate best
319 * projective 2D transformation.
320 * @return an instance of projective 2D transformation estimator.
321 */
322 public static LineCorrespondenceProjectiveTransformation2DRobustEstimator create(
323 final double[] qualityScores, final RobustEstimatorMethod method) {
324 return switch (method) {
325 case LMEDS -> new LMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator();
326 case MSAC -> new MSACLineCorrespondenceProjectiveTransformation2DRobustEstimator();
327 case PROSAC -> new PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator(qualityScores);
328 case PROMEDS -> new PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator(qualityScores);
329 default -> new RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator();
330 };
331 }
332
333 /**
334 * Creates a projective 2D transformation estimator based on 2D line
335 * correspondences and using provided robust estimator method.
336 *
337 * @param inputLines list of input lines to be used to estimate a
338 * projective 2D transformation.
339 * @param outputLines list of output lines to be used to estimate a
340 * projective 2D transformation.
341 * @param qualityScores quality scores corresponding to each pair of matched
342 * lines.
343 * @param method method of a robust estimator algorithm to estimate best
344 * projective 2D transformation.
345 * @return an instance of projective 2D transformation estimator.
346 * @throws IllegalArgumentException if provided lists of lines don't have
347 * the same size or their size is smaller than MINIMUM_SIZE.
348 */
349 public static LineCorrespondenceProjectiveTransformation2DRobustEstimator create(
350 final List<Line2D> inputLines, final List<Line2D> outputLines, final double[] qualityScores,
351 final RobustEstimatorMethod method) {
352 return switch (method) {
353 case LMEDS -> new LMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator(inputLines, outputLines);
354 case MSAC -> new MSACLineCorrespondenceProjectiveTransformation2DRobustEstimator(inputLines, outputLines);
355 case PROSAC -> new PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator(
356 inputLines, outputLines, qualityScores);
357 case PROMEDS -> new PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator(
358 inputLines, outputLines, qualityScores);
359 default -> new RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator(inputLines, outputLines);
360 };
361 }
362
363 /**
364 * Creates a projective 2D transformation estimator based on 2D line
365 * correspondences and using provided robust estimator method.
366 *
367 * @param listener listener to be notified of events such as when estimation
368 * starts, ends or its progress significantly changes.
369 * @param qualityScores quality scores corresponding to each pair of matched
370 * lines.
371 * @param method method of a robust estimator algorithm to estimate best
372 * projective 2D transformation.
373 * @return an instance of projective 2D transformation estimator.
374 */
375 public static LineCorrespondenceProjectiveTransformation2DRobustEstimator create(
376 final ProjectiveTransformation2DRobustEstimatorListener listener, final double[] qualityScores,
377 final RobustEstimatorMethod method) {
378 return switch (method) {
379 case LMEDS -> new LMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator(listener);
380 case MSAC -> new MSACLineCorrespondenceProjectiveTransformation2DRobustEstimator(listener);
381 case PROSAC -> new PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator(
382 listener, qualityScores);
383 case PROMEDS -> new PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator(
384 listener, qualityScores);
385 default -> new RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator(listener);
386 };
387 }
388
389 /**
390 * Creates a projective 2D transformation estimator based on 2D line
391 * correspondences and using provided robust estimator method.
392 *
393 * @param listener listener to be notified of events such as when estimation
394 * starts, ends or its progress significantly changes.
395 * @param inputLines list of input lines to be used to estimate a projective
396 * 2D transformation.
397 * @param outputLines list of output lines to be used to estimate a
398 * projective 2D transformation.
399 * @param qualityScores quality scores corresponding to each pair of matched
400 * lines.
401 * @param method method of a robust estimator algorithm to estimate best
402 * projective 2D transformation.
403 * @return an instance of projective 2D transformation estimator.
404 * @throws IllegalArgumentException if provided lists of lines don't have
405 * the same size or their size is smaller than MINIMUM_SIZE.
406 */
407 public static LineCorrespondenceProjectiveTransformation2DRobustEstimator create(
408 final ProjectiveTransformation2DRobustEstimatorListener listener,
409 final List<Line2D> inputLines, final List<Line2D> outputLines, final double[] qualityScores,
410 final RobustEstimatorMethod method) {
411 return switch (method) {
412 case LMEDS -> new LMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator(
413 listener, inputLines, outputLines);
414 case MSAC -> new MSACLineCorrespondenceProjectiveTransformation2DRobustEstimator(
415 listener, inputLines, outputLines);
416 case PROSAC -> new PROSACLineCorrespondenceProjectiveTransformation2DRobustEstimator(
417 listener, inputLines, outputLines, qualityScores);
418 case PROMEDS -> new PROMedSLineCorrespondenceProjectiveTransformation2DRobustEstimator(
419 listener, inputLines, outputLines, qualityScores);
420 default -> new RANSACLineCorrespondenceProjectiveTransformation2DRobustEstimator(
421 listener, inputLines, outputLines);
422 };
423 }
424
425 /**
426 * Creates a projective 2D transformation estimator based on 2D line
427 * correspondences and using default robust estimator method.
428 *
429 * @return an instance of projective 2D transformation estimator.
430 */
431 public static LineCorrespondenceProjectiveTransformation2DRobustEstimator create() {
432 return create(DEFAULT_ROBUST_METHOD);
433 }
434
435 /**
436 * Creates a projective 2D transformation estimator based on 2D line
437 * correspondences and using default robust estimator method.
438 *
439 * @param inputLines list of input lines to be used to estimate a
440 * projective 2D transformation.
441 * @param outputLines list of output lines to be used to estimate a
442 * projective 2D transformation.
443 * @return an instance of projective 2D transformation estimator.
444 * @throws IllegalArgumentException if provided lists of lines don't have
445 * the same size or their size is smaller than MINIMUM_SIZE.
446 */
447 public static LineCorrespondenceProjectiveTransformation2DRobustEstimator create(
448 final List<Line2D> inputLines, final List<Line2D> outputLines) {
449 return create(inputLines, outputLines, DEFAULT_ROBUST_METHOD);
450 }
451
452 /**
453 * Creates a projective 2D transformation estimator based on 2D line
454 * correspondences and using default robust estimator method.
455 *
456 * @param listener listener to be notified of events such as when estimation
457 * starts, ends or its progress significantly changes.
458 * @return an instance of projective 2D transformation estimator.
459 */
460 public static LineCorrespondenceProjectiveTransformation2DRobustEstimator create(
461 final ProjectiveTransformation2DRobustEstimatorListener listener) {
462 return create(listener, DEFAULT_ROBUST_METHOD);
463 }
464
465 /**
466 * Creates a projective 2D transformation estimator based on 2D line
467 * correspondences and using default robust estimator method.
468 *
469 * @param listener listener to be notified of events such as when estimation
470 * starts, ends or its progress significantly changes.
471 * @param inputLines list of input lines to be used to estimate a
472 * projective 2D transformation.
473 * @param outputLines list of output lines to be used to estimate a
474 * projective 2D transformation.
475 * @return an instance of projective 2D transformation estimator.
476 * @throws IllegalArgumentException if provided lists of lines don't have
477 * the same size or their size is smaller than MINIMUM_SIZE.
478 */
479 public static LineCorrespondenceProjectiveTransformation2DRobustEstimator create(
480 final ProjectiveTransformation2DRobustEstimatorListener listener,
481 final List<Line2D> inputLines, final List<Line2D> outputLines) {
482 return create(listener, inputLines, outputLines, DEFAULT_ROBUST_METHOD);
483 }
484
485 /**
486 * Creates a projective 2D transformation estimator based on 2D line
487 * correspondences and using default robust estimator method.
488 *
489 * @param qualityScores quality scores corresponding to each pair of matched
490 * points.
491 * @return an instance of affine 2D transformation estimator.
492 */
493 public static LineCorrespondenceProjectiveTransformation2DRobustEstimator create(final double[] qualityScores) {
494 return create(qualityScores, DEFAULT_ROBUST_METHOD);
495 }
496
497 /**
498 * Creates a projective 2D transformation estimator based on 2D line
499 * correspondences and using default robust estimator method.
500 *
501 * @param inputLines list of input lines to be used to estimate a projective
502 * 2D transformation.
503 * @param outputLines list of output lines to be used to estimate a
504 * projective 2D transformation.
505 * @param qualityScores quality scores corresponding to each pair of matched
506 * points.
507 * @return an instance of projective 2D transformation estimator.
508 * @throws IllegalArgumentException if provided lists of lines don't have
509 * the same size or their size is smaller than MINIMUM_SIZE.
510 */
511 public static LineCorrespondenceProjectiveTransformation2DRobustEstimator create(
512 final List<Line2D> inputLines, final List<Line2D> outputLines, final double[] qualityScores) {
513 return create(inputLines, outputLines, qualityScores, DEFAULT_ROBUST_METHOD);
514 }
515
516 /**
517 * Creates a projective 2D transformation estimator based on 2D line
518 * correspondences and using default robust estimator method.
519 *
520 * @param listener listener to be notified of events such as when estimation
521 * starts, ends or its progress significantly changes.
522 * @param qualityScores quality scores corresponding to each pair of matched
523 * points.
524 * @return an instance of projective 2D transformation estimator.
525 */
526 public static LineCorrespondenceProjectiveTransformation2DRobustEstimator create(
527 final ProjectiveTransformation2DRobustEstimatorListener listener, final double[] qualityScores) {
528 return create(listener, qualityScores, DEFAULT_ROBUST_METHOD);
529 }
530
531 /**
532 * Creates a projective 2D transformation estimator based on 2D line
533 * correspondences and using default robust estimator method.
534 *
535 * @param listener listener to be notified of events such as when estimation
536 * starts, ends or its progress significantly changes.
537 * @param inputLines list of input lines to be used to estimate a projective
538 * 2D transformation.
539 * @param outputLines list of output lines to be used to estimate a
540 * projective 2D transformation.
541 * @param qualityScores quality scores corresponding to each pair of matched
542 * lines.
543 * @return an instance of projective 2D transformation estimator.
544 * @throws IllegalArgumentException if provided lists of lines don't have
545 * the same size or their size is smaller than MINIMUM_SIZE.
546 */
547 public static LineCorrespondenceProjectiveTransformation2DRobustEstimator create(
548 final ProjectiveTransformation2DRobustEstimatorListener listener,
549 final List<Line2D> inputLines, final List<Line2D> outputLines, final double[] qualityScores) {
550 return create(listener, inputLines, outputLines, qualityScores, DEFAULT_ROBUST_METHOD);
551 }
552
553 /**
554 * Internal method to set lists of lines to be used to estimate a projective
555 * 2D transformation.
556 * This method does not check whether estimator is locked or not.
557 *
558 * @param inputLines list of input lines to be used to estimate a projective
559 * 2D transformation.
560 * @param outputLines list of output lines to be used to estimate a
561 * projective 2D transformation.
562 * @throws IllegalArgumentException if provided lists of lines don't have
563 * the same size or their size is smaller than MINIMUM_SIZE.
564 */
565 private void internalSetLines(final List<Line2D> inputLines, final List<Line2D> outputLines) {
566 if (inputLines.size() < MINIMUM_SIZE) {
567 throw new IllegalArgumentException();
568 }
569 if (inputLines.size() != outputLines.size()) {
570 throw new IllegalArgumentException();
571 }
572 this.inputLines = inputLines;
573 this.outputLines = outputLines;
574 }
575
576 /**
577 * Computes residual by comparing two lines algebraically by doing the
578 * dot product of their parameters.
579 * A residual of 0 indicates that dot product was 1 or -1 and lines were
580 * equal.
581 * A residual of 1 indicates that dot product was 0 and lines were
582 * orthogonal.
583 * If dot product was -1, then although their director vectors are opposed,
584 * lines are considered equal, since sign changes are not taken into account.
585 *
586 * @param line originally sampled output line.
587 * @param transformedLine estimated output line obtained after using
588 * estimated transformation.
589 * @return computed residual.
590 */
591 protected static double getResidual(final Line2D line, final Line2D transformedLine) {
592 return LineCorrespondenceAffineTransformation2DRobustEstimator.getResidual(line, transformedLine);
593 }
594
595 /**
596 * Attempts to refine provided solution if refinement is requested.
597 * This method returns a refined solution of the same provided solution
598 * if refinement is not requested or has failed.
599 * If refinement is enabled, and it is requested to keep covariance, this
600 * method will also keep covariance of refined transformation.
601 *
602 * @param transformation transformation estimated by a robust estimator
603 * without refinement.
604 * @return solution after refinement (if requested) or the provided
605 * non-refined solution if not requested or refinement failed.
606 */
607 @SuppressWarnings("DuplicatedCode")
608 protected ProjectiveTransformation2D attemptRefine(final ProjectiveTransformation2D transformation) {
609 if (refineResult) {
610 final var refiner = new LineCorrespondenceProjectiveTransformation2DRefiner(transformation, keepCovariance,
611 getInliersData(), inputLines, outputLines, getRefinementStandardDeviation());
612
613 try {
614 final var result = new ProjectiveTransformation2D();
615 final var improved = refiner.refine(result);
616
617 if (keepCovariance) {
618 // keep covariance
619 covariance = refiner.getCovariance();
620 }
621
622 return improved ? result : transformation;
623 } catch (final Exception e) {
624 // refinement failed, so we return input value
625 return transformation;
626 }
627 } else {
628 return transformation;
629 }
630 }
631 }