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.estimators.LockedException;
19 import com.irurueta.numerical.robust.InliersData;
20
21 import java.util.BitSet;
22
23 /**
24 * Refines an instance of type T by taking into account an initial estimation,
25 * inlier matches and their residuals.
26 * This class can be used to find a solution that minimizes error of inliers in
27 * LMSE terms.
28 * Typically, a refiner is used by a robust estimator, however it can also be
29 * useful in some other situations.
30 *
31 * @param <T> type of instance to be refined.
32 */
33 public abstract class InliersDataRefiner<T> extends Refiner<T> {
34 /**
35 * Array indicating which of the provided matches are inliers.
36 */
37 protected BitSet inliers;
38
39 /**
40 * Residuals for matched data corresponding to the initial estimation.
41 * Residuals are used to determine the amount of precision of each match
42 * in order to find a refined solution that minimizes the LMSE error of all
43 * inlier matches.
44 */
45 protected double[] residuals;
46
47 /**
48 * Number of inliers on initial estimation.
49 */
50 protected int numInliers;
51
52 /**
53 * Constructor.
54 */
55 protected InliersDataRefiner() {
56 }
57
58 /**
59 * Constructor.
60 *
61 * @param initialEstimation initial estimation to be set.
62 * @param keepCovariance true if covariance of estimation must be kept after
63 * refinement, false otherwise.
64 * @param inliers set indicating which of the provided matches are inliers.
65 * @param residuals residuals for matched samples.
66 * @param numInliers number of inliers on initial estimation.
67 */
68 protected InliersDataRefiner(final T initialEstimation, final boolean keepCovariance, final BitSet inliers,
69 final double[] residuals, final int numInliers) {
70 super(initialEstimation, keepCovariance);
71 this.inliers = inliers;
72 this.residuals = residuals;
73 this.numInliers = numInliers;
74 }
75
76 /**
77 * Constructor.
78 *
79 * @param initialEstimation initial estimation to be set.
80 * @param keepCovariance true if covariance of estimation must be kept after
81 * refinement, false otherwise.
82 * @param inliersData inlier data, typically obtained from a robust
83 * estimator.
84 */
85 protected InliersDataRefiner(final T initialEstimation, final boolean keepCovariance,
86 final InliersData inliersData) {
87 super(initialEstimation, keepCovariance);
88 inliers = inliersData.getInliers();
89 residuals = inliersData.getResiduals();
90 numInliers = inliersData.getNumInliers();
91 }
92
93 /**
94 * Gets set indicating which of the provided matches are inliers.
95 *
96 * @return set indicating which of the provided matches are inliers.
97 */
98 public BitSet getInliers() {
99 return inliers;
100 }
101
102 /**
103 * Specifies set indicating which of the provided matches are inliers.
104 *
105 * @param inliers set indicating which of the provided matches are inliers.
106 * @throws LockedException if estimator is locked.
107 */
108 public void setInliers(final BitSet inliers) throws LockedException {
109 if (isLocked()) {
110 throw new LockedException();
111 }
112 this.inliers = inliers;
113 }
114
115 /**
116 * Gets residuals for matched samples corresponding to the initial
117 * estimation.
118 * Residuals are used to determine the amount of precision of each matched
119 * sample in order to find a refined solution that minimizes the LMSE error
120 * of all inlier matches.
121 *
122 * @return residuals for matched samples.
123 */
124 public double[] getResiduals() {
125 return residuals;
126 }
127
128 /**
129 * Sets residuals for matched samples corresponding to the initial
130 * estimation.
131 * Residuals are used to determine the amount of precision of each matched
132 * sample in order to find a refined solution that minimizes the LMSE error
133 * of all inlier matches.
134 *
135 * @param residuals residuals for matched samples.
136 * @throws LockedException if estimator is locked.
137 */
138 public void setResiduals(final double[] residuals) throws LockedException {
139 if (isLocked()) {
140 throw new LockedException();
141 }
142 this.residuals = residuals;
143 }
144
145 /**
146 * Gets number of inliers on initial estimation.
147 *
148 * @return number of inliers on initial estimation.
149 */
150 public int getNumInliers() {
151 return numInliers;
152 }
153
154 /**
155 * Sets number of inliers on initial estimation.
156 *
157 * @param numInliers number of inliers on initial estimation.
158 * @throws LockedException if estimator is locked.
159 * @throws IllegalArgumentException if provided value is zero or negative.
160 */
161 public void setNumInliers(final int numInliers) throws LockedException {
162 if (isLocked()) {
163 throw new LockedException();
164 }
165 if (numInliers <= 0) {
166 throw new IllegalArgumentException();
167 }
168 this.numInliers = numInliers;
169 }
170
171 /**
172 * Gets total number of provided matched samples.
173 *
174 * @return total number of provided matched samples.
175 */
176 public int getTotalSamples() {
177 return residuals != null ? residuals.length : 0;
178 }
179
180 /**
181 * Sets inlier data.
182 *
183 * @param inliersData inlier data, typically obtained from a robust
184 * estimator.
185 * @throws LockedException if estimator is locked.
186 */
187 public void setInliersData(final InliersData inliersData) throws LockedException {
188 if (isLocked()) {
189 throw new LockedException();
190 }
191 inliers = inliersData.getInliers();
192 residuals = inliersData.getResiduals();
193 numInliers = inliersData.getNumInliers();
194 }
195 }