Image Component Library (ICL)
RansacFitter.h
Go to the documentation of this file.
1 /********************************************************************
2 ** Image Component Library (ICL) **
3 ** **
4 ** Copyright (C) 2006-2013 CITEC, University of Bielefeld **
5 ** Neuroinformatics Group **
6 ** Website: www.iclcv.org and **
7 ** http://opensource.cit-ec.de/projects/icl **
8 ** **
9 ** File : ICLMath/src/ICLMath/RansacFitter.h **
10 ** Module : ICLMath **
11 ** Authors: Christof Elbrechter **
12 ** **
13 ** **
14 ** GNU LESSER GENERAL PUBLIC LICENSE **
15 ** This file may be used under the terms of the GNU Lesser General **
16 ** Public License version 3.0 as published by the **
17 ** **
18 ** Free Software Foundation and appearing in the file LICENSE.LGPL **
19 ** included in the packaging of this file. Please review the **
20 ** following information to ensure the license requirements will **
21 ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt **
22 ** **
23 ** The development of this software was supported by the **
24 ** Excellence Cluster EXC 277 Cognitive Interaction Technology. **
25 ** The Excellence Cluster EXC 277 is a grant of the Deutsche **
26 ** Forschungsgemeinschaft (DFG) in the context of the German **
27 ** Excellence Initiative. **
28 ** **
29 ********************************************************************/
30 
31 #pragma once
32 
33 #include <ICLUtils/CompatMacros.h>
34 #include <ICLUtils/Function.h>
35 #include <ICLUtils/Uncopyable.h>
36 #include <ICLUtils/Random.h>
37 #include <ICLMath/DynVector.h>
38 #include <ICLMath/FixedVector.h>
39 
40 namespace icl{
41  namespace math{
42 
43 
45 
61  template<class DataPoint=std::vector<float>,
62  class Model=std::vector<float> >
63  class RansacFitter{
64  public:
66  typedef std::vector<DataPoint> DataSet;
67 
70 
73 
74  private:
77 
80 
83 
86 
89 
92 
95 
96  public:
98  struct Result{
101 
103  Model model;
104 
106 
108 
111 
113  bool found() const { return consensusSet.size(); }
114  };
115 
116  private:
119 
121  static inline bool find_in(const std::vector<int> &v, int i, int n){
122  return std::find(v.data(), v.data()+n, i) != v.data()+n;
123  }
124 
126  void find_random_consensus_set(DataSet &currConsensusSet,
127  const DataSet &allPoints,
128  std::vector<int> &usedIndices){
129  utils::get_random_subset(allPoints, (int) currConsensusSet.size(),
130  currConsensusSet, usedIndices);
131  /*const std::vector<T> &s, int subsetSize,
132  std::vector<T> &subset, std::vector<int> &indices)
133 
134  const int n = currConsensusSet.size();
135  utils::URandI r(allPoints.size()-1);
136 
137  for(int i=0;i<n;++i){
138  do { usedIndices[i] = r; } while ( find_in(usedIndices, usedIndices[i], i-1) );
139  currConsensusSet[i] = allPoints[ usedIndices[i] ];
140  }*/
141  }
142 
143  public:
146 
148 
150  RansacFitter(int minPointsForModel,
151  int iterations,
152  ModelFitting fitting,
153  PointError err,
154  icl64f maxModelDistance,
155  int minClosePointsForGoodModel,
156  icl64f minErrorExit=0):
157  m_minPointsForModel(minPointsForModel),
158  m_iterations(iterations),
159  m_maxModelDistance(maxModelDistance),
160  m_minClosePointsForGoodModel(minClosePointsForGoodModel),
161  m_fitting(fitting),m_err(err),
162  m_minErrorExit(minErrorExit){
163  }
164 
166  const Result &fit(const DataSet &allPoints){
167  m_result.model = Model();
168  m_result.consensusSet.clear();
169  m_result.error = utils::Range64f::limits().maxVal;
171  std::vector<DataPoint> consensusSet(m_minPointsForModel);
172  std::vector<int> usedIndices(m_minPointsForModel);
173 
174  int i = 0;
175  for(i=0;i<m_iterations;++i){
176  consensusSet.resize(m_minPointsForModel);
177  find_random_consensus_set(consensusSet, allPoints, usedIndices);
178 
179  /* std::cout << " selected indices: [ "
180  << usedIndices[0] << ", "
181  << usedIndices[1] << ", "
182  << usedIndices[2] << ", "
183  << usedIndices[3] << "]" << std::endl;
184  */
185  Model model = m_fitting(consensusSet);
186  for(int j=0;j<(int)allPoints.size();++j){
187  if(find_in(usedIndices, j, usedIndices.size())) continue;
188  if(m_err(model, allPoints[j]) < m_maxModelDistance){
189  consensusSet.push_back(allPoints[j]);
190  }
191  }
192 
193 
194  if((int)consensusSet.size() >= m_minClosePointsForGoodModel){
195  model = m_fitting(consensusSet);
196  double error = 0;
197  for(unsigned int j=0;j<consensusSet.size();++j){
198  error += m_err(model, consensusSet[j]);
199  }
200  error /= consensusSet.size();
201 
202  if(error < m_result.error){
203  m_result.error = error;
204  m_result.model = model;
205  m_result.consensusSet = consensusSet;
208  return m_result;
209  }
210  }
211  }
212  }
214  return m_result;
215  }
216  };
217  } // namespace math
218 }
219 
PointError m_err
point-model error function
Definition: RansacFitter.h:91
DataSet consensusSet
consensus set of best match (i.e. inliers)
Definition: RansacFitter.h:107
icl64f m_maxModelDistance
maximum distance of a point to the model to become an inlier
Definition: RansacFitter.h:82
undocument this line if you encounter any issues!
Definition: Any.h:37
Model model
model (zero sized if no model was found)
Definition: RansacFitter.h:103
bool found() const
returns whether any model was found
Definition: RansacFitter.h:113
std::vector< T > get_random_subset(const std::vector< T > &s, int subsetSize)
Definition: Random.h:223
int iterationCount
number of iterations needed
Definition: RansacFitter.h:110
int m_iterations
number of iterations
Definition: RansacFitter.h:79
RansacFitter()
empty constructor (creates a dummy instance)
Definition: RansacFitter.h:145
std::vector< DataPoint > DataSet
DataSet type (just a set of DataPoint instances)
Definition: RansacFitter.h:66
utils::Function< Model, const DataSet & > ModelFitting
Function for the fitting module (gets a dataset and returns the fitted model)
Definition: RansacFitter.h:69
icl64f error
reached error
Definition: RansacFitter.h:100
icl64f m_minErrorExit
min error criterion for early exit
Definition: RansacFitter.h:94
Ipp64f icl64f
64Bit floating point type for the ICL
Definition: BasicTypes.h:52
int m_minClosePointsForGoodModel
minimum amount of inliers for a 'good' model
Definition: RansacFitter.h:85
ICLCV_API void error(const char *msg)
Display error message and terminate program.
ModelFitting m_fitting
fitting function
Definition: RansacFitter.h:88
result structure
Definition: RansacFitter.h:98
int m_minPointsForModel
minimum points that are used to create a coarse model
Definition: RansacFitter.h:76
const Result & fit(const DataSet &allPoints)
fitting function (actual RANSAC algorithm)
Definition: RansacFitter.h:166
RansacFitter(int minPointsForModel, int iterations, ModelFitting fitting, PointError err, icl64f maxModelDistance, int minClosePointsForGoodModel, icl64f minErrorExit=0)
constructor with given parameters
Definition: RansacFitter.h:150
static bool find_in(const std::vector< int > &v, int i, int n)
internal utility method
Definition: RansacFitter.h:121
void find_random_consensus_set(DataSet &currConsensusSet, const DataSet &allPoints, std::vector< int > &usedIndices)
internal utility method
Definition: RansacFitter.h:126
utils::Function< icl64f, const Model &, const DataPoint & > PointError
Error function for single points.
Definition: RansacFitter.h:72
Generic RANSAC (RAndom SAmpling Consensus) Implementation.
Definition: RansacFitter.h:63
Result m_result
internal result buffer
Definition: RansacFitter.h:118