Image Component Library (ICL)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
RansacFitter.h
Go to the documentation of this file.
00001 /********************************************************************
00002 **                Image Component Library (ICL)                    **
00003 **                                                                 **
00004 ** Copyright (C) 2006-2013 CITEC, University of Bielefeld          **
00005 **                         Neuroinformatics Group                  **
00006 ** Website: www.iclcv.org and                                      **
00007 **          http://opensource.cit-ec.de/projects/icl               **
00008 **                                                                 **
00009 ** File   : ICLMath/src/ICLMath/RansacFitter.h                     **
00010 ** Module : ICLMath                                                **
00011 ** Authors: Christof Elbrechter                                    **
00012 **                                                                 **
00013 **                                                                 **
00014 ** GNU LESSER GENERAL PUBLIC LICENSE                               **
00015 ** This file may be used under the terms of the GNU Lesser General **
00016 ** Public License version 3.0 as published by the                  **
00017 **                                                                 **
00018 ** Free Software Foundation and appearing in the file LICENSE.LGPL **
00019 ** included in the packaging of this file.  Please review the      **
00020 ** following information to ensure the license requirements will   **
00021 ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt                **
00022 **                                                                 **
00023 ** The development of this software was supported by the           **
00024 ** Excellence Cluster EXC 277 Cognitive Interaction Technology.    **
00025 ** The Excellence Cluster EXC 277 is a grant of the Deutsche       **
00026 ** Forschungsgemeinschaft (DFG) in the context of the German       **
00027 ** Excellence Initiative.                                          **
00028 **                                                                 **
00029 ********************************************************************/
00030 
00031 #pragma once
00032 
00033 #include <ICLUtils/CompatMacros.h>
00034 #include <ICLUtils/Function.h>
00035 #include <ICLUtils/Uncopyable.h>
00036 #include <ICLUtils/Random.h>
00037 #include <ICLMath/DynVector.h>
00038 #include <ICLMath/FixedVector.h>
00039 
00040 namespace icl{
00041   namespace math{
00042    
00043     
00045 
00061     template<class DataPoint=std::vector<float>,
00062              class Model=std::vector<float> >
00063     class RansacFitter{
00064       public:
00066       typedef std::vector<DataPoint> DataSet;
00067       
00069       typedef utils::Function<Model,const DataSet&> ModelFitting;
00070       
00072       typedef utils::Function<icl64f,const Model&,const DataPoint&> PointError;
00073       
00074       private:
00076       int m_minPointsForModel;
00077       
00079       int m_iterations;
00080       
00082       icl64f m_maxModelDistance;
00083       
00085       int m_minClosePointsForGoodModel;
00086       
00088       ModelFitting m_fitting;
00089       
00091       PointError m_err;
00092       
00094       icl64f m_minErrorExit;
00095       
00096       public:
00098       struct Result{
00100         icl64f error;
00101         
00103         Model model;
00104         
00106 
00107         DataSet consensusSet;
00108   
00110         int iterationCount;
00111         
00113         bool found() const { return consensusSet.size(); }
00114       };
00115       
00116       private:
00118       Result m_result;
00119       
00121       static inline bool find_in(const std::vector<int> &v, int i, int n){
00122         return std::find(v.data(), v.data()+n, i) != v.data()+n;
00123       }
00124   
00126       void find_random_consensus_set(DataSet &currConsensusSet,
00127                                      const DataSet &allPoints,
00128                                      std::vector<int> &usedIndices){
00129         const int n = currConsensusSet.size();
00130         utils::URandI r(allPoints.size()-1);
00131         
00132         for(int i=0;i<n;++i){
00133           do { usedIndices[i] = r; } while ( find_in(usedIndices, usedIndices[i], i-1) );
00134           currConsensusSet[i] = allPoints[ usedIndices[i] ];
00135         }
00136       }
00137       
00138       public:
00140       RansacFitter(){}
00141       
00143 
00145       RansacFitter(int minPointsForModel, 
00146                    int iterations, 
00147                    ModelFitting fitting,
00148                    PointError err,
00149                    icl64f maxModelDistance,
00150                    int minClosePointsForGoodModel,
00151                    icl64f minErrorExit=0):
00152         m_minPointsForModel(minPointsForModel),
00153         m_iterations(iterations),
00154         m_maxModelDistance(maxModelDistance),
00155         m_minClosePointsForGoodModel(minClosePointsForGoodModel),
00156         m_fitting(fitting),m_err(err),
00157         m_minErrorExit(minErrorExit){
00158       }
00159       
00161       const Result &fit(const DataSet &allPoints){
00162         m_result.model = Model();
00163         m_result.consensusSet.clear();
00164         m_result.error = utils::Range64f::limits().maxVal;
00165         m_result.iterationCount = 0;
00166         std::vector<DataPoint> consensusSet(m_minPointsForModel);
00167         std::vector<int> usedIndices(m_minPointsForModel);
00168         
00169         int i = 0;
00170         for(i=0;i<m_iterations;++i){
00171           consensusSet.resize(m_minPointsForModel);
00172           find_random_consensus_set(consensusSet, allPoints, usedIndices);
00173           
00174           Model model = m_fitting(consensusSet);
00175           for(int j=0;j<(int)allPoints.size();++j){
00176             if(find_in(usedIndices, j, usedIndices.size())) continue;
00177             if(m_err(model, allPoints[j]) < m_maxModelDistance){
00178               consensusSet.push_back(allPoints[j]);
00179             }
00180           }
00181           
00182           if((int)consensusSet.size() >= m_minClosePointsForGoodModel){
00183             model = m_fitting(consensusSet);
00184             double error = 0;
00185             for(unsigned int j=0;j<consensusSet.size();++j){
00186               error += m_err(model, consensusSet[j]);
00187             }
00188             error /= consensusSet.size();
00189             
00190             if(error < m_result.error){
00191               m_result.error = error;
00192               m_result.model = model;
00193               m_result.consensusSet = consensusSet;
00194               if(m_result.error < m_minErrorExit){
00195                 m_result.iterationCount = i;
00196                 return m_result;
00197               }
00198             }
00199           }
00200         }
00201         m_result.iterationCount = i;
00202         return m_result;
00203       }
00204     };
00205   } // namespace math
00206 }
00207 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines