00001
00002
00003 #ifndef VSLAM_ERROR_FUNC_H_INCLUDED
00004 #define VSLAM_ERROR_FUNC_H_INCLUDED
00005
00006 #include "utils.h"
00007 #include "sfm_utils.h"
00008 #include <Eigen/Dense>
00009 #include <boost/tr1/cmath.hpp>
00010
00011
00012
00025
00026
00027
00029 struct LandmarkObservation{
00030 SE3 T_cw;
00031 Vector2d pixel;
00032
00033 LandmarkObservation(const SE3& _T_cw, const Vector2d& _pixel) : T_cw(_T_cw), pixel(_pixel) { }
00034 bool operator==(const LandmarkObservation& other){
00035 return T_cw.matrix().isApprox(other.T_cw.matrix()) && pixel.isApprox(other.pixel);
00036 }
00037 };
00038
00039
00046 template<class ModelT, class DatumT, class ErrorT> class DatumErrorFunc{
00047 public:
00048 typedef Model<ModelT, DatumT> ModelClassT;
00049 typedef ModelT ModelRep;
00050 typedef DatumT Datum;
00051 typedef ErrorT Error;
00052
00053 virtual ErrorT operator()(const ModelT& model, const DatumT& datum) const = 0;
00054 };
00055
00056
00058 template<class ModelT, class DatumT>
00059 class DatumRealErrorFunc : public DatumErrorFunc<ModelT, DatumT, double> { };
00060
00061
00062
00063 template<class DatumErrorFuncT> class MDErrorFuncAdaptor : public
00064 DatumRealErrorFunc<typename DatumErrorFuncT::ModelRep, typename DatumErrorFuncT::Datum>{
00065 protected:
00066
00067 DatumErrorFuncT ef;
00068 public:
00069 MDErrorFuncAdaptor(const DatumErrorFuncT& _error_func) : ef(_error_func) {}
00070
00071 virtual double operator()(
00072 const typename DatumErrorFuncT::ModelRep& model,
00073 const typename DatumErrorFuncT::Datum& datum) const{
00074 return ef(model, datum).norm();
00075 }
00076 };
00077
00079 template<class ModelT, class DatumT> class DummyErrorFunc : public DatumRealErrorFunc<ModelT, DatumT>{
00080 public:
00081 virtual double operator()(const ModelT & E, const DatumT& datum) const{
00082 return 0;
00083 }
00084 };
00085
00091 template<class DatumErrorFuncT, class ErrorAccumulatorT> class ErrorAccumulator{
00092 protected:
00093 DatumErrorFuncT error_func;
00094 public:
00095 typedef typename DatumErrorFuncT::ModelClassT::ModelRep ModelRep;
00096 typedef typename DatumErrorFuncT::ModelClassT::Datum DatumT;
00097 typedef typename DatumErrorFuncT::Error ErrorT;
00098 typedef Model<ModelRep, DatumT> ModelClassT;
00099
00100 ErrorAccumulator(const DatumErrorFuncT& _error_func) : error_func(_error_func) { }
00101
00102 ErrorT computeError(const ModelRep& model, const DatumT& datum){
00103 return error_func(model, datum);
00104 }
00105
00106 bool inlierTest(const ErrorT& e) { assert(false); return false;}
00107
00108 ErrorAccumulatorT errorAccumulator(ErrorAccumulatorT ae, ErrorT e) {assert(false);}
00109 };
00110
00111 template<class DatumErrorFuncT>
00112 class RealErrorPlusErrorAccumulator : public ErrorAccumulator<DatumErrorFuncT, double>{
00113 protected:
00114 double treshold;
00115 public:
00116 RealErrorPlusErrorAccumulator(DatumErrorFuncT _error_func, double _treshold) :
00117 ErrorAccumulator<DatumErrorFuncT, double>(_error_func), treshold(_treshold) { }
00118
00119 bool isInlier(const double& e){ return e < treshold; }
00120
00121 double errorAccumulator(double ae, double e){ return ae + e; }
00122 };
00123
00124 template<class DatumErrorFuncT>
00125 class RealErrorMaxErrorAccumulator : public ErrorAccumulator<DatumErrorFuncT, double>{
00126 protected:
00127 double treshold;
00128 public:
00129 RealErrorMaxErrorAccumulator(DatumErrorFuncT _error_func, double _treshold) :
00130 ErrorAccumulator<DatumErrorFuncT, double>(_error_func), treshold(_treshold) { }
00131
00132 bool isInlier(const double& e){ return e < treshold; }
00133
00134 double errorAccumulator(double ae, double e){ return std::max(ae, e); }
00135 };
00136
00137
00144 class LandmarkToPoseReprojectionError : public DatumErrorFunc<Vector3d, LandmarkObservation, Vector2d>{
00145 public:
00149 virtual Vector2d operator()(const Vector3d& model, const LandmarkObservation& datum) const{
00150 Vector2d epx, mpx, wh, error;
00151 epx = PanoImCoord::fromHomogenous(datum.T_cw.inverse()*model).getPixel();
00152 mpx = datum.pixel;
00153
00154 wh(0)=PanoImCoord::Params::width;
00155 wh(1)=PanoImCoord::Params::height;
00156 for(int i=0; i<2;i++){
00157 error(i) =
00158 std::min(
00159 std::abs(epx(i) - mpx(i)),
00160 std::min(
00161 std::abs((epx(i) + wh(0)) - mpx(i)),
00162 std::abs((epx(i) - wh(0)) - mpx(i))));
00164
00165 }
00166 return error;
00167 }
00168 };
00169
00170
00171
00173 class DatumErrorFromSE3Tranform : public DatumRealErrorFunc<Matrix3d, ImageMatch>{
00174 ImageMatchVec selected;
00175 public:
00176 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00177 DatumErrorFromSE3Tranform(const ImageMatchVec & _selected) : selected(_selected) {}
00178
00179 virtual double operator()(const Matrix3d & E, const ImageMatch & image_match) const{
00180 SE3 T_c1c2;
00181 if(extractTransformFromE(selected, E, T_c1c2)){;
00182 Vector3d d1 = T_c1c2 * image_match.first;
00183 d1.normalize();
00184 Vector3d d2 = image_match.second;
00185 d2.normalize();
00186 return (d1-d2).norm();
00187 } else{
00188 return HUGE_VAL;
00189 }
00190 }
00191 };
00192
00193
00195 class AngleError : public DatumRealErrorFunc<Matrix3d, ImageMatch>{
00196 protected:
00197 double computeAbsoluteAngle(
00198 const Vector3d & hom_line, const Vector3d & hom_point) const{
00199 Vector3d pt_on_plane = closestPointOnEpipolarPlane(hom_line, hom_point);
00200
00201 double tmp = atan((hom_point - pt_on_plane).norm() / pt_on_plane.norm());
00202 if(!std::isfinite(tmp)) tmp = HUGE_VAL;
00203 return tmp;
00204 }
00205 public:
00206 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00207
00208 virtual double operator()(const Matrix3d & E, const ImageMatch & image_match) const{
00209 double error = computeAbsoluteAngle(E * image_match.first, image_match.second);
00210 error += computeAbsoluteAngle(image_match.second.transpose() * E, image_match.first);
00211 return error / 2.0;
00212 }
00213 };
00214
00216
00218
00220
00221
00222 #endif