View Javadoc
1   /*
2    * Copyright (C) 2013 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.numerical.robust;
17  
18  import com.irurueta.numerical.LockedException;
19  import com.irurueta.numerical.NotReadyException;
20  
21  /**
22   * Robust estimator to estimate some object in a robust manner
23   *
24   * @param <T> Object to be estimated (i.e. lines, cameras, etc)
25   */
26  public abstract class RobustEstimator<T> {
27  
28      /**
29       * Default amount of progress variation before notifying a change in
30       * estimation progress. By default, this is set to 5%
31       */
32      public static final float DEFAULT_PROGRESS_DELTA = 0.05f;
33  
34      /**
35       * Minimum allowed value for progress delta
36       */
37      public static final float MIN_PROGRESS_DELTA = 0.0f;
38  
39      /**
40       * Maximum allowed value for progress delta.
41       */
42      public static final float MAX_PROGRESS_DELTA = 1.0f;
43  
44      /**
45       * Listener to be notified of events such as when estimation starts, ends
46       * or its progress significantly changes.
47       */
48      protected RobustEstimatorListener<T> listener;
49  
50      /**
51       * Indicates if this estimator is locked because an estimation is being
52       * computed.
53       */
54      protected volatile boolean locked;
55  
56      /**
57       * Amount of progress variation before notifying a progress change during
58       * estimation.
59       */
60      protected float progressDelta;
61  
62      /**
63       * Constructor.
64       */
65      protected RobustEstimator() {
66          listener = null;
67          locked = false;
68          progressDelta = DEFAULT_PROGRESS_DELTA;
69      }
70  
71      /**
72       * Constructor.
73       *
74       * @param listener listener to be notified of events such as when estimation
75       *                 starts, ends or its progress significantly changes.
76       */
77      protected RobustEstimator(final RobustEstimatorListener<T> listener) {
78          this.listener = listener;
79          locked = false;
80          progressDelta = DEFAULT_PROGRESS_DELTA;
81      }
82  
83      /**
84       * Returns reference to listener to be notified of events such as when
85       * estimation starts, ends or its progress significantly changes.
86       *
87       * @return listener to be notified of events.
88       */
89      public RobustEstimatorListener<T> getListener() {
90          return listener;
91      }
92  
93      /**
94       * Sets listener to be notified of events such as when estimation starts,
95       * ends or its progress significantly changes.
96       *
97       * @param listener listener to be notified of events.
98       * @throws LockedException if robust estimator is locked.
99       */
100     public void setListener(final RobustEstimatorListener<T> listener) throws LockedException {
101         if (isLocked()) {
102             throw new LockedException();
103         }
104         this.listener = listener;
105     }
106 
107     /**
108      * Indicates whether listener has been provided and is available for
109      * retrieval.
110      *
111      * @return true if available, false otherwise.
112      */
113     public boolean isListenerAvailable() {
114         return listener != null;
115     }
116 
117     /**
118      * Indicates if this instance is locked because estimation is being computed.
119      *
120      * @return true if locked, false otherwise.
121      */
122     public boolean isLocked() {
123         return locked;
124     }
125 
126     /**
127      * Returns amount of progress variation before notifying a progress change
128      * during estimation.
129      *
130      * @return amount of progress variation before notifying a progress change
131      * during estimation.
132      */
133     public float getProgressDelta() {
134         return progressDelta;
135     }
136 
137     /**
138      * Sets amount of progress variation before notifying a progress change
139      * during estimation.
140      *
141      * @param progressDelta amount of progress variation before notifying a
142      *                      progress change during estimation.
143      * @throws IllegalArgumentException if progress delta is less than zero or
144      *                                  greater than 1.
145      * @throws LockedException          if this estimator is locked because an estimation
146      *                                  is being computed.
147      */
148     public void setProgressDelta(final float progressDelta) throws LockedException {
149         if (isLocked()) {
150             throw new LockedException();
151         }
152         if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
153             throw new IllegalArgumentException();
154         }
155         this.progressDelta = progressDelta;
156     }
157 
158     /**
159      * Robustly estimates an instance of T.
160      *
161      * @return estimated object.
162      * @throws LockedException          if robust estimator is locked.
163      * @throws NotReadyException        if provided input data is not enough to start
164      *                                  the estimation.
165      * @throws RobustEstimatorException if estimation fails for any reason
166      *                                  (i.e. numerical instability, no solution available, etc).
167      */
168     public abstract T estimate() throws LockedException, NotReadyException, RobustEstimatorException;
169 
170     /**
171      * Returns data about inliers once estimation has been done.
172      *
173      * @return data about inliers or null if estimation has not been done.
174      */
175     public abstract InliersData getInliersData();
176 
177     /**
178      * Returns method being used for robust estimation.
179      *
180      * @return method being used for robust estimation.
181      */
182     public abstract RobustEstimatorMethod getMethod();
183 
184     /**
185      * Indicates if estimator is ready to start the estimation process.
186      *
187      * @return true if ready, false otherwise.
188      */
189     public boolean isReady() {
190         if (listener != null) {
191             return listener.isReady();
192         } else {
193             return false;
194         }
195     }
196 }