Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
TestPreemptiveRANSAC.cpp
1 #include <MathAlgo/PreemptiveRANSAC.hh>
2 #include <Base/Common/CompareFloatingPoint.hh>
3 #include <Base/Debug/TimeMeasure.hh>
4 
5 #include "MeanDoubleRANSACEvaluator.hh"
6 #include "TestMeanDoubleHelper.hh"
7 
8 using namespace BIAS;
9 using namespace std;
10 
11 Random MyRandom;
12 bool verbose = false;
13 const double max_outlier_fraction = 0.5;
14 
15 void DebugOut(const unsigned t, const unsigned num_data,
16  const unsigned num_outliers, const double sigma3,
17  const int ret_val_solve_master, const vector<double> &data,
18  const vector<bool> &gt_inliers, const double gt_mean,
19  const double &est_mean, const unsigned est_num_inliers,
20  const double &score, const double &max_score);
21 
22 int main(int argc, char *argv[])
23 {
24  const unsigned num_tries = 200;
26  PreemptiveRANSAC<double> mdpr(&mdch);
27  const unsigned min_sample_size =
29  const int debug_try = -1;
30 // mdpr.AddDebugLevel("D_PRANSAC_SolveMaster");
31 // mdpr.AddDebugLevel("D_PRANSAC_EvalOrder");
32 // mdpr.AddDebugLevel("D_PRANSAC_Evaluate");
33 // mdpr.AddDebugLevel("D_PRANSAC_InitialReject");
34 // mdpr.AddDebugLevel("D_PRANSAC_Inlier");
35 // mdpr.AddDebugLevel("D_PRANSAC_GetSolution");
36 // mdpr.AddDebugLevel("D_PRANSAC_GenerateSolutions");
37  TimeMeasure timer;
38 
39  for (unsigned t=0; t<num_tries; t++){
40  unsigned num_data =
41  (unsigned)rint(MyRandom.GetUniformDistributed(5., 200.));
42  if (t==0) {
43  // test what happens when there are barely enough samples
44  num_data = min_sample_size;
45  } else if (t==1 && min_sample_size>1){
46  // test what happens when not enough data is present
47  num_data = min_sample_size-1;
48  }
49  const unsigned min_num_outliers = (unsigned)floor(0.1*(double)num_data);
50  unsigned max_num_outliers =
51  (unsigned)floor(max_outlier_fraction*(double)num_data);
52  if (num_data>=min_sample_size && max_num_outliers+min_sample_size>num_data){
53  max_num_outliers = num_data-min_sample_size;
54  }
55  const unsigned num_outliers =
56  MyRandom.GetUniformDistributedInt(min_num_outliers, max_num_outliers);
57  const double sigma3 =
58  MyRandom.GetUniformDistributed(0., 1.0);
59  vector<double> data;
60  vector<bool> gt_inliers, est_inliers;
61  double gt_mean, est_mean;
62  if (t==(unsigned)debug_try) verbose = true;
63  if (verbose) {
64  cout << "------------ "<<t<<" -------------\n";
65  }
66  GenerateRandomData(MyRandom,num_data, num_outliers, sigma3, min_sample_size, data,
67  gt_inliers, gt_mean);
68  if (verbose) {
69  cout << " "<<num_data<<" samples ("<<num_outliers<<" outliers)\n"
70  << " mean: "<<gt_mean<<" \tsigma3: "<<sigma3<<endl;
71  }
72  if (t==(unsigned)debug_try){
73  mdpr.AddDebugLevel("D_PRANSAC_SolveMaster");
74  mdpr.AddDebugLevel("D_PRANSAC_Evaluate");
75  mdpr.AddDebugLevel("D_PRANSAC_InitialReject");
76  mdpr.AddDebugLevel("D_PRANSAC_GetSolution");
77  mdpr.AddDebugLevel("D_PRANSAC_GenerateSolutions");
78  }
79  try{
80  mdch.Init(data, sigma3);
81  } catch (BaseException &ex) {
82  cout<<"Exception failed:"<<ex.What()<<endl;
83  if (data.size()>=mdch.GetMinNumSamplesForSolutionComputation() ){
84  BIASABORT;
85  }
86  }
87 
88 
89  double inlying_data_fraction = 1.0-max_outlier_fraction-0.01;
90  const double max_score = 100.0;
91  double score;
92  unsigned num_inliers;
93  const bool auto_compute_max_samples = true;
94  timer.Reset();
95  timer.Start();
96  mdpr.Init();
97  int res = mdpr.SolveMaster(inlying_data_fraction, max_score, est_mean,
98  est_inliers, num_inliers, score,
99  auto_compute_max_samples);
100  timer.Stop();
101  // cout << setw(3) << t << ": "<<num_data<<" / "<<num_outliers<<" time: "
102 // <<timer.GetUserTime()<<endl;
103  if (res!=0){
104  if (num_data < min_sample_size){
105  if (res != PRANSAC_NOTE_ENOUGH_SAMPLES){
106  cerr << "invalid return value when not enough samples are present\n";
107  BIASABORT;
108  }
109  continue;
110  }
111  DebugOut(t, num_data, num_outliers, sigma3, res, data, gt_inliers,
112  gt_mean, est_mean, num_inliers, score, max_score);
113  if (res<0){
114  BIASABORT;
115  }
116  }
117  if (verbose)
118  cout << " found solution: "<<est_mean<<" (gt is "<<gt_mean<<", diff "
119  <<fabs(est_mean-gt_mean)/sigma3<<"*sigma3)\n";
120  if (!CheckResult(est_inliers, est_mean, gt_inliers, gt_mean, sigma3)){
121  DebugOut(t, num_data, num_outliers, sigma3, res, data, gt_inliers,
122  gt_mean, est_mean, num_inliers, score, max_score);
123  cerr << "wrong result\n";
124  BIASABORT;
125  }
126  if (!verbose)
127  cout << "#" << flush;
128  }
129  if (!verbose)
130  cout << "\n";
131 
132  return 0;
133 }
134 
135 
136 void DebugOut(const unsigned t, const unsigned num_data,
137  const unsigned num_outliers, const double sigma3,
138  const int ret_val_solve_master, const vector<double> &data,
139  const vector<bool> &gt_inliers, const double gt_mean,
140  const double &est_mean, const unsigned est_num_inliers,
141  const double &score, const double &max_score)
142 {
143  cerr << "\n---- try "<<t<<" -------\n"
144  << "(num samples: "<<num_data
145  <<", num_outliers: "<<num_outliers<<", sigma3: "<<sigma3<<"): res="
146  <<ret_val_solve_master<<endl;
147  if (ret_val_solve_master<0){
148  cerr << "Error computing solution\n";
149  } else if (ret_val_solve_master>0){
150  cerr << "Solution violates min quality criteria\n";
151  cout << "estimated num inliers: "<<est_num_inliers
152  << " (expected min "<<num_data-num_outliers<<")\n";
153  cout << "estimated score: "<<score
154  << " (expected max "<<max_score<<")\n";
155  }
156  for (unsigned k=0; k<data.size(); k++){
157  cout << data[k]<<"("<<((gt_inliers[k])?("+"):("-"))<< ") ";
158  }
159  cout << endl;
160  cout << "gt_mean : "<<gt_mean<<endl;
161  cout << "est_mean: "<<est_mean<<endl;
162  cout << "est num inliers: "<<est_num_inliers<<endl;
163  cout << "est score: "<<score<<endl;
164 }
helper class for implementation of PreemptievRANSAC and COSAC for robust computation of the mean of a...
double GetUniformDistributed(const double min, const double max)
on succesive calls return uniform distributed random variable between min and max ...
Definition: Random.hh:84
unsigned GetMinNumSamplesForSolutionComputation() const
Returns the minimum required samples for computation of a solution.
int GetUniformDistributedInt(const int min, const int max)
get uniform distributed random variable including min/max
Definition: Random.cpp:139
int Init(const std::vector< double > &data, const double &sigma3)
bool CheckResult(const std::vector< bool > &est_inliers, const double &est_mean, const std::vector< bool > &gt_inliers, const double &gt_mean, const double &gt_sigma3)
bool GenerateRandomData(Random &MyRandom, const unsigned num_data, const unsigned num_outliers, const double sigma3, const unsigned min_sample_size, std::vector< double > &data, std::vector< bool > &inliers, double &mean)
Fast RANSAC after David Nister, &quot;Preemptive RANSAC for Live Structure And Motion Estimation&quot;, Internation Conference on Computer Vision (ICCV) 2003.
class for producing random numbers from different distributions
Definition: Random.hh:51
class TimeMeasure contains functions for timing real time and cpu time.
Definition: TimeMeasure.hh:111
generic exception
Definition: Exception.hh:77
virtual const std::string & What() const
Definition: Exception.hh:95