Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
MeanDoubleRANSACEvaluator.hh
1 /* This file is part of the BIAS library (Basic ImageAlgorithmS).
2 
3  Copyright (C) 2003-2009 (see file CONTACT for details)
4  Multimediale Systeme der Informationsverarbeitung
5  Institut fuer Informatik
6  Christian-Albrechts-Universitaet Kiel
7 
8  BIAS is free software; you can redistribute it and/or modify
9  it under the terms of the GNU Lesser General Public License as published by
10  the Free Software Foundation; either version 2.1 of the License, or
11  (at your option) any later version.
12 
13  BIAS is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public License
19  along with BIAS; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
21 #ifndef __MeanDoubleRANSACEvaluator_hh__
22 #define __MeanDoubleRANSACEvaluator_hh__
23 
24 #include <MathAlgo/RANSACEvaluatorInterface.hh>
25 #include <Base/Debug/Error.hh>
26 #include <Base/Debug/Exception.hh>
27 #include <Base/Common/CompareFloatingPoint.hh>
28 
29 #include <vector>
30 #include <cmath>
31 
32 namespace BIAS {
33 
34  /** @class MeanDoubleRANSACEvaluator
35  @brief helper class for implementation of PreemptievRANSAC and COSAC
36  for robust computation of the mean of a vector of doubles
37  @relates TestCOSAC, TestPreemptiveRANSAC, RANSACEvaluatorInterface, COSAC,
38  PreemptiveRANSAC
39  @author woelk 01/2010 (c) www.vision-n.de */
41  : public RANSACEvaluatorInterface<double>
42  {
43  public:
45 
47 
48  int Init(const std::vector<double> &data, const double &sigma3);
49 
50  unsigned GetNumMeasurements() const { return Data_.size(); }
51 
52  unsigned GetMinNumSamplesForSolutionComputation() const { return 2u; }
53 
54  inline bool IsInlier(const double& solution, const unsigned data_index,
55  double& score);
56 
57  inline int GetSampleSolutions(const std::vector<unsigned> &which_samples,
58  std::vector<double> &solutions);
59 
60  inline bool RefineSolution(const std::vector<bool>& inliers,
61  double& solution);
62 
63  protected:
64  std::vector<double> Data_;
65  double Sigma3_;
66 
67  }; // class
68 
69  //////////////////////////////////////////////////////////////////////////
70  // implementation
71  //////////////////////////////////////////////////////////////////////////
72 
73 
76  : RANSACEvaluatorInterface<double>(), Data_(), Sigma3_(1.0)
77  {}
78 
79 
81  Init(const std::vector<double> &data, const double &sigma3)
82  {
83  Data_ = data;
84  Sigma3_ = sigma3;
85  if (data.empty()){
86  //return -1;
87  BEXCEPTION("MeanDoubleRANSACEvaluator::MeanDoubleRANSACEvaluator(): No measurements");
88  }
89  if (data.size()<GetMinNumSamplesForSolutionComputation()){
90  //return -2;
91  BEXCEPTION("MeanDoubleRANSACEvaluator::MeanDoubleRANSACEvaluator(): Not enough "
92  <<"measurements");
93  }
94  if (sigma3<0.0){
95  //return -3;
96  BEXCEPTION("MeanDoubleRANSACEvaluator::MeanDoubleRANSACEvaluator(): Sigma3 must be "
97  <<"greater or equal to zero.");
98  }
99  return 0;
100  }
101 
102 
105  {}
106 
107 
109  IsInlier(const double &solution, const unsigned data_index, double &score)
110  {
111  if (Data_.empty()){
112  BEXCEPTION("MeanDoubleRANSACEvaluator::IsInlier(): Not initialized\n");
113  }
114  BIASASSERT(data_index<Data_.size());
115 
116  double dist = fabs(solution - Data_[data_index]);
117  const double eps = 1e-13;
118  if (Equal(dist, 0.0, eps)) {
119  dist = eps;
120  }
121  score = log(dist / Sigma3_);
122  if (isnan(score) || isinf(score)){
123  BEXCEPTION("MeanDoubleRANSACEvaluator::IsInlier_(): Cannot compute score, "
124  <<"maybe expected sigma ("<<Sigma3_<<") is invalid? dist = "
125  <<dist<<"\t"<<solution<<"\t"<<Data_[data_index]);
126  }
127  bool is_inlier = (dist < Sigma3_);
128  return is_inlier;
129  }
130 
131 
133  GetSampleSolutions(const std::vector<unsigned> &which_samples,
134  std::vector<double> &solutions)
135  {
136  if (Data_.empty()){
137  BEXCEPTION("MeanDoubleRANSACEvaluator::IsInlier(): Not initialized\n");
138  }
139  // check for duplicate samples
140  if (which_samples.size()>1 && which_samples[0]==which_samples[1]){
141  BIASABORT;
142  }
143  BIASASSERT(which_samples.size()==GetMinNumSamplesForSolutionComputation());
144  BIASASSERT(!which_samples.empty());
145  double sum = 0.;
146  std::vector<unsigned>::const_iterator it;
147  for (it = which_samples.begin(); it!=which_samples.end(); it++){
148  BIASASSERT(*it<Data_.size());
149  sum += Data_[*it];
150  }
151  double mean = sum / (double)(which_samples.size());
152  BIASASSERT(!isinf(mean) && !isnan(mean));
153  // check if all data points from which the solution has been generated are
154  // inliers to the solution
155  double score;
156  for (it = which_samples.begin(); it!=which_samples.end(); it++){
157  if (!IsInlier(mean, *it, score)){
158  return false;
159  }
160  }
161 
162  solutions.clear();
163  solutions.push_back(mean);
164 
165  return 0;
166  }
167 
168 
170  RefineSolution(const std::vector<bool>& inliers, double& solution)
171  {
172  if (Data_.empty()){
173  BEXCEPTION("MeanDoubleRANSACEvaluator::IsInlier(): Not initialized\n");
174  }
175  double sum = 0.;
176  unsigned count = 0;
177  BIASASSERT(inliers.size()==Data_.size());
178  for (unsigned i=0; i<inliers.size(); i++){
179  if (inliers[i]){
180  sum += Data_[i];
181  count++;
182  }
183  }
184  if (count==0){ return false; }
185  solution = sum / (double)count;
186  BIASASSERT(!isinf(solution) && !isnan(solution));
187 
188  return true;
189  }
190 
191 } // namespace
192 
193 #endif // __MeanDoubleRANSACEvaluator_hh__
Interface for computation of solutions and evaluation of measurements.
helper class for implementation of PreemptievRANSAC and COSAC for robust computation of the mean of a...
unsigned GetMinNumSamplesForSolutionComputation() const
Returns the minimum required samples for computation of a solution.
int Init(const std::vector< double > &data, const double &sigma3)
bool Equal(const T left, const T right, const T eps)
comparison function for floating point values See http://www.boost.org/libs/test/doc/components/test_...
int GetSampleSolutions(const std::vector< unsigned > &which_samples, std::vector< double > &solutions)
Compute solution(s) for the given set of samples.
bool IsInlier(const double &solution, const unsigned data_index, double &score)
Checks whether a certain sample (i.e.
bool RefineSolution(const std::vector< bool > &inliers, double &solution)
Refine a solution based on the inliers vector.
unsigned GetNumMeasurements() const
Returns the number of available measurements.