Go to the documentation of this file.00001
00002
00005
00008
00015 #ifndef VSLAM_MODEL_H_INCLUDED
00016 #define VSLAM_MODEL_H_INCLUDED
00017
00018 typedef std::vector<bool> MaskVec;
00019
00023 template<class ModelT, class DatumT> class Model{
00024 public:
00025 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00026 typedef typename ALIGNED<DatumT>::vector DataVec;
00027 typedef ModelT ModelRep;
00028 typedef DatumT Datum;
00029 protected:
00030 const unsigned int size;
00031 const DataVec model_data;
00032 ModelT model;
00033 double error;
00034 double all_data_error;
00035 vector<bool> inlier_mask;
00036 typename DataVec::size_type inlier_count;
00037 public:
00038 Model(int _size, const DataVec& _model_data, const ModelT& _model) :
00039 size(_size), model_data(_model_data), model(_model) {}
00040
00049 virtual void compute(const DataVec & image_matches) = 0;
00050
00052 double getError() const{
00053 assert(inlier_mask.size() > 0);
00054 return all_data_error;
00055 }
00056
00058 double getInlierError() const{
00059 assert(inlier_mask.size() > 0);
00060 return error;
00061 }
00062
00064 const vector<bool> & getInlierMask() const{
00065 assert(inlier_mask.size() > 0);
00066 return inlier_mask;
00067 }
00068
00070 int getInlierCount() const{
00071 assert(inlier_mask.size() > 0);
00072 return inlier_count;
00073 }
00074
00081 DataVec getInliers(const DataVec & all_data){
00082 assert(inlier_mask.size() > 0);
00083 DataVec inliers(inlier_count);
00084 typename DataVec::iterator inliers_it = inliers.begin();
00085 typename DataVec::const_iterator it = all_data.begin();
00086 typename MaskVec::const_iterator it_mask = inlier_mask.begin();
00087 while(it!=all_data.end()){
00088 if(*it_mask) *inliers_it = *it;
00089 ++it; ++it_mask;
00090 }
00091 return inliers;
00092 }
00093
00094 int getSize() const{
00095 return size;
00096 }
00097
00098 const ModelT & getModel() const{
00099 return model;
00100 }
00101 const DataVec& getModelData() const{
00102 return model_data;
00103 }
00104
00105 };
00106
00107 typedef Model<Matrix3d, ImageMatch> EMatrixModel;
00108
00109
00116 template<class ErrorAccumulatorT> class SingleSolutionModel : public
00117 Model<typename ErrorAccumulatorT::ModelRep, typename ErrorAccumulatorT::DatumT>{
00118 protected:
00119 ErrorAccumulatorT error_acc;
00120
00121 public:
00122 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00123
00124 typedef Model<typename ErrorAccumulatorT::ModelRep, typename ErrorAccumulatorT::DatumT>
00125 ModelClassT;
00126
00127 SingleSolutionModel(
00128 int _size,
00129 const typename ModelClassT::DataVec& _model_data,
00130 const typename ErrorAccumulatorT::ModelRep& _model,
00131 const ErrorAccumulatorT& _error) :
00132 Model<typename ErrorAccumulatorT::ModelRep, typename ErrorAccumulatorT::DatumT>(
00133 _size, _model_data, _model), error_acc(_error) {}
00134
00135 virtual void compute(const typename ModelClassT::DataVec & all_data){
00136 this->inlier_mask.resize(all_data.size());
00137 this->error=0;
00138 this->all_data_error=0;
00139 this->inlier_count=0;
00140 typename ModelClassT::DataVec::const_iterator all_data_it = all_data.begin();
00141 vector<bool>::iterator inlier_mask_it = this->inlier_mask.begin();
00142 while(all_data_it!=all_data.end()){
00143 assert(inlier_mask_it != this->inlier_mask.end());
00144 double tmp = error_acc.computeError(this->getModel(), *all_data_it);
00145 if(error_acc.isInlier(tmp)){
00146 *inlier_mask_it = true;
00147 this->error = error_acc.errorAccumulator(this->error, tmp);
00148 this->inlier_count++;
00149 } else{
00150 *inlier_mask_it = false;
00151 }
00152 this->all_data_error = error_acc.errorAccumulator(this->all_data_error, tmp);
00153 ++all_data_it; ++inlier_mask_it;
00154 }
00155 assert(inlier_mask_it == this->inlier_mask.end());
00156 }
00157 };
00158
00159
00160 template<class ErrorAccumulatorT, template<class> class CAllocTT> class MultiSolutionModel :
00161 public Model<typename ErrorAccumulatorT::ModelRep, typename ErrorAccumulatorT::DatumT> {
00162 public:
00163 typedef typename ErrorAccumulatorT::ModelRep ModelRepT;
00164 typedef typename ErrorAccumulatorT::ModelClassT ModelT;
00165 typedef std::vector<ModelRepT, CAllocTT<ModelRepT> > ModelRepVecT;
00166
00167 protected:
00168 ErrorAccumulatorT error_acc;
00169 ModelRepVecT models;
00170
00171 virtual void compute(const typename ModelT::DataVec & all_data){
00172 shared_ptr<shared_ptr<typename ErrorAccumulatorT::ModelT> > model_tmp, best_model;
00173 BOOST_FOREACH(ModelRepT mr, models){
00174 model_tmp.reset(new SingleSolutionModel<ErrorAccumulatorT>(
00175 this->model_data, mr, error_acc));
00176 model_tmp->compute(all_data);
00177 if(!best_model || (best_model->getInlierCount() < model_tmp->getInlierCount())){
00178 best_model = model_tmp;
00179 }
00180 }
00181 assert(best_model != models.end());
00182 this->model = best_model->getModel();
00183 this->error = best_model->getError();
00184 this->all_data_error = best_model->all_data_error;
00185 this->inlier_mask = best_model->getInlierMask();
00186 this->inlier_count = best_model->getInlierCount();
00187 }
00188
00189 public:
00190 MultiSolutionModel(
00191 int _size,
00192 const typename ModelT::DataVec& _model_data,
00193 const ModelRepVecT & _models,
00194 const ErrorAccumulatorT& _error) :
00195 Model<ModelRepT, typename ErrorAccumulatorT::DatumT>(
00196 _size, _model_data), models(_models), error_acc(_error) {}
00197
00198
00199 };
00200
00201
00203 template<class ModelClassT> class ModelBuilder{
00204 public:
00206 virtual shared_ptr<ModelClassT> operator()(
00207 const typename ModelClassT::DataVec & selected) = 0;
00208
00210 virtual unsigned int getSize() const = 0;
00211 };
00212
00213 typedef ModelBuilder<EMatrixModel> EMatrixModelBuilder;
00214
00215
00223 template<class ErrorAccumClassT> class GeneralizedModelBuilder : public
00224 ModelBuilder<typename ErrorAccumClassT::ModelClassT>{
00225 protected:
00226 ErrorAccumClassT error_accum;
00227 public:
00228 GeneralizedModelBuilder(const ErrorAccumClassT& _error_accum) : error_accum(_error_accum) { }
00230 virtual shared_ptr<typename ErrorAccumClassT::ModelClassT> operator()(
00231 const typename ErrorAccumClassT::ModelClassT::DataVec & selected) = 0;
00232
00234 virtual unsigned int getSize() const = 0;
00235 };
00237
00239
00240
00241 #endif