1 /*
2 * Copyright (C) 2017 Alberto Irurueta Carro (alberto@irurueta.com)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package com.irurueta.geometry.refiners;
17
18 import com.irurueta.geometry.ProjectiveTransformation3D;
19 import com.irurueta.geometry.estimators.LockedException;
20 import com.irurueta.geometry.estimators.NotReadyException;
21 import com.irurueta.numerical.robust.InliersData;
22
23 import java.util.BitSet;
24 import java.util.List;
25
26 /**
27 * Base class for ProjectiveTransformation3D refiner.
28 * Implementations of this class refine a 3D projective transformation by taking
29 * into account an initial estimation, inlier point or plane matches and their
30 * residuals.
31 * This class can be used to find a solution that minimizes error of inliers in
32 * LMSE terms.
33 * Typically, a refiner is used by a robust estimator, however it can also be
34 * useful in some other situations.
35 *
36 * @param <S1> type of matched samples in 1st set.
37 * @param <S2> type of matched samples in 2nd set.
38 */
39 public abstract class ProjectiveTransformation3DRefiner<S1, S2> extends
40 PairMatchesAndInliersDataRefiner<ProjectiveTransformation3D, S1, S2> {
41
42 /**
43 * Standard deviation used for Levenberg-Marquardt fitting during
44 * refinement.
45 * Returned value gives an indication of how much variance each residual
46 * has.
47 * Typically, this value is related to the threshold used on each robust
48 * estimation, since residuals of found inliers are within the range of
49 * such threshold.
50 */
51 private double refinementStandardDeviation;
52
53 /**
54 * Constructor.
55 */
56 protected ProjectiveTransformation3DRefiner() {
57 }
58
59 /**
60 * Constructor.
61 *
62 * @param initialEstimation initial estimation to be set.
63 * @param keepCovariance true if covariance of estimation must be kept after
64 * refinement, false otherwise.
65 * @param inliers set indicating which of the provided matches are inliers.
66 * @param residuals residuals for matched samples.
67 * @param numInliers number of inliers on initial estimation.
68 * @param samples1 1st set of paired samples.
69 * @param samples2 2nd set of paired samples.
70 * @param refinementStandardDeviation standard deviation used for
71 * Levenberg-Marquardt fitting.
72 */
73 protected ProjectiveTransformation3DRefiner(
74 final ProjectiveTransformation3D initialEstimation, final boolean keepCovariance, final BitSet inliers,
75 final double[] residuals, final int numInliers, final List<S1> samples1, final List<S2> samples2,
76 final double refinementStandardDeviation) {
77 super(initialEstimation, keepCovariance, inliers, residuals, numInliers, samples1, samples2);
78 this.refinementStandardDeviation = refinementStandardDeviation;
79 }
80
81 /**
82 * Constructor.
83 *
84 * @param initialEstimation initial estimation to be set.
85 * @param keepCovariance true if covariance of estimation must be kept after
86 * refinement, false otherwise.
87 * @param inliersData inlier data, typically obtained from a robust
88 * estimator.
89 * @param samples1 1st set of paired samples.
90 * @param samples2 2nd set of paired samples.
91 * @param refinementStandardDeviation standard deviation used for
92 * Levenberg-Marquardt fitting.
93 */
94 protected ProjectiveTransformation3DRefiner(
95 final ProjectiveTransformation3D initialEstimation, final boolean keepCovariance,
96 final InliersData inliersData, final List<S1> samples1, final List<S2> samples2,
97 final double refinementStandardDeviation) {
98 super(initialEstimation, keepCovariance, inliersData, samples1, samples2);
99 this.refinementStandardDeviation = refinementStandardDeviation;
100 }
101
102 /**
103 * Gets standard deviation used for Levenberg-Marquardt fitting during
104 * refinement.
105 * Returned value gives an indication of how much variance each residual
106 * has.
107 * Typically, this value is related to the threshold used on each robust
108 * estimation, since residuals of found inliers are within the range of
109 * such threshold.
110 *
111 * @return standard deviation used for refinement.
112 */
113 public double getRefinementStandardDeviation() {
114 return refinementStandardDeviation;
115 }
116
117 /**
118 * Sets standard deviation used for Levenberg-Marquardt fitting during
119 * refinement.
120 * Returned value gives an indication of how much variance each residual
121 * has.
122 * Typically, this value is related to the threshold used on each robust
123 * estimation, since residuals of found inliers are within the range of such
124 * threshold.
125 *
126 * @param refinementStandardDeviation standard deviation used for
127 * refinement.
128 * @throws LockedException if estimator is locked.
129 */
130 public void setRefinementStandardDeviation(final double refinementStandardDeviation) throws LockedException {
131 if (isLocked()) {
132 throw new LockedException();
133 }
134 this.refinementStandardDeviation = refinementStandardDeviation;
135 }
136
137 /**
138 * Refines provided initial estimation.
139 *
140 * @return refines estimation.
141 * @throws NotReadyException if not enough input data has been provided.
142 * @throws LockedException if estimator is locked because refinement is
143 * already in progress.
144 * @throws RefinerException if refinement fails for some reason (e.g. unable
145 * to converge to a result).
146 */
147 @Override
148 public ProjectiveTransformation3D refine() throws NotReadyException, LockedException, RefinerException {
149 final var result = new ProjectiveTransformation3D();
150 refine(result);
151 return result;
152 }
153 }