model_estimation.h
Go to the documentation of this file.
00001 //part of the source code of master thesis, source code produced by Jiri Divis
00011 #ifndef VSLAM_MODEL_ESTIMATION_H_INCLUDED
00012 #define VSLAM_MODEL_ESTIMATION_H_INCLUDED
00013 
00014 #include "model.h"
00015 #include "error_func.h"
00016 #include "utils.h"
00017 #include <Eigen/Dense>
00018 #include "sfm_utils.h"
00019 #include "lihartley5pt/interface.h"
00020 
00021 /*------------------------------------------------------------------------------------------------*/
00022 /*------------------------------------------------------------------------------------------------*/
00034 struct ImageMatchClass{
00035     typedef ALIGNED<ImageMatchClass>::vector ImageMatchClassVec;
00036     const Vector3d im_c1, im_c2;
00037     ImageMatchClass(const Vector3d& a, const Vector3d& b) : im_c1(a), im_c2(b) { }
00038     ImageMatch getAsImageMatch(){
00039         return std::make_pair(im_c1, im_c2);
00040     }
00041 };
00042 
00043 
00050 template<class ErrorAccumClassT> 
00051         class Point3dModelFromLandmarkObservationPairBuilder : public GeneralizedModelBuilder<ErrorAccumClassT>{
00052     public:
00053         typedef Model<Vector3d, LandmarkObservation> Point3dModel;
00054 
00055         Point3dModelFromLandmarkObservationPairBuilder(const ErrorAccumClassT& _error_accum) :
00056                 GeneralizedModelBuilder<ErrorAccumClassT>(_error_accum) { }
00057 
00058         virtual shared_ptr<Point3dModel> operator()(const Point3dModel::DataVec & selected){
00059                 assert(selected.size()==getSize());
00060                 LandmarkObservation oa = selected[0];
00061                 LandmarkObservation ob = selected[1];
00062                 Vector3d pt_c1; 
00063                 Vector3d oa_bproj, ob_bproj;
00064                 oa_bproj = PanoImCoord::fromPixel(oa.pixel).getHomogenous();
00065                 ob_bproj = PanoImCoord::fromPixel(ob.pixel).getHomogenous();
00066                 computeStructureForcePositiveDepth( ob.T_cw.inverse() * oa.T_cw, 
00067                         ImageMatchClass(oa_bproj, ob_bproj).getAsImageMatch(), pt_c1);
00068                 Vector3d pt_w = oa.T_cw * pt_c1;
00069                 return shared_ptr<Point3dModel>(new SingleSolutionModel<ErrorAccumClassT>(
00070                             getSize(), selected, pt_w, this->error_accum));
00071             }
00072         virtual unsigned int getSize() const { return 2; }
00073 };
00074 
00076 /*------------------------------------------------------------------------------------------------*/
00077 
00078 /*------------------------------------------------------------------------------------------------*/
00081 
00082 
00083 class ScaleObservation{
00084     public:
00085         Vector2d k_proj_measurement;
00086         Vector2d n_proj_measurement;
00087         Vector3d lm_estimate_kk_k;
00088         SE3 T_wk; 
00089         SE3 T_kn; 
00090     //ScaleObservation(const G& g, const FeatureID<G>& fid, const SE3& T_kn){}
00091 };
00092 
00093 
00094 
00095 class ScaleReprojectionError : public DatumErrorFunc<double, ScaleObservation, Vector2d> {
00096     private:
00097         LandmarkToPoseReprojectionError lm_reprojection_error;
00098     public:
00099         virtual Vector2d operator()(const double& model, const ScaleObservation& datum) const{
00100             SE3 T_kn(datum.T_kn.unit_quaternion(), model * datum.T_kn.translation());    
00101             LandmarkObservation lm_obs((T_kn * datum.T_wk).inverse(), datum.n_proj_measurement);
00102             return lm_reprojection_error(datum.T_wk.inverse() * datum.lm_estimate_kk_k, lm_obs);
00103         }
00104 };
00105 
00106 
00107 template<class ErrorAccumClassT> 
00108     class ScaleModelBuilder : public GeneralizedModelBuilder<ErrorAccumClassT>{
00109         public:
00110             typedef typename ErrorAccumClassT::ModelClassT ScaleModel;
00111 
00112             ScaleModelBuilder(const ErrorAccumClassT& _error_accum) : 
00113                 GeneralizedModelBuilder<ErrorAccumClassT>(_error_accum) { }
00114 
00115             virtual shared_ptr<ScaleModel> operator()(const typename ScaleModel::DataVec & selected){
00116                 assert(selected.size()==this->getSize());
00117                 ScaleObservation datum = selected[0];
00118                 Vector3d estimate_kn_k;
00119                 computeStructureForcePositiveDepth(
00120                         datum.T_kn, 
00121                         computeMatch(datum.k_proj_measurement, datum.n_proj_measurement),
00122                         estimate_kn_k);
00123                 return shared_ptr<ScaleModel>(new SingleSolutionModel<ErrorAccumClassT>(
00124                         getSize(), 
00125                         selected, 
00126                         (datum.lm_estimate_kk_k.norm() / estimate_kn_k.norm()),
00127                         this->error_accum));
00128             }
00129 
00130             virtual unsigned int getSize() const { return 1; }
00131 };
00132 
00134 /*------------------------------------------------------------------------------------------------*/
00135 
00137 /*------------------------------------------------------------------------------------------------*/
00138 
00139 /*------------------------------------------------------------------------------------------------*/
00142 
00145 
00146 
00148 template<class ContainerT> class DataSelector{
00149     public:
00153         virtual shared_ptr<ContainerT> select() = 0;
00154 };
00155 
00156 
00157 template<class ContainerT> class RandomDataSelector : public DataSelector<ContainerT>{
00158     const ContainerT data;
00159     int model_size;
00160     int num_iterations;
00161     int iterations;
00162 
00163     public:
00164         RandomDataSelector(const ContainerT& _data, int _model_size, int _num_iterations) : 
00165                 data(_data), model_size(_model_size) {
00166             num_iterations=_num_iterations;        
00167             iterations=0;
00168         }
00169 
00170         virtual shared_ptr<ContainerT> select(){
00171             if(iterations > num_iterations) return shared_ptr<ContainerT>();
00172 
00173             std::set<int> selected_idx;
00174             assert(static_cast<int>(data.size())>=model_size);
00175             while(static_cast<int>(selected_idx.size()) < model_size){
00176                 boost::uniform_int<> interval(0,data.size() - 1);
00177                 selected_idx.insert(interval(rng_mt19937));
00178             }
00179             shared_ptr<ContainerT> selected(new ContainerT());
00180             for(std::set<int>::iterator it=selected_idx.begin(); it!=selected_idx.end(); it++){
00181                 selected->push_back(data[*it]);
00182             }
00183             ++iterations;
00184             return selected;
00185         }
00186 };
00187 
00188 template<class ContainerT> class PairSelectorFromTwoSets : public DataSelector<ContainerT>{
00189     private:
00190         const ContainerT data1, data2;
00191         typename ContainerT::const_iterator it1, it2;
00192         bool past_end;
00193 
00194         PairSelectorFromTwoSets(const ContainerT& _data1, const ContainerT& _data2) :
00195                 data1(_data1), data2(_data2){
00196             it1=data1.begin();
00197             it2=data2.begin();
00198             past_end=false;
00199         }
00200 
00201         virtual shared_ptr<ContainerT> select(){
00202             if(past_end) return 0;
00203 
00204             shared_ptr<ContainerT> selected_data(new ContainerT());
00205             selected_data->push_back(*it1);
00206             selected_data->push_back(*it2);
00207 
00208             it2++;
00209             if(it2==data2.end()){
00210                 it1++;
00211                 if(it1==data1.end()){
00212                     past_end=true;
00213                 } else{
00214                     it2=data2.begin();
00215                 }
00216             }
00217 
00218             return selected_data;
00219         }
00220 };
00221 
00222 
00223 template<class ContainerT> class AllCombinationsSelector : public DataSelector<ContainerT>{
00224     private:
00225         const ContainerT data;
00226         std::deque<typename ContainerT::const_iterator> state;
00227         bool past_end;
00228         int model_size;
00229 
00230         typedef typename ContainerT::const_iterator T;
00231 
00232         void next(){
00233             T it = state.back();
00234             state.pop_back();
00235             ++it;
00236             if(it == data.end()){
00237                 if(state.size()==0){
00238                     past_end=true;
00239                 } else{
00240                     next();
00241                 }
00242                 state.push_back(data.begin());
00243             } else{
00244                 state.push_back(it);
00245             }
00246         }
00247     public:
00248         AllCombinationsSelector(const ContainerT& _data, int _model_size) :
00249                 data(_data), model_size(_model_size){
00250             assert(static_cast<int>(data.size()) > model_size);
00251             for(int i=0; i < model_size;i++){
00252                 typename ContainerT::const_iterator it = data.begin();
00253                 for(int j=0; j<i; j++){
00254                     it++;
00255                 }
00256                 state.push_back(it);
00257             }
00258             past_end=false;
00259         }
00260 
00261         virtual shared_ptr<ContainerT> select(){
00262             if(past_end){
00263                 return shared_ptr<ContainerT>();
00264             } else{
00265                 shared_ptr<ContainerT> selected_data(new ContainerT());
00266                 BOOST_FOREACH(T it, state){
00267                     selected_data->push_back(*it);
00268                 }
00269                 next();
00270                 return selected_data;
00271             }
00272         }
00273 };
00274 
00276 /*------------------------------------------------------------------------------------------------*/
00277 
00278 
00282 template<class ErrorAccumClassT> class RanSaCOptions{
00283     private:
00284         int iterations;
00285         shared_ptr<double> inlier_ratio;
00286         shared_ptr<int> min_inliers;
00287     public:
00288         RanSaCOptions(int _iterations, double _inlier_ratio = 0.35) : 
00289                 iterations(_iterations), inlier_ratio(new double(_inlier_ratio)) {
00290             assert(_inlier_ratio < 1.0);
00291         }
00292 
00293         RanSaCOptions(int _iterations, int _min_inliers) :
00294                 iterations(_iterations), 
00295                 min_inliers(new int(_min_inliers)) {}
00296 
00297         int getMinInliers(
00298                 shared_ptr<ModelBuilder<ErrorAccumClassT> > mbuilder, int data_size) const{
00299             int val;
00300             if(min_inliers){
00301                 val = *min_inliers;
00302             } else{
00303                 val = static_cast<int>(data_size * *inlier_ratio);
00304             }
00305             val = std::max(val, mbuilder->getSize());
00306             return val;
00307         }
00308 
00309         int getIterations() const{
00310             return iterations;
00311         }
00312 };
00313 
00314 
00321 template<class ErrorAccumClassT> shared_ptr<typename ErrorAccumClassT::ModelClassT> ranSaC(
00322         shared_ptr<ModelBuilder<typename ErrorAccumClassT::ModelClassT> > model_builder,
00323         shared_ptr<DataSelector<typename ErrorAccumClassT::ModelClassT::DataVec> > data_selector,
00324         const typename ErrorAccumClassT::ModelClassT::DataVec & data){
00325     typedef typename ErrorAccumClassT::ModelClassT ModelT;
00326     assert(model_builder);
00327     assert(data_selector);
00328     assert(data.size()>= model_builder->getSize());
00329     shared_ptr<ModelT> model, best_model;
00330     shared_ptr<typename ModelT::DataVec> selected = data_selector->select();
00331     while(selected){
00332         shared_ptr<ModelT> model = model_builder->operator()(*selected);
00333         if(model){ 
00334             model->compute(data);
00335             if (!best_model || (best_model->getInlierCount() < model->getInlierCount())){
00336                 best_model = model;
00337             }
00338         }
00339         selected = data_selector->select();
00340     }
00341     return best_model;
00342 }
00343 
00345 /*------------------------------------------------------------------------------------------------*/
00346 
00348 /*------------------------------------------------------------------------------------------------*/
00349 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines


pose_estimation
Author(s): Jiri Divis/jiridivis@gmail.com
autogenerated on Wed Mar 27 2013 21:00:12