last update 20 Sep 2009 |
00001 /* 00002 * Copyright (C) 2008 00003 * Claudia Goenner 00004 * 00005 * This file is part of the Computer Vision and Robotics Library (CVR-Lib) 00006 * 00007 * The CVR-Lib is free software; you can redistribute it and/or 00008 * modify it under the terms of the BSD License. 00009 * 00010 * All rights reserved. 00011 * 00012 * Redistribution and use in source and binary forms, with or without 00013 * modification, are permitted provided that the following conditions are met: 00014 * 00015 * 1. Redistributions of source code must retain the above copyright notice, 00016 * this list of conditions and the following disclaimer. 00017 * 00018 * 2. Redistributions in binary form must reproduce the above copyright notice, 00019 * this list of conditions and the following disclaimer in the documentation 00020 * and/or other materials provided with the distribution. 00021 * 00022 * 3. Neither the name of the authors nor the names of its contributors may be 00023 * used to endorse or promote products derived from this software without 00024 * specific prior written permission. 00025 * 00026 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00027 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00028 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00029 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00030 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00031 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00032 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00033 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00034 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00035 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00036 * POSSIBILITY OF SUCH DAMAGE. 00037 */ 00038 00039 /** 00040 * \file cvrRansacEstimation.h 00041 * Contains the template class cvr::ransacEstimation<E>, used to 00042 * estimate any transformation E with help of the RANSAC algorithm. 00043 * 00044 * \author Claudia Goenner (Original LTI-Lib class) 00045 * \author Pablo Alvarado (Adaptation to CVR-Lib model) 00046 * \date 13.02.2008 00047 * 00048 * revisions ..: $Id: cvrRansacEstimation.h,v $ 00049 */ 00050 00051 #ifndef _CVR_RANSAC_ESTIMATION_H_ 00052 #define _CVR_RANSAC_ESTIMATION_H_ 00053 00054 00055 #include "cvrMatrix.h" 00056 #include "cvrFunctor.h" 00057 #include "cvrUniformDiscreteDistribution.h" 00058 00059 namespace cvr { 00060 00061 /** 00062 * Template Class ransacEstimation<E> 00063 * 00064 * This class estimates a transform E using the RANSAC algorithm, which is a 00065 * robust estimation approach that maximizes the number of inliers. At each 00066 * iteration a subset of points/correspondences is drawn from which the 00067 * transform is computed. 00068 * 00069 * Theoretically the RANSAC algorithm copes with up to 90% outliers. It is 00070 * advised though, to verify the estimated transform and repeat the 00071 * estimation in case the result is not satisfactory. 00072 * 00073 * The template type E corresponds to a basic estimation class like: 00074 * - cvr::euclideanTransformation2D 00075 * - cvr::similarityTransformation2D 00076 * - cvr::affineTransformation2D 00077 * 00078 * In any case, it is expected for that class E to provide the methods 00079 * - estimateLLS(const ivector&,const std::vector<P>&,const std::vector<P>&) 00080 * - dof() 00081 * 00082 * @see ransacEstimation::parameters. 00083 * 00084 * @ingroup gGeometricTrans 00085 */ 00086 template<class E> 00087 class ransacEstimation : public functor { 00088 public: 00089 /** 00090 * The parameters for the class ransacEstimation 00091 */ 00092 class parameters : public functor::parameters { 00093 public: 00094 /** 00095 * Default constructor 00096 */ 00097 parameters(); 00098 00099 /** 00100 * Copy constructor 00101 * @param other the parameters object to be copied 00102 */ 00103 parameters(const parameters& other); 00104 00105 /** 00106 * Destructor 00107 */ 00108 ~parameters(); 00109 00110 /** 00111 * Copy the contents of a parameters object 00112 * @param other the parameters object to be copied 00113 * @return a reference to this parameters object 00114 */ 00115 parameters& copy(const parameters& other); 00116 00117 /** 00118 * Copy the contents of a parameters object 00119 * @param other the parameters object to be copied 00120 * @return a reference to this parameters object 00121 */ 00122 parameters& operator=(const parameters& other); 00123 00124 /** 00125 * Returns a pointer to a clone of the parameters 00126 */ 00127 virtual parameters* clone() const; 00128 00129 /** 00130 * Returns a pointer to a new instance of the parameters 00131 */ 00132 virtual parameters* newInstance() const; 00133 00134 /** 00135 * Returns the name of this parameter class. 00136 */ 00137 virtual const std::string& name() const; 00138 00139 /** 00140 * Write the parameters in the given ioHandler 00141 * @param handler the ioHandler to be used 00142 * @param complete if true (the default) the enclosing begin/end will 00143 * be also written, otherwise only the data block will be written. 00144 * @return true if write was successful 00145 */ 00146 virtual bool write(ioHandler& handler,const bool complete=true) const; 00147 00148 /** 00149 * Read the parameters from the given ioHandler 00150 * @param handler the ioHandler to be used 00151 * @param complete if true (the default) the enclosing begin/end will 00152 * be also written, otherwise only the data block will be written. 00153 * @return true if write was successful 00154 */ 00155 virtual bool read(ioHandler& handler,const bool complete=true); 00156 00157 /** 00158 * Maximal number of iterations used while trying to converge to a 00159 * solution. 00160 * 00161 * Default: 50 00162 */ 00163 int numberOfIterations; 00164 00165 /** 00166 * Flag for automatic adjustment of the degree of contamination after 00167 * each successfull guess. 00168 * 00169 * The contamination is only decreased and never increased. This 00170 * parameter has a direct effect on the number of iterations performed. 00171 * The functor will always terminate after at most the maximum 00172 * numberOfIterations is reached, though. 00173 * 00174 * If adaptive contamination is turned on, the apply-methods return true 00175 * even if the detected inliers suggest a contamination above the 00176 * parametrized contamination. 00177 * 00178 * Default: false. 00179 */ 00180 bool adaptiveContamination; 00181 00182 /** 00183 * The number of correspondences drawn at each trial to estimate the 00184 * transformation. Literature advises to use the minimum number 00185 * correspondences that are required which is proved optimal under a 00186 * statistical context. 00187 * 00188 * The minimum number of correspondences required to estimate a 00189 * transformation can be obtained with C=(dof()+1)/2 (assuming integer 00190 * division), where dof() is a method provided in the interface of the 00191 * estimators. If the number provided here is less than that minimum C, 00192 * then C is used instead. 00193 * 00194 * Default: -1 (always use the minimum number of correspondences) 00195 * 00196 */ 00197 int numberOfCorrespondences; 00198 00199 /** 00200 * The number of trials in adaptive mode depends on the estimated 00201 * contamination and the confidence, under which the result is correct. 00202 * 00203 * Default: .99 00204 */ 00205 float confidence; 00206 00207 /** 00208 * The expected degree of contamination. This is the part of the total 00209 * correspondences that is assumed to be contaminated. 00210 * 00211 * Default: .5 00212 */ 00213 float contamination; 00214 00215 /** 00216 * The maximum error for a single correspondence or the averaged 00217 * size of the residual. 00218 * 00219 * Default: .8f 00220 */ 00221 float maxError; 00222 00223 /** 00224 * Some estimators allow configurations that you may want to control 00225 * explicitelly. These are the parameters set to the basic estimator 00226 * before any computations are made. 00227 */ 00228 typename E::parameters initialEstimationParameters; 00229 00230 /** 00231 * Parameters for uniform discrete distribution. 00232 */ 00233 uniformDiscreteDistribution::parameters rndParameters; 00234 }; 00235 00236 /** 00237 * Default constructor 00238 */ 00239 ransacEstimation(); 00240 00241 /** 00242 * Construct a functor using the given parameters 00243 */ 00244 ransacEstimation(const parameters& par); 00245 00246 /** 00247 * Copy constructor 00248 * @param other the object to be copied 00249 */ 00250 ransacEstimation(const ransacEstimation<E>& other); 00251 00252 /** 00253 * Destructor 00254 */ 00255 virtual ~ransacEstimation(); 00256 00257 /** 00258 * Estimates the transformation for the given set of correspondences. 00259 * 00260 * It will be assumed that for any valid index i the point setA[i] has a 00261 * correspondent point setB[i]. 00262 * 00263 * @param setA first set of points of type P. 00264 * @param setB second set of points of type P. 00265 * @param dest std::vector<P> where the result will be left. 00266 * @return true if apply successful or false otherwise. 00267 */ 00268 template<class P> 00269 bool apply(const std::vector<P>& setA, 00270 const std::vector<P>& setB, 00271 typename E::parameters& result) const; 00272 00273 /** 00274 * Estimates the transformation for the given set of correspondences. 00275 * 00276 * It will be assumed that for any valid index i the point setA[i] has a 00277 * correspondent point setB[i]. 00278 * 00279 * @param setA first set of points of type P. 00280 * @param setB second set of points of type P. 00281 * @param inliers output container with the indices of the inliers detected 00282 * @param dest std::vector<P> where the result will be left. 00283 * @return true if apply successful or false otherwise. 00284 */ 00285 template<class P> 00286 bool apply(const std::vector<P>& setA, 00287 const std::vector<P>& setB, 00288 ivector& inliers, 00289 typename E::parameters& result) const; 00290 00291 /** 00292 * Copy data of "other" functor. 00293 * @param other the functor to be copied 00294 * @return a reference to this functor object 00295 */ 00296 ransacEstimation<E>& copy(const ransacEstimation<E>& other); 00297 00298 /** 00299 * Alias for copy member 00300 * @param other the functor to be copied 00301 * @return a reference to this functor object 00302 */ 00303 ransacEstimation<E>& operator=(const ransacEstimation<E>& other); 00304 00305 /** 00306 * Returns the name of this type, which depends on the template parameters. 00307 */ 00308 virtual const std::string& name() const; 00309 00310 /** 00311 * Returns a pointer to a clone of this functor. 00312 */ 00313 virtual ransacEstimation<E>* clone() const; 00314 00315 /** 00316 * Returns a pointer to a new instance of this functor. 00317 */ 00318 virtual ransacEstimation<E>* newInstance() const; 00319 00320 /** 00321 * Returns used parameters 00322 */ 00323 const parameters& getParameters() const; 00324 00325 /** 00326 * Update parameters 00327 */ 00328 virtual bool updateParameters(); 00329 private: 00330 00331 /** 00332 * Shadow of parameters (but fixed) 00333 */ 00334 int numPointsPerTrial_; 00335 00336 /** 00337 * Shadow of parameters but logarithmic 00338 */ 00339 double logConfidence_; 00340 00341 /** 00342 * Get n random numbers. 00343 * It assumes that idx contains each of its own valid indices exactly once. 00344 */ 00345 void getNRandom(uniformDiscreteDistribution& rnd, 00346 const int n, 00347 ivector& idx) const; 00348 00349 /** 00350 * Take the points in setA, transform them with transformer into a 00351 * estB which are compare with each point in setB. The squared distances 00352 * between estB and setB are stored in residual. 00353 */ 00354 template<class P> 00355 void computeResidual(E& transformer, 00356 const std::vector<P>& setA, 00357 const std::vector<P>& setB, 00358 const float maxError, 00359 fvector& residuals, 00360 float& average, 00361 ivector& inliers, 00362 int& numInliers) const; 00363 }; 00364 } 00365 00366 #include "cvrRansacEstimation_template.h" 00367 00368 #endif 00369