1 /* 2 * Copyright (C) 2015 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.ar.epipolar.estimators; 17 18 import com.irurueta.ar.epipolar.FundamentalMatrix; 19 import com.irurueta.geometry.Point2D; 20 import com.irurueta.geometry.estimators.LockedException; 21 import com.irurueta.geometry.estimators.NotReadyException; 22 23 import java.util.List; 24 25 /** 26 * Base class for a non-robust fundamental matrix estimator. 27 */ 28 public abstract class FundamentalMatrixEstimator { 29 30 /** 31 * Default method for non-robust fundamental matrix estimation. 32 */ 33 public static final FundamentalMatrixEstimatorMethod DEFAULT_METHOD = 34 FundamentalMatrixEstimatorMethod.SEVEN_POINTS_ALGORITHM; 35 36 /** 37 * Listener to be notified of events generated by this fundamental matrix 38 * estimator. 39 */ 40 protected FundamentalMatrixEstimatorListener listener; 41 42 /** 43 * List of 2D points corresponding to left view. 44 */ 45 protected List<Point2D> leftPoints; 46 47 /** 48 * List of 2D points corresponding to right view. 49 */ 50 protected List<Point2D> rightPoints; 51 52 /** 53 * Indicates whether this instance is locked because estimation is being 54 * computed. 55 */ 56 protected boolean locked; 57 58 /** 59 * Constructor. 60 */ 61 protected FundamentalMatrixEstimator() { 62 } 63 64 /** 65 * Constructor with matched 2D points. 66 * 67 * @param leftPoints 2D points on left view. 68 * @param rightPoints 2D points on right view. 69 * @throws IllegalArgumentException if provided list of points do not 70 * have the same length. 71 */ 72 protected FundamentalMatrixEstimator(final List<Point2D> leftPoints, final List<Point2D> rightPoints) { 73 internalSetPoints(leftPoints, rightPoints); 74 } 75 76 /** 77 * Returns matched 2D points on left view. 78 * 79 * @return 2D points on left view. 80 */ 81 public List<Point2D> getLeftPoints() { 82 return leftPoints; 83 } 84 85 /** 86 * Returns matched 2D points on right view. 87 * 88 * @return 2D points on right view. 89 */ 90 public List<Point2D> getRightPoints() { 91 return rightPoints; 92 } 93 94 /** 95 * Sets matched 2D points on both left and right views. 96 * 97 * @param leftPoints matched 2D points on left view. 98 * @param rightPoints matched 2D points on right view. 99 * @throws LockedException if this fundamental matrix estimator is locked. 100 * @throws IllegalArgumentException if provided matched points on left and 101 * right views do not have the same length. 102 */ 103 public void setPoints(final List<Point2D> leftPoints, final List<Point2D> rightPoints) throws LockedException { 104 if (isLocked()) { 105 throw new LockedException(); 106 } 107 108 internalSetPoints(leftPoints, rightPoints); 109 } 110 111 /** 112 * Returns listener to be notified of events generated by this fundamental 113 * matrix estimator. 114 * 115 * @return listener to be notified of events generated by this fundamental 116 * matrix estimator. 117 */ 118 public FundamentalMatrixEstimatorListener getListener() { 119 return listener; 120 } 121 122 /** 123 * Sets listener to be notified of events generated by this fundamental 124 * matrix estimator. 125 * 126 * @param listener listener to be notified of events generated by this 127 * fundamental matrix estimator. 128 * @throws LockedException if this estimator is locked. 129 */ 130 public void setListener(final FundamentalMatrixEstimatorListener listener) throws LockedException { 131 if (isLocked()) { 132 throw new LockedException(); 133 } 134 135 this.listener = listener; 136 } 137 138 /** 139 * Returns boolean indicating if estimator is locked because estimation is 140 * under progress. 141 * 142 * @return true if estimator is locked, false otherwise. 143 */ 144 public boolean isLocked() { 145 return locked; 146 } 147 148 /** 149 * Returns boolean indicating whether estimator is ready to start the 150 * fundamental matrix estimation. 151 * This is true when the required number of matched points is provided to 152 * obtain a solution. 153 * 154 * @return true if estimator is ready to start the fundamental matrix 155 * estimation, false otherwise. 156 */ 157 public abstract boolean isReady(); 158 159 /** 160 * Estimates a fundamental matrix using provided lists of matched points on 161 * left and right views. 162 * 163 * @return a fundamental matrix. 164 * @throws LockedException if estimator is locked doing an estimation. 165 * @throws NotReadyException if estimator is not ready because required 166 * input points have not already been provided. 167 * @throws FundamentalMatrixEstimatorException if configuration of provided 168 * 2D points is degenerate and fundamental matrix 169 * estimation fails. 170 */ 171 public abstract FundamentalMatrix estimate() throws LockedException, NotReadyException, 172 FundamentalMatrixEstimatorException; 173 174 /** 175 * Returns method of non-robust fundamental matrix estimator. 176 * 177 * @return method of fundamental matrix estimator. 178 */ 179 public abstract FundamentalMatrixEstimatorMethod getMethod(); 180 181 /** 182 * Returns minimum number of matched pair of points required to start 183 * the estimation. 184 * 185 * @return minimum number of matched pair of points required to start 186 * the estimation. 187 */ 188 public abstract int getMinRequiredPoints(); 189 190 /** 191 * Creates an instance of a fundamental matrix estimator using provided 192 * method. 193 * 194 * @param method a fundamental matrix estimator method. 195 * @return an instance of a fundamental matrix estimator. 196 */ 197 public static FundamentalMatrixEstimator create(final FundamentalMatrixEstimatorMethod method) { 198 return switch (method) { 199 case AFFINE_ALGORITHM -> new AffineFundamentalMatrixEstimator(); 200 case EIGHT_POINTS_ALGORITHM -> new EightPointsFundamentalMatrixEstimator(); 201 default -> new SevenPointsFundamentalMatrixEstimator(); 202 }; 203 } 204 205 /** 206 * Creates an instance of a fundamental matrix estimator using provided 207 * matched 2D points on left and right views and provided method. 208 * 209 * @param leftPoints matched 2D points on left view. 210 * @param rightPoints matched 2D points on right view. 211 * @param method a fundamental matrix estimator method. 212 * @return an instance of a fundamental matrix estimator. 213 * @throws IllegalArgumentException if provided list of points do not 214 * have the same length. 215 */ 216 public static FundamentalMatrixEstimator create( 217 final List<Point2D> leftPoints, final List<Point2D> rightPoints, 218 final FundamentalMatrixEstimatorMethod method) { 219 return switch (method) { 220 case AFFINE_ALGORITHM -> new AffineFundamentalMatrixEstimator(leftPoints, rightPoints); 221 case EIGHT_POINTS_ALGORITHM -> new EightPointsFundamentalMatrixEstimator(leftPoints, rightPoints); 222 default -> new SevenPointsFundamentalMatrixEstimator(leftPoints, rightPoints); 223 }; 224 } 225 226 /** 227 * Creates an instance of a fundamental matrix estimator using default 228 * method. 229 * 230 * @return an instance of a fundamental matrix estimator. 231 */ 232 public static FundamentalMatrixEstimator create() { 233 return create(DEFAULT_METHOD); 234 } 235 236 /** 237 * Creates an instance of a fundamental matrix estimator using provided 238 * matched 2D points on left and right views and default method. 239 * 240 * @param leftPoints matched 2D points on left view. 241 * @param rightPoints matched 2D points on right view. 242 * @return an instance of a fundamental matrix estimator. 243 * @throws IllegalArgumentException if provided list of points do not 244 * have the same length. 245 */ 246 public static FundamentalMatrixEstimator create(final List<Point2D> leftPoints, final List<Point2D> rightPoints) { 247 return create(leftPoints, rightPoints, DEFAULT_METHOD); 248 } 249 250 /** 251 * Sets matched 2D points on left and right views. 252 * This method does not check whether instance is locked or not. 253 * 254 * @param leftPoints matched 2D points on left view. 255 * @param rightPoints matched 2D points on right view. 256 * @throws IllegalArgumentException if provided lists of points don't have 257 * the same size. 258 */ 259 private void internalSetPoints(final List<Point2D> leftPoints, final List<Point2D> rightPoints) { 260 if (leftPoints.size() != rightPoints.size()) { 261 throw new IllegalArgumentException(); 262 } 263 264 this.leftPoints = leftPoints; 265 this.rightPoints = rightPoints; 266 } 267 }