latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 2002, 2003, 2004, 2005, 2006 00003 * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany 00004 * 00005 * This file is part of the LTI-Computer Vision Library (LTI-Lib) 00006 * 00007 * The LTI-Lib is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public License (LGPL) 00009 * as published by the Free Software Foundation; either version 2.1 of 00010 * the License, or (at your option) any later version. 00011 * 00012 * The LTI-Lib is distributed in the hope that it will be 00013 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 00014 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with the LTI-Lib; see the file LICENSE. If 00019 * not, write to the Free Software Foundation, Inc., 59 Temple Place - 00020 * Suite 330, Boston, MA 02111-1307, USA. 00021 */ 00022 00023 00024 /*-------------------------------------------------------------------- 00025 * project ....: LTI-Lib: Image Processing and Computer Vision Library 00026 * file .......: fundamentalMatrixSolverLMS.h 00027 * authors ....: Frederik Lange 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 7.1.2002 00030 * revisions ..: $Id: ltiFMatrixSolverLMS.h,v 1.8 2006/02/08 11:05:10 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_FUND_SOLVER_LMS_H_ 00034 #define _LTI_FUND_SOLVER_LMS_H_ 00035 00036 //TODO: include only those files which are needed in this header!! 00037 00038 #include "ltiEigenSystem.h" 00039 #include "ltiPointList.h" 00040 #include "ltiImage.h" 00041 #include "ltiTransform.h" 00042 00043 namespace lti { 00044 00045 /** 00046 * This Algorithm determines the fundamental matrix from point 00047 * correnspondences in two images. 00048 * 00049 * It is the least median of squares method (LMS). 00050 * 00051 * Algorithm outline: 00052 * 00053 * For each iteration 00054 * 00055 * -# choose a subset of 8 points randomly 00056 * the algorithm also works with more than 8 points, what could 00057 * be interesting to increase the accuracy of the result 00058 * when the used samples are all inliers 00059 * (sub-pixel-accuracy) 00060 * 00061 * -# estimate the fundamental matrix for this subset 00062 * using singular value decomposition 00063 * 00064 * -# calculate the residual for all samples 00065 * (we have choosen to take the distance from the 00066 * epipolar line in image 2) 00067 * 00068 * -# take the median of the resulting distances and compare it with 00069 * the best previous median (and maybe swap) 00070 * it would also be possible to count the number of 00071 * conform samples and take the maximum of them 00072 * this is called RANSAC 00073 * 00074 * This is repeated until a threshold for the median of the 00075 * residuals or the maximum number of iterations is reached 00076 * 00077 * enforce the rank 2 constraint of the resulting fmatrix 00078 */ 00079 00080 class fundamentalMatrixSolverLMS : public transform { 00081 public: 00082 /** 00083 * the parameters for the class fundamentalMatrixSolverLMS 00084 */ 00085 class parameters : public transform::parameters { 00086 public: 00087 /** 00088 * default constructor 00089 */ 00090 parameters(); 00091 00092 /** 00093 * copy constructor 00094 * @param other the parameters object to be copied 00095 */ 00096 parameters(const parameters& other); 00097 00098 /** 00099 * destructor 00100 */ 00101 ~parameters(); 00102 00103 /** 00104 * returns name of this type 00105 */ 00106 const char* getTypeName() const; 00107 00108 /** 00109 * copy the contents of a parameters object 00110 * @param other the parameters object to be copied 00111 * @return a reference to this parameters object 00112 */ 00113 parameters& copy(const parameters& other); 00114 00115 /** 00116 * copy the contents of a parameters object 00117 * @param other the parameters object to be copied 00118 * @return a reference to this parameters object 00119 */ 00120 parameters& operator=(const parameters& other); 00121 00122 00123 /** 00124 * returns a pointer to a clone of the parameters 00125 */ 00126 virtual functor::parameters* clone() const; 00127 00128 /** 00129 * write the parameters in the given ioHandler 00130 * @param handler the ioHandler to be used 00131 * @param complete if true (the default) the enclosing begin/end will 00132 * be also written, otherwise only the data block will be written. 00133 * @return true if write was successful 00134 */ 00135 virtual bool write(ioHandler& handler,const bool complete=true) const; 00136 00137 /** 00138 * read the parameters from the given ioHandler 00139 * @param handler the ioHandler to be used 00140 * @param complete if true (the default) the enclosing begin/end will 00141 * be also written, otherwise only the data block will be written. 00142 * @return true if write was successful 00143 */ 00144 virtual bool read(ioHandler& handler,const bool complete=true); 00145 00146 # ifdef _LTI_MSC_6 00147 /** 00148 * this function is required by MSVC only, as a workaround for a 00149 * very awful bug, which exists since MSVC V.4.0, and still by 00150 * V.6.0 with all bugfixes (so called "service packs") remains 00151 * there... This method is also public due to another bug, so please 00152 * NEVER EVER call this method directly: use read() instead 00153 */ 00154 bool readMS(ioHandler& handler,const bool complete=true); 00155 00156 /** 00157 * this function is required by MSVC only, as a workaround for a 00158 * very awful bug, which exists since MSVC V.4.0, and still by 00159 * V.6.0 with all bugfixes (so called "service packs") remains 00160 * there... This method is also public due to another bug, so please 00161 * NEVER EVER call this method directly: use write() instead 00162 */ 00163 bool writeMS(ioHandler& handler,const bool complete=true) const; 00164 # endif 00165 00166 // ------------------------------------------------ 00167 // the parameters 00168 // ------------------------------------------------ 00169 00170 //TODO: comment the parameters of your functor 00171 // If you add more parameters manually, do not forget to do following: 00172 // 1. indicate in the default constructor the default values 00173 // 2. make sure that the copy member also copy your new parameters 00174 // 3. make sure that the read and write members also read and 00175 // write your parameters 00176 00177 00178 /** 00179 * gives the maximum nuber of trials 00180 */ 00181 int numTrials; 00182 00183 /** 00184 * the threshold for the minimal median of the distances of the 00185 * points to their epipolar lines 00186 */ 00187 double threshold; 00188 00189 }; 00190 00191 /** 00192 * default constructor 00193 */ 00194 fundamentalMatrixSolverLMS(); 00195 00196 /** 00197 * copy constructor 00198 * @param other the object to be copied 00199 */ 00200 fundamentalMatrixSolverLMS(const fundamentalMatrixSolverLMS& other); 00201 00202 /** 00203 * destructor 00204 */ 00205 virtual ~fundamentalMatrixSolverLMS(); 00206 00207 /** 00208 * returns the name of this type ("fundamentalMatrixSolverLMS") 00209 */ 00210 virtual const char* getTypeName() const; 00211 00212 //TODO: comment your apply methods! 00213 00214 /** 00215 * Computes the fundamental matrix assuming the the corresponding 00216 * points occupies the same relative position in the lists l1 and l2. 00217 * 00218 * @param l1 first list of points. It must have the same length t 00219 * @param l2 second list of points 00220 * @param fMatrix the resulting fundamental matrix. It will be a 00221 * a 3x3 matrix, the fundamental matrix 00222 * 00223 * @return true if apply successful or false otherwise. 00224 */ 00225 bool apply(const tpointList<double>& l1, 00226 const tpointList<double>& l2, 00227 matrix<double>& fMatrix) const; 00228 00229 /** 00230 * operates on the given %parameter. 00231 * integer vesion (data is converted to floatingpoint) 00232 * @return true if apply successful or false otherwise. 00233 */ 00234 bool apply(const pointList& l1, 00235 const pointList& l2, 00236 matrix<double>& fMatrix) const; 00237 00238 00239 /** 00240 * copy data of "other" functor. 00241 * @param other the functor to be copied 00242 * @return a reference to this functor object 00243 */ 00244 fundamentalMatrixSolverLMS& copy(const fundamentalMatrixSolverLMS& other); 00245 00246 /** 00247 * alias for copy member 00248 * @param other the functor to be copied 00249 * @return a reference to this functor object 00250 */ 00251 fundamentalMatrixSolverLMS& operator=(const fundamentalMatrixSolverLMS& other); 00252 00253 /** 00254 * returns a pointer to a clone of this functor. 00255 */ 00256 virtual functor* clone() const; 00257 00258 /** 00259 * returns used parameters 00260 */ 00261 const parameters& getParameters() const; 00262 00263 //TODO: comment the attributes of your functor 00264 // If you add more attributes manually, do not forget to do following: 00265 // 1. indicate in the default constructor the default values 00266 // 2. make sure that the copy member also copy your new attributes, or 00267 // to ensure there, that these attributes are properly initialized. 00268 00269 00270 /** 00271 * builds the pointMatrix from the point-correspondences 00272 * needed for the calculation of the residual 00273 */ 00274 void buildPointMatrix(const tpointList<double>& l1, 00275 const tpointList<double>& l2, 00276 matrix<double> &pointMatrix) const; 00277 00278 /** 00279 * calculates the residual for each point correspondence 00280 * in our case the residual is the distance of the point 00281 * to its corresponding epipolar line 00282 */ 00283 double calcResidual(const matrix<double> &pointMatrix, 00284 const matrix<double> &fundMatrix, 00285 vector<double> &resid) const; 00286 00287 00288 protected: 00289 void buildMomentMatrix(const matrix<double> &pointMatrix, 00290 matrix<double> &momentMatrix) const; 00291 00292 void buildMomentMatrixRandom(const matrix<double> &pointMatrix, 00293 const int numSamples, 00294 matrix<double> &momentMatrix, 00295 vector<int> &select) const; 00296 00297 void calcFundMat(const matrix<double> &momentMatrix, 00298 matrix<double> &fundMatrix) const; 00299 00300 }; 00301 } 00302 00303 #endif