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 }