Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ExampleRANSAC_double.hh
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003, 2004 (see file CONTACTS for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 #ifndef __ExampleRANSAC_double_hh__
26 #define __ExampleRANSAC_double_hh__
27 
28 #include "MathAlgo/RANSAC.hh"
29 
30 namespace BIAS {
31 
32  /** @class RANSAC_double
33  @brief Robust mean computation for double values using RANSAC.
34 
35  This class implements a simple example for RANSAC class overloading.
36 
37  Method RANSAC_double::GetSampleSolutions picks a number of values
38  and computes the mean from them. The sample size is not fixed here
39  but can be chosen when calling method RANSAC_double::Init.
40 
41  Method RANSAC_double::EvaluateSolution evaluates how many values are
42  considered as "inliers" with respect to the mean hypothesis, i.e.
43  their distance to the mean does not exceed a certain threshold.
44 
45  In RANSAC_double::RefineSolution the mean is recomputed for all inliers.
46 
47  You have to set the inlier threshold (max. distance to mean to accept
48  a value as being an inlier) and the fraction of valid input values
49  which will define the number of samples evaluated by RANSAC.
50 
51  @author MIP
52  */
53  class RANSAC_double : public RANSAC<double>
54  {
55  public:
56 
57  RANSAC_double();
58 
60 
61  void Init(std::vector<double>& data, unsigned int sample_size,
62  double inlier_distance_threshold, bool refine_solution,
63  double expected_inlier_fraction,
64  double solution_error_threshold);
65 
66  virtual int GetSampleSolutions(std::vector<unsigned int> &which_samples,
67  std::vector<double> &solutions);
68 
69  virtual bool EvaluateSolution(const double& solution,
70  bool existing_solution_flag,
71  std::vector<bool>& inlier,
72  int& accept_count,
73  double& evaluate_score,
74  bool& ok_to_terminate_flag);
75 
76  virtual bool RefineSolution(std::vector<unsigned int>& which_samples,
77  double& solution,
78  std::vector<bool>& new_inliers);
79 
80  protected:
81 
82  // @brief Vector of all input values to compute the robust mean for
83  std::vector<double> _vData;
84 
85  // @brief Data closer to solution than this threshold is regarded as inlier
87 
88  // @brief If a sample yields more than _dExpectedInlierFraction inliers and
89  // the evaluate_score is lower than _dSolutionErrorThreshold, RANSAC will stop
92  };
93 
95  {}
96 
98  {}
99 
100  void RANSAC_double::Init(std::vector<double>& data,
101  unsigned int sample_size,
102  double inlier_distance_threshold,
103  bool refine_solution,
104  double expected_inlier_fraction,
105  double solution_error_threshold)
106  {
107  RANSAC<double>::Init(sample_size, 1, refine_solution);
108  _vData = data;
109  _uiDataSize = data.size();
110  _dInlierDistanceThreshold = inlier_distance_threshold;
111  _dExpectedInlierFraction = expected_inlier_fraction;
112  _dSolutionErrorThreshold = solution_error_threshold;
113  }
114 
115  int RANSAC_double::
116  GetSampleSolutions(std::vector<unsigned int> &which_samples,
117  std::vector<double> &solutions)
118  {
119  double mean = 0.0;
120  for (unsigned int i = 0; i < which_samples.size(); i++)
121  mean += _vData[which_samples[i]];
122  mean /= which_samples.size();
123  solutions.clear();
124  solutions.push_back(mean);
125  return solutions.size();
126  }
127 
128  bool RANSAC_double::
129  EvaluateSolution(const double& solution,
130  bool existing_solution_flag,
131  std::vector<bool>& inlier,
132  int& accept_count,
133  double& evaluate_score,
134  bool& ok_to_terminate_flag)
135  {
136  bool good_flag = true;
137  inlier.clear();
138  inlier.resize(_uiDataSize);
139 
140  int my_accept_count = 0;
141  evaluate_score = 0.0;
142 
143  for (unsigned int i = 0; i < _uiDataSize; i++){
144  inlier[i] = (fabs(solution-_vData[i]) < _dInlierDistanceThreshold);
145  if (inlier[i]) {
146  my_accept_count++;
147  evaluate_score += fabs(solution-_vData[i]);
148  if (existing_solution_flag && my_accept_count > accept_count) break;
149  }
150  }
151  if (my_accept_count!=0) {
152  evaluate_score /= my_accept_count;
153  } else {
154  evaluate_score = DBL_MAX;
155  good_flag = false;
156  }
157  accept_count = my_accept_count;
158 
159  ok_to_terminate_flag =
160  (((accept_count/(double)_uiDataSize) > _dExpectedInlierFraction) &&
161  (evaluate_score < _dSolutionErrorThreshold));
162 
163  return good_flag;
164  }
165 
166  bool RANSAC_double::
167  RefineSolution(std::vector<unsigned int>& which_samples,
168  double& solution, std::vector<bool>& new_inliers)
169  {
170  solution = 0.0;
171  for (unsigned int i = 0; i < which_samples.size(); i++)
172  solution += _vData[which_samples[i]];
173  solution /= which_samples.size();
174 
175  new_inliers.clear();
176  new_inliers.resize(_uiDataSize);
177  for (unsigned int i = 0; i < _uiDataSize; i++)
178  new_inliers[i] = (fabs(solution-_vData[i]) < _dInlierDistanceThreshold);
179 
180  return true;
181  }
182 
183 } // namespace
184 
185 #endif // __ExampleRANSAC_double_hh__
virtual bool RefineSolution(std::vector< unsigned int > &which_samples, double &solution, std::vector< bool > &new_inliers)
refine previously computed solution based on its inliers
virtual int GetSampleSolutions(std::vector< unsigned int > &which_samples, std::vector< double > &solutions)
Compute solution(s) for the given set of samples.
Robust mean computation for double values using RANSAC.
std::vector< double > _vData
void Init(unsigned int sample_size, unsigned int max_solutions_per_sample=1, bool refine_solution=false, bool greedy=false)
Definition: RANSAC.hh:360
virtual bool EvaluateSolution(const double &solution, bool existing_solution_flag, std::vector< bool > &inlier, int &accept_count, double &evaluate_score, bool &ok_to_terminate_flag)
evaluate the goodness of a solution
void Init(std::vector< double > &data, unsigned int sample_size, double inlier_distance_threshold, bool refine_solution, double expected_inlier_fraction, double solution_error_threshold)
Generic abstract base class for RANSAC (RANdom SAmple Consensus) estimators.
Definition: RANSAC.hh:80
unsigned _uiDataSize
number of data elements needed to compute a solution
Definition: RANSAC.hh:270