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; 17 18 import com.irurueta.geometry.Point2D; 19 import com.irurueta.geometry.estimators.NotReadyException; 20 21 /** 22 * Fixes a single matched pair of points so that they perfectly follow a given 23 * epipolar geometry. 24 * When matching points typically the matching precision is about 1 pixel, 25 * however this makes that matched points under a given epipolar geometry (i.e. 26 * fundamental or essential matrix), do not lie perfectly on the corresponding 27 * epipolar plane or epipolar lines. 28 * The consequence is that triangularization of these matches will fail or 29 * produce inaccurate results. 30 * By fixing matched points using a corrector following a given epipolar 31 * geometry, this effect is alleviated. 32 * This is an abstract class, subclasses will implement different methods to 33 * fix matched points coordinates 34 */ 35 public abstract class SingleCorrector { 36 37 /** 38 * Default corrector type. 39 */ 40 public static final CorrectorType DEFAULT_TYPE = CorrectorType.GOLD_STANDARD; 41 42 /** 43 * Left matched point to be corrected. 44 */ 45 protected Point2D leftPoint; 46 47 /** 48 * Right matched point to be corrected. 49 */ 50 protected Point2D rightPoint; 51 52 /** 53 * Left matched point after correction. 54 */ 55 protected Point2D leftCorrectedPoint; 56 57 /** 58 * Right matched point after correction. 59 */ 60 protected Point2D rightCorrectedPoint; 61 62 /** 63 * A fundamental matrix defining an epipolar geometry. 64 */ 65 protected FundamentalMatrix fundamentalMatrix; 66 67 /** 68 * Constructor. 69 */ 70 protected SingleCorrector() { 71 } 72 73 /** 74 * Constructor. 75 * 76 * @param fundamentalMatrix fundamental matrix defining the epipolar 77 * geometry. 78 */ 79 protected SingleCorrector(final FundamentalMatrix fundamentalMatrix) { 80 setFundamentalMatrix(fundamentalMatrix); 81 } 82 83 /** 84 * Constructor. 85 * 86 * @param leftPoint matched point on left view to be corrected. 87 * @param rightPoint matched point on right view to be corrected. 88 */ 89 protected SingleCorrector(final Point2D leftPoint, final Point2D rightPoint) { 90 setPoints(leftPoint, rightPoint); 91 } 92 93 /** 94 * Constructor. 95 * 96 * @param leftPoint matched point on left view to be corrected. 97 * @param rightPoint matched point on right view to be corrected. 98 * @param fundamentalMatrix fundamental matrix defining an epipolar geometry. 99 */ 100 protected SingleCorrector(final Point2D leftPoint, final Point2D rightPoint, 101 final FundamentalMatrix fundamentalMatrix) { 102 setPointsAndFundamentalMatrix(leftPoint, rightPoint, fundamentalMatrix); 103 } 104 105 /** 106 * Sets a matched pair of points to be corrected and a fundamental matrix 107 * defining the epipolar geometry. 108 * 109 * @param leftPoint matched point on left view to be corrected. 110 * @param rightPoint matched point on right view to be corrected. 111 * @param fundamentalMatrix fundamental matrix defining an epipolar geometry. 112 */ 113 public final void setPointsAndFundamentalMatrix( 114 final Point2D leftPoint, final Point2D rightPoint, final FundamentalMatrix fundamentalMatrix) { 115 setPoints(leftPoint, rightPoint); 116 setFundamentalMatrix(fundamentalMatrix); 117 } 118 119 /** 120 * Sets a matched pair of points to be corrected. 121 * 122 * @param leftPoint matched point on left view to be corrected. 123 * @param rightPoint matched point on right view to be corrected. 124 */ 125 public final void setPoints(final Point2D leftPoint, final Point2D rightPoint) { 126 this.leftPoint = leftPoint; 127 this.rightPoint = rightPoint; 128 } 129 130 /** 131 * Sets the fundamental matrix defining the epipolar geometry. 132 * 133 * @param fundamentalMatrix fundamental matrix to be set. 134 */ 135 public final void setFundamentalMatrix(final FundamentalMatrix fundamentalMatrix) { 136 this.fundamentalMatrix = fundamentalMatrix; 137 } 138 139 /** 140 * Returns matched point on left view. 141 * 142 * @return matched point on left view. 143 */ 144 public Point2D getLeftPoint() { 145 return leftPoint; 146 } 147 148 /** 149 * Returns matched point on right view. 150 * 151 * @return matched point on right view. 152 */ 153 public Point2D getRightPoint() { 154 return rightPoint; 155 } 156 157 /** 158 * Returns fundamental matrix defining epipolar geometry. 159 * 160 * @return fundamental matrix defining epipolar geometry. 161 */ 162 public FundamentalMatrix getFundamentalMatrix() { 163 return fundamentalMatrix; 164 } 165 166 /** 167 * Indicates whether this instance is ready to correct provided left 168 * and right points using provided fundamental matrix. 169 * 170 * @return true if ready, false otherwise. 171 */ 172 public boolean isReady() { 173 return leftPoint != null && rightPoint != null && fundamentalMatrix != null 174 && fundamentalMatrix.isInternalMatrixAvailable(); 175 } 176 177 /** 178 * Returns matched point on left view after correction. 179 * 180 * @return matched point on left view after correction. 181 */ 182 public Point2D getLeftCorrectedPoint() { 183 return leftCorrectedPoint; 184 } 185 186 /** 187 * Returns matched point on right view after correction. 188 * 189 * @return matched point on right view after correction. 190 */ 191 public Point2D getRightCorrectedPoint() { 192 return rightCorrectedPoint; 193 } 194 195 /** 196 * Corrects the pair of provided matched points to be corrected. 197 * 198 * @throws NotReadyException if this instance is not ready (either points or 199 * fundamental matrix has not been provided yet). 200 * @throws CorrectionException if correction fails. 201 */ 202 public abstract void correct() throws NotReadyException, CorrectionException; 203 204 /** 205 * Gets type of correction being used. 206 * 207 * @return type of correction. 208 */ 209 public abstract CorrectorType getType(); 210 211 /** 212 * Creates an instance of a single corrector using provided type. 213 * 214 * @param type a corrector type. 215 * @return an instance of a single corrector. 216 */ 217 public static SingleCorrector create(final CorrectorType type) { 218 return type == CorrectorType.SAMPSON_CORRECTOR 219 ? new SampsonSingleCorrector() : new GoldStandardSingleCorrector(); 220 } 221 222 /** 223 * Creates an instance of a single corrector using provided fundamental 224 * matrix and provided type. 225 * 226 * @param fundamentalMatrix fundamental matrix defining the epipolar 227 * geometry. 228 * @param type a corrector type. 229 * @return an instance of a single corrector. 230 */ 231 public static SingleCorrector create(final FundamentalMatrix fundamentalMatrix, final CorrectorType type) { 232 return type == CorrectorType.SAMPSON_CORRECTOR 233 ? new SampsonSingleCorrector(fundamentalMatrix) : new GoldStandardSingleCorrector(fundamentalMatrix); 234 } 235 236 /** 237 * Creates an instance of a single corrector using provided left and right 238 * points to be corrected, and provided type. 239 * 240 * @param leftPoint matched point on left view to be corrected. 241 * @param rightPoint matched point on right view to be corrected. 242 * @param type a corrector type. 243 * @return an instance of a single corrector. 244 */ 245 public static SingleCorrector create(final Point2D leftPoint, final Point2D rightPoint, final CorrectorType type) { 246 return type == CorrectorType.SAMPSON_CORRECTOR 247 ? new SampsonSingleCorrector(leftPoint, rightPoint) 248 : new GoldStandardSingleCorrector(leftPoint, rightPoint); 249 } 250 251 /** 252 * Creates an instance of a single corrector using provided left and right 253 * points to be corrected, fundamental matrix and provided type. 254 * 255 * @param leftPoint matched point on left view to be corrected. 256 * @param rightPoint matched point on right view to be corrected. 257 * @param fundamentalMatrix fundamental matrix defining the epipolar 258 * geometry. 259 * @param type a corrector type. 260 * @return an instance of a single corrector. 261 */ 262 public static SingleCorrector create( 263 final Point2D leftPoint, final Point2D rightPoint, final FundamentalMatrix fundamentalMatrix, 264 final CorrectorType type) { 265 return type == CorrectorType.SAMPSON_CORRECTOR 266 ? new SampsonSingleCorrector(leftPoint, rightPoint, fundamentalMatrix) 267 : new GoldStandardSingleCorrector(leftPoint, rightPoint, fundamentalMatrix); 268 } 269 270 /** 271 * Creates an instance of a single corrector using default type. 272 * 273 * @return an instance of a single corrector. 274 */ 275 public static SingleCorrector create() { 276 return create(DEFAULT_TYPE); 277 } 278 279 /** 280 * Creates an instance of a single corrector using provided fundamental 281 * matrix and default type. 282 * 283 * @param fundamentalMatrix fundamental matrix defining the epipolar 284 * geometry. 285 * @return an instance of a single corrector. 286 */ 287 public static SingleCorrector create(final FundamentalMatrix fundamentalMatrix) { 288 return create(fundamentalMatrix, DEFAULT_TYPE); 289 } 290 291 /** 292 * Creates an instance of a single corrector using provided left and right 293 * points to be corrected. 294 * 295 * @param leftPoint matched point on left view to be corrected. 296 * @param rightPoint matched point on right view to be corrected. 297 * @return an instance of a single corrector. 298 */ 299 public static SingleCorrector create(final Point2D leftPoint, final Point2D rightPoint) { 300 return create(leftPoint, rightPoint, DEFAULT_TYPE); 301 } 302 303 /** 304 * Creates an instance of a single corrector using provided left and right 305 * points to be corrected, provided fundamental matrix and default type. 306 * 307 * @param leftPoint matched point on left view to be corrected. 308 * @param rightPoint matched point on right view to be corrected. 309 * @param fundamentalMatrix fundamental matrix defining the epipolar 310 * geometry. 311 * @return an instance of a single corrector. 312 */ 313 public static SingleCorrector create( 314 final Point2D leftPoint, final Point2D rightPoint, 315 final FundamentalMatrix fundamentalMatrix) { 316 return create(leftPoint, rightPoint, fundamentalMatrix, DEFAULT_TYPE); 317 } 318 }