Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ExampleRANSAC_double.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT 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 /** @example ExampleRANSAC_double.cpp
26  @relates DoubleRANSAC, RANSAC
27  @ingroup g_examples
28  @brief Example for using classes derived from BIAS::RANSAC to
29  solve custom problems robustly.
30  @author MIP
31 */
32 
33 #include <Base/Common/BIASpragma.hh>
34 
35 #include "ExampleRANSAC_double.hh"
36 
37 #include <Base/Math/Random.hh>
38 #include <vector>
39 #include <iostream>
40 #include <iomanip>
41 #include <float.h>
42 
43 using namespace BIAS;
44 using namespace std;
45 
46 /* Generate test data for RANSAC_double instance.
47  input : inlier percentage of inliers
48  count number of data generated
49  mean mean ofthe generated data
50  sigma standard deviation of the generated data
51  output: data the generated data
52 */
53 void GenerateRANSAC_doubleData(unsigned int count, double mean, double sigma,
54  double inlier_fraction, vector<double>& data,
55  Random& randomizer)
56 {
57  if (data.size() != count) data.resize(count);
58  double outlier_prob;
59  for (unsigned int i = 0; i < count; i++) {
60  outlier_prob = randomizer.GetUniformDistributed(0.0, 1.0);
61  if (outlier_prob > inlier_fraction) {
62  // generate a outlier
63  data[i] = randomizer.GetNormalDistributed(mean, sigma) +
64  randomizer.GetUniformDistributed(3*sigma, 30.0*sigma);
65  } else {
66  // generate an inlier
67  data[i] = randomizer.GetNormalDistributed(mean, sigma);
68  }
69  }
70 }
71 
72 
73 int main(int argc, char *argv[])
74 {
75  Random randomizer;
76  int res = 0;
77  vector<vector<double> > data_array;
78  vector<double> data;
79  double min = -100.0, max = 100.0;
80  double minsigma = 0.0, maxsigma = 5.0;
81  vector<double> mean;
82  vector<double> sigma;
83  double inlier_fraction = 0.7;
84  vector<double> expected_inlier_fraction;
85  unsigned int sample_size = 2;
86  bool refine_solution = true;
87  double inlier_distance_threshold;
88  double solution;
89  vector<bool> inliers;
90  bool debug = false; //true;
91  RANSAC_double ransac;
92  double mean_error = 0.0;
93  double solution_error_threshold;
94 
95  if (debug) {
96  ransac.AddDebugLevel("D_RANSAC_SAMPLES");
97  ransac.AddDebugLevel("D_RANSAC_SOLVE_MASTER");
98  ransac.AddDebugLevel("D_DOUBLE_RANSAC_SOLUTION");
99  }
100 
101  unsigned int count = argc > 1 ? atoi(argv[1]) : 1000;
102  unsigned int data_length = argc > 2 ? atoi(argv[2]) : 1000;
103  cout << endl << "Running " << argv[0] << " " << count << " times with "
104  << data_length << " samples per test : " << endl
105  << "(call " << argv[0] << " <num_tests> <num_samples> to change "
106  << "parameters)" << endl << endl;
107 
108  // generate all test sets in advance since randomizer might be reset
109  // in RANSAC instance
110  data_array.resize(count);
111  mean.resize(count);
112  sigma.resize(count);
113  expected_inlier_fraction.resize(count);
114  for (unsigned int i = 0; i < count; i++)
115  {
116  mean[i] = randomizer.GetUniformDistributed(min, max);
117  sigma[i] = randomizer.GetUniformDistributed(minsigma, maxsigma);
118  expected_inlier_fraction[i] = inlier_fraction +
119  randomizer.GetNormalDistributed(0.0, (1.0-inlier_fraction)/3.0);
120  if (expected_inlier_fraction[i] > 1.0)
121  expected_inlier_fraction[i] = 1.0;
122  GenerateRANSAC_doubleData(data_length, mean[i], sigma[i], inlier_fraction,
123  data_array[i], randomizer);
124  }
125 
126  // evaluate all test sets
127  for (unsigned int i = 0; i < count; i++)
128  {
129  inlier_distance_threshold = 3.0*sigma[i];
130  solution_error_threshold = 1.5*sigma[i];
131  //expected_inlier_fraction[i] = 0.5;
132  if (debug) {
133  for (unsigned int j = 0; j < data_length; j++)
134  cout << data_array[i][j] << " ";
135  cout << endl;
136  cout <<setw(5)<<i<<":\tmean: "<<mean[i]<<"\tsigma: "<<sigma[i]<<endl;
137  cout << "inlier_distance_threshold = "<<inlier_distance_threshold<<endl;
138  cout << "solution_error_threshold = "<<solution_error_threshold<<endl;
139  cout << "expected_inlier_fraction " << expected_inlier_fraction[i]<<endl;
140  }
141 
142  ransac.Init(data_array[i], sample_size, inlier_distance_threshold,
143  refine_solution, expected_inlier_fraction[i],
144  solution_error_threshold);
145 
146  if (ransac.SolveMaster(expected_inlier_fraction[i], solution, inliers) < 0)
147  {
148  BIASERR("Error running RANSAC_double::SolveMaster()!");
149  cerr << "- true solution \t" << mean[i] <<" \t"
150  << "sigma: "<<sigma[i]<<" \t"
151  << "expected_inlier_fraction: "<<expected_inlier_fraction[i]<<endl;
152  } else {
153  cerr << "- true solution \t" << mean[i] <<" \t"
154  << "sigma: "<<sigma[i]<<" \t"
155  << "expected_inlier_fraction: "<<expected_inlier_fraction[i]<<endl
156  << " estimated solution \t" << solution <<" \t"
157  << "error: "<<fabs(solution-mean[i])<<" \t"
158  << "expected_inlier_fraction: "<<expected_inlier_fraction[i]<<endl;
159  mean_error += (sigma[i]!=0.0) ? (fabs(solution-mean[i])/sigma[i]) :
160  (fabs(solution-mean[i]) / DBL_MIN);
161  }
162  }
163  mean_error /= (double)count;
164 
165  cerr << "\n mean error of all tests : " << mean_error << endl << endl;
166  return res;
167 }
void AddDebugLevel(const long int lv)
Definition: Debug.hh:355
virtual int SolveMaster(double inlying_data_fraction, SolutionType &solution, std::vector< bool > &inliers)
Main computation function called by user.
Definition: RANSAC.hh:378
Robust mean computation for double values using RANSAC.
double GetUniformDistributed(const double min, const double max)
on succesive calls return uniform distributed random variable between min and max ...
Definition: Random.hh:84
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)
double GetNormalDistributed(const double mean, const double sigma)
on succesive calls return normal distributed random variable with mean and standard deviation sigma ...
Definition: Random.hh:71
class for producing random numbers from different distributions
Definition: Random.hh:51