00001 #ifndef rrel_ran_sam_search_h_ 00002 #define rrel_ran_sam_search_h_ 00003 //: 00004 // \file 00005 // \brief Random sampling search for minimization of a robust objective function 00006 // \author Chuck Stewart (stewart@cs.rpi.edu) 00007 // \date March 2001 00008 00009 #include <vnl/vnl_vector.h> 00010 #include <vnl/vnl_random.h> 00011 #include <vcl_vector.h> 00012 00013 class rrel_objective; 00014 class rrel_estimation_problem; 00015 00016 //: Random sampling search for minimization of a robust objective function. 00017 // The code organization follows the design of the rrel 00018 // library where there is a separation between objective function 00019 // (M-estimator, LMS, etc), search technique, and estimation problem. 00020 // See discussion in rrel_estimation_problem. 00021 // 00022 // The algorithm implemented was discovered independently by Fischler 00023 // and Bolles in the CACM RANSAC paper from 1981 and Rousseeuw in a 00024 // Journal of the American Statistical Association paper from 1984. 00025 // The implementation follows Rousseeuw's approach by not allowing 00026 // the short-circuiting of RANSAC, which can cause incorrect results 00027 // for a large number of outliers. 00028 // 00029 // The number of samples taken is computed to accommodate the 00030 // possibility of more than one population in the data, as described 00031 // in Stewart, PAMI 1995. It is a relatively straightforward 00032 // generalization of the ordinary method for calculating the number 00033 // of samples. 00034 // 00035 // Using this class requires calling set_sampling_params (or 00036 // set_gen_all_samples, which can be quite expensive), and then 00037 // calling estimate(). Results may be obtained through the functions 00038 // params() and scale(). 00039 00040 class rrel_ran_sam_search 00041 { 00042 public: 00043 //: Constructor using a non-deterministic random-sampling seed. 00044 rrel_ran_sam_search( ); 00045 00046 //: Constructor using a given random-sampling seed. 00047 rrel_ran_sam_search( int seed ); 00048 00049 virtual ~rrel_ran_sam_search(); 00050 00051 // Parameters to control the search technique. The default set 00052 // when the constructor is called is to sample as in generate 00053 // samples as specified in least-median of squares. 00054 00055 //: Indicate that all possible minimal subset samples should be tried. 00056 void set_gen_all_samples(); 00057 00058 //: Set the parameters for random sampling. 00059 void set_sampling_params( double max_outlier_frac = 0.5, 00060 double desired_prob_good = 0.99, 00061 unsigned int max_populations_expected = 1, 00062 unsigned int min_samples = 0 ); 00063 00064 // ---------------------------------------- 00065 // Main estimation functions 00066 // ---------------------------------------- 00067 00068 //: \brief Estimation for an "ordinary" estimation problem. 00069 virtual bool 00070 estimate( const rrel_estimation_problem* problem, 00071 const rrel_objective* obj_fcn ); 00072 00073 // ----------------------------------------- 00074 // Access to results and computed parameters 00075 // ----------------------------------------- 00076 00077 //: Get the scale estimate. 00078 double scale() const { return scale_; } 00079 00080 //: Get the parameter estimate. 00081 const vnl_vector<double>& params() const { return params_; } 00082 00083 //: Get the indices of best data sample 00084 const vcl_vector<int>& index() const { return indices_; } 00085 00086 //: Get the residuals for best sample 00087 const vcl_vector<double>& residuals() const { return residuals_; } 00088 00089 //: Get the cost for best sample returned by rrel_objective function 00090 double cost() const { return min_obj_; } 00091 00092 //: Get the number of samples tested in during estimation. 00093 int samples_tested() const { return samples_to_take_; } 00094 00095 //: Print the sampling parameters. Used for debugging. 00096 void print_params() const; 00097 00098 void set_trace_level( int level ) { trace_level_ = level; } 00099 00100 protected: 00101 // ------------------------------------------------------------ 00102 // Random sampling functions. Don't call directly. These are 00103 // public for test purposes. 00104 // ------------------------------------------------------------ 00105 00106 //: Calculate number of samples --- non-unique matching estimation problems 00107 virtual void 00108 calc_num_samples( const rrel_estimation_problem* problem ); 00109 00110 //: Determine the next random sample, filling in the "sample" vector. 00111 virtual void 00112 next_sample( unsigned int taken, unsigned int num_points, vcl_vector<int>& sample, 00113 unsigned int points_per_sample ); 00114 00115 private: 00116 00117 void trace_sample( const vcl_vector<int>& point_indices ) const; 00118 void trace_residuals( const vcl_vector<double>& residuals ) const; 00119 00120 protected: 00121 // 00122 // Parameters 00123 // 00124 double max_outlier_frac_; 00125 double desired_prob_good_; 00126 unsigned int max_populations_expected_; 00127 unsigned int min_samples_; 00128 bool generate_all_; 00129 00130 //: Random number generator. 00131 // Normally, this will point to the "global" generator, but a could 00132 // point to a local one if the user wants to specify a seed. 00133 vnl_random* generator_; 00134 bool own_generator_; 00135 00136 // 00137 // The estimate 00138 // 00139 vnl_vector<double> params_; 00140 double scale_; 00141 vcl_vector<int> indices_; 00142 vcl_vector<double> residuals_; 00143 00144 double min_obj_; 00145 // 00146 // Sampling variables 00147 // 00148 unsigned int samples_to_take_; 00149 00150 int trace_level_; 00151 }; 00152 00153 #endif