1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.irurueta.numerical.polynomials.estimators;
17
18 import com.irurueta.numerical.LockedException;
19 import com.irurueta.numerical.NotReadyException;
20 import com.irurueta.numerical.polynomials.Polynomial;
21 import com.irurueta.numerical.robust.RANSACRobustEstimator;
22 import com.irurueta.numerical.robust.RANSACRobustEstimatorListener;
23 import com.irurueta.numerical.robust.RobustEstimator;
24 import com.irurueta.numerical.robust.RobustEstimatorException;
25 import com.irurueta.numerical.robust.RobustEstimatorMethod;
26
27 import java.util.ArrayList;
28 import java.util.List;
29
30
31
32
33 public class RANSACPolynomialRobustEstimator extends PolynomialRobustEstimator {
34
35
36
37
38
39
40
41 public static final double DEFAULT_THRESHOLD = 1e-6;
42
43
44
45
46
47 public static final double MIN_THRESHOLD = 0.0;
48
49
50
51
52
53 private double threshold;
54
55
56
57
58 public RANSACPolynomialRobustEstimator() {
59 super();
60 threshold = DEFAULT_THRESHOLD;
61 }
62
63
64
65
66
67
68
69 public RANSACPolynomialRobustEstimator(final int degree) {
70 super(degree);
71 threshold = DEFAULT_THRESHOLD;
72 }
73
74
75
76
77
78
79
80
81 public RANSACPolynomialRobustEstimator(final List<PolynomialEvaluation> evaluations) {
82 super(evaluations);
83 threshold = DEFAULT_THRESHOLD;
84 }
85
86
87
88
89
90
91
92 public RANSACPolynomialRobustEstimator(final PolynomialRobustEstimatorListener listener) {
93 super(listener);
94 threshold = DEFAULT_THRESHOLD;
95 }
96
97
98
99
100
101
102
103
104
105
106 public RANSACPolynomialRobustEstimator(final int degree, final List<PolynomialEvaluation> evaluations) {
107 super(degree, evaluations);
108 threshold = DEFAULT_THRESHOLD;
109 }
110
111
112
113
114
115
116
117
118
119 public RANSACPolynomialRobustEstimator(final int degree, final PolynomialRobustEstimatorListener listener) {
120 super(degree, listener);
121 threshold = DEFAULT_THRESHOLD;
122 }
123
124
125
126
127
128
129
130
131
132
133 public RANSACPolynomialRobustEstimator(
134 final List<PolynomialEvaluation> evaluations, final PolynomialRobustEstimatorListener listener) {
135 super(evaluations, listener);
136 threshold = DEFAULT_THRESHOLD;
137 }
138
139
140
141
142
143
144
145
146
147
148
149
150 public RANSACPolynomialRobustEstimator(
151 final int degree, final List<PolynomialEvaluation> evaluations,
152 final PolynomialRobustEstimatorListener listener) {
153 super(degree, evaluations, listener);
154 threshold = DEFAULT_THRESHOLD;
155 }
156
157
158
159
160
161
162
163
164 public double getThreshold() {
165 return threshold;
166 }
167
168
169
170
171
172
173
174
175
176
177
178 public void setThreshold(final double threshold) throws LockedException {
179 if (isLocked()) {
180 throw new LockedException();
181 }
182 if (threshold <= MIN_THRESHOLD) {
183 throw new IllegalArgumentException();
184 }
185 this.threshold = threshold;
186 }
187
188
189
190
191
192
193
194
195
196
197
198
199
200 @Override
201 public Polynomial estimate() throws LockedException, NotReadyException, RobustEstimatorException {
202 if (isLocked()) {
203 throw new LockedException();
204 }
205 if (!isReady()) {
206 throw new NotReadyException();
207 }
208
209 final RANSACRobustEstimator<Polynomial> innerEstimator = new RANSACRobustEstimator<>(
210 new RANSACRobustEstimatorListener<>() {
211
212
213 private final List<PolynomialEvaluation> subsetEvaluations = new ArrayList<>();
214
215 @Override
216 public double getThreshold() {
217 return threshold;
218 }
219
220 @Override
221 public int getTotalSamples() {
222 return evaluations.size();
223 }
224
225 @Override
226 public int getSubsetSize() {
227 return polynomialEstimator.getMinNumberOfEvaluations();
228 }
229
230 @Override
231 public void estimatePreliminarSolutions(
232 final int[] samplesIndices, final List<Polynomial> solutions) {
233 subsetEvaluations.clear();
234 for (var samplesIndex : samplesIndices) {
235 subsetEvaluations.add(evaluations.get(samplesIndex));
236 }
237
238 try {
239 polynomialEstimator.setLMSESolutionAllowed(false);
240 polynomialEstimator.setEvaluations(subsetEvaluations);
241
242 final var polynomial = polynomialEstimator.estimate();
243 solutions.add(polynomial);
244 } catch (Exception e) {
245
246 }
247 }
248
249 @Override
250 public double computeResidual(final Polynomial currentEstimation, final int i) {
251 final var eval = evaluations.get(i);
252 return getDistance(eval, currentEstimation);
253 }
254
255 @Override
256 public boolean isReady() {
257 return RANSACPolynomialRobustEstimator.this.isReady();
258 }
259
260 @Override
261 public void onEstimateStart(final RobustEstimator<Polynomial> estimator) {
262 if (listener != null) {
263 listener.onEstimateStart(RANSACPolynomialRobustEstimator.this);
264 }
265 }
266
267 @Override
268 public void onEstimateEnd(final RobustEstimator<Polynomial> estimator) {
269 if (listener != null) {
270 listener.onEstimateEnd(RANSACPolynomialRobustEstimator.this);
271 }
272 }
273
274 @Override
275 public void onEstimateNextIteration(
276 final RobustEstimator<Polynomial> estimator, final int iteration) {
277 if (listener != null) {
278 listener.onEstimateNextIteration(RANSACPolynomialRobustEstimator.this, iteration);
279 }
280 }
281
282 @Override
283 public void onEstimateProgressChange(
284 final RobustEstimator<Polynomial> estimator, final float progress) {
285 if (listener != null) {
286 listener.onEstimateProgressChange(RANSACPolynomialRobustEstimator.this, progress);
287 }
288 }
289 });
290
291 try {
292 locked = true;
293 innerEstimator.setConfidence(confidence);
294 innerEstimator.setMaxIterations(maxIterations);
295 innerEstimator.setProgressDelta(progressDelta);
296 return innerEstimator.estimate();
297 } finally {
298 locked = false;
299 }
300 }
301
302
303
304
305
306
307 @Override
308 public RobustEstimatorMethod getMethod() {
309 return RobustEstimatorMethod.RANSAC;
310 }
311 }