Basic Image AlgorithmS Library 2.8.0

MeanDoubleRANSACEvaluator.hh

00001 /* This file is part of the BIAS library (Basic ImageAlgorithmS).
00002    
00003    Copyright (C) 2003-2009    (see file CONTACT for details)
00004    Multimediale Systeme der Informationsverarbeitung
00005    Institut fuer Informatik
00006    Christian-Albrechts-Universitaet Kiel
00007    
00008    BIAS is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU Lesser General Public License as published by
00010    the Free Software Foundation; either version 2.1 of the License, or
00011    (at your option) any later version.
00012    
00013    BIAS is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU Lesser General Public License for more details.
00017    
00018    You should have received a copy of the GNU Lesser General Public License
00019    along with BIAS; if not, write to the Free Software
00020    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
00021 #ifndef __MeanDoubleRANSACEvaluator_hh__
00022 #define __MeanDoubleRANSACEvaluator_hh__
00023 
00024 #include <MathAlgo/RANSACEvaluatorInterface.hh>
00025 #include <Base/Debug/Error.hh>
00026 #include <Base/Debug/Exception.hh>
00027 #include <Base/Common/CompareFloatingPoint.hh>
00028 
00029 #include <vector>
00030 #include <cmath>
00031 
00032 namespace BIAS {
00033 
00034   /** @class MeanDoubleRANSACEvaluator
00035       @brief helper class for implementation of PreemptievRANSAC and COSAC
00036       for robust computation of the mean of a vector of doubles
00037       @relates TestCOSAC, TestPreemptiveRANSAC, RANSACEvaluatorInterface, COSAC, 
00038       PreemptiveRANSAC
00039       @author woelk 01/2010 (c) www.vision-n.de */
00040   class MeanDoubleRANSACEvaluator
00041     : public RANSACEvaluatorInterface<double>
00042   {
00043   public:
00044     MeanDoubleRANSACEvaluator();
00045 
00046     virtual ~MeanDoubleRANSACEvaluator();
00047 
00048     int Init(const std::vector<double> &data, const double &sigma3);
00049 
00050     unsigned GetNumMeasurements() const { return Data_.size(); }
00051 
00052     unsigned GetMinNumSamplesForSolutionComputation() const { return 2u; }
00053 
00054     inline bool IsInlier(const double& solution, const unsigned data_index,
00055                          double& score);
00056     
00057     inline int GetSampleSolutions(const std::vector<unsigned> &which_samples,
00058                                   std::vector<double> &solutions);
00059   
00060     inline bool RefineSolution(const std::vector<bool>& inliers,
00061                                double& solution);        
00062 
00063   protected:
00064     std::vector<double> Data_;
00065     double Sigma3_;
00066 
00067   }; // class
00068 
00069   //////////////////////////////////////////////////////////////////////////
00070   // implementation
00071   //////////////////////////////////////////////////////////////////////////
00072   
00073 
00074   MeanDoubleRANSACEvaluator::
00075   MeanDoubleRANSACEvaluator()
00076     :  RANSACEvaluatorInterface<double>(), Data_(), Sigma3_(1.0)
00077   {}
00078 
00079 
00080   int MeanDoubleRANSACEvaluator::
00081   Init(const std::vector<double> &data, const double &sigma3)
00082   {
00083     Data_ = data;
00084     Sigma3_ = sigma3;
00085     if (data.empty()){
00086       //return -1;
00087       BEXCEPTION("MeanDoubleRANSACEvaluator::MeanDoubleRANSACEvaluator(): No measurements");
00088     }
00089     if (data.size()<GetMinNumSamplesForSolutionComputation()){
00090       //return -2;
00091       BEXCEPTION("MeanDoubleRANSACEvaluator::MeanDoubleRANSACEvaluator(): Not enough "
00092                  <<"measurements");
00093     }
00094     if (sigma3<0.0){
00095       //return -3;
00096       BEXCEPTION("MeanDoubleRANSACEvaluator::MeanDoubleRANSACEvaluator(): Sigma3 must be "
00097                  <<"greater or equal to zero.");
00098     }
00099     return 0;
00100   }
00101 
00102 
00103   MeanDoubleRANSACEvaluator::
00104   ~MeanDoubleRANSACEvaluator()
00105   {}
00106 
00107 
00108   bool MeanDoubleRANSACEvaluator::
00109   IsInlier(const double &solution, const unsigned data_index, double &score)
00110   {
00111     if (Data_.empty()){
00112       BEXCEPTION("MeanDoubleRANSACEvaluator::IsInlier(): Not initialized\n");
00113     }
00114     BIASASSERT(data_index<Data_.size());
00115   
00116     double dist = fabs(solution - Data_[data_index]);
00117     const double eps = 1e-13;
00118     if (Equal(dist, 0.0, eps)) {
00119       dist = eps;
00120     }
00121     score = log(dist / Sigma3_);
00122     if (isnan(score) || isinf(score)){
00123       BEXCEPTION("MeanDoubleRANSACEvaluator::IsInlier_(): Cannot compute score, "
00124                  <<"maybe expected sigma ("<<Sigma3_<<") is invalid? dist = "
00125                  <<dist<<"\t"<<solution<<"\t"<<Data_[data_index]);
00126     }
00127     bool is_inlier = (dist < Sigma3_);
00128     return is_inlier;
00129   }
00130   
00131 
00132   int MeanDoubleRANSACEvaluator::
00133   GetSampleSolutions(const std::vector<unsigned> &which_samples,
00134                      std::vector<double> &solutions)
00135   {
00136     if (Data_.empty()){
00137       BEXCEPTION("MeanDoubleRANSACEvaluator::IsInlier(): Not initialized\n");
00138     }
00139     // check for duplicate samples
00140     if (which_samples.size()>1 && which_samples[0]==which_samples[1]){
00141       BIASABORT;
00142     }
00143     BIASASSERT(which_samples.size()==GetMinNumSamplesForSolutionComputation());
00144     BIASASSERT(!which_samples.empty());
00145     double sum = 0.;
00146     std::vector<unsigned>::const_iterator it;
00147     for (it = which_samples.begin(); it!=which_samples.end(); it++){
00148       BIASASSERT(*it<Data_.size());
00149       sum += Data_[*it];
00150     }
00151     double mean = sum / (double)(which_samples.size());
00152     BIASASSERT(!isinf(mean) && !isnan(mean));
00153     // check if all data points from which the solution has been generated are 
00154     // inliers to the solution
00155     double score;
00156     for (it = which_samples.begin(); it!=which_samples.end(); it++){
00157       if (!IsInlier(mean, *it, score)){
00158         return false;
00159       }
00160     }
00161 
00162     solutions.clear();
00163     solutions.push_back(mean);
00164 
00165     return 0;
00166   }
00167   
00168 
00169   bool MeanDoubleRANSACEvaluator::
00170   RefineSolution(const std::vector<bool>& inliers, double& solution)
00171   {
00172     if (Data_.empty()){
00173       BEXCEPTION("MeanDoubleRANSACEvaluator::IsInlier(): Not initialized\n");
00174     }
00175     double sum = 0.;
00176     unsigned count = 0;
00177     BIASASSERT(inliers.size()==Data_.size());
00178     for (unsigned i=0; i<inliers.size(); i++){
00179       if (inliers[i]){
00180         sum += Data_[i];
00181         count++;
00182       }
00183     }
00184     if (count==0){ return false; }
00185     solution = sum / (double)count;
00186     BIASASSERT(!isinf(solution) && !isnan(solution));
00187   
00188     return true;
00189   }
00190 
00191 } // namespace
00192 
00193 #endif // __MeanDoubleRANSACEvaluator_hh__
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends