pose_graph.h
Go to the documentation of this file.
00001 //part of the source code of master thesis of Jiri Divis, source code written by Jiri Divis
00011 #ifndef VSLAM_POSE_GRAPH_H_INCLUDED
00012 #define VSLAM_POSE_GRAPH_H_INCLUDED
00013 
00014 #include "utils.h"
00015 #include "tf/transform_listener.h"
00016 #include "sensor_msgs/CameraInfo.h"
00017 #include "sensor_msgs/CompressedImage.h"
00018 #include "cv_bridge/cv_bridge.h"
00019 #include "image_transport/image_transport.h" 
00020 #include "Sophus/se3.h"
00021 //#include "sfm_utils.h" //XXX moove
00022 #include "feature_matching.h"
00023 
00024 #include <vector>
00025 #include <string>
00026 #include <iostream>
00027 #include <fstream>
00028 #include <opencv2/core/core.hpp>
00029 #include <opencv2/imgproc/imgproc.hpp>
00030 #include <opencv2/highgui/highgui.hpp>
00031 #include <opencv2/features2d/features2d.hpp>
00032 #include <opencv2/calib3d/calib3d.hpp>
00033 #include <assert.h>
00034 #include <algorithm>
00035 #include <boost/graph/adjacency_list.hpp>
00036 #include <boost/graph/depth_first_search.hpp>
00037 #include <map>
00038 //#include <boost/tr1/functional.hpp> // XXX
00039 
00040 
00041 
00042 namespace boost{
00058 
00059 
00066 
00067     
00069     enum vertex_kp_t { vertex_kp = 101 }; 
00071     enum vertex_desc_t { vertex_desc = 102 }; 
00073 
00081     enum vertex_fix_idx_t { vertex_fix_idx = 103 }; 
00082 
00084     enum vertex_seq_t { vertex_seq = 104 }; 
00085 
00087     enum vertex_transform_t { vertex_transform = 105 }; 
00088     
00093     enum vertex_keyframe_flag_t { vertex_keyframe_flag = 106 }; 
00094 
00096     enum vertex_debug_info_t { vertex_debug_info = 107 };
00097 
00099     enum vertex_timestamp_t { vertex_timestamp = 108 }; 
00100 
00102     enum edge_kp_idx_map_t { edge_kp_idx_map= 201 }; 
00103 
00105 
00106     enum edge_transform_t { edge_transform= 202 }; 
00107     
00109     enum edge_rel_scale_error_t { edge_rel_scale_error= 203 }; 
00110 
00112     enum graph_points_t { graph_points= 301 }; 
00113 
00114     BOOST_INSTALL_PROPERTY(vertex, kp);
00115     BOOST_INSTALL_PROPERTY(vertex, desc);
00116     BOOST_INSTALL_PROPERTY(vertex, fix_idx);
00117     BOOST_INSTALL_PROPERTY(vertex, seq);
00118     BOOST_INSTALL_PROPERTY(vertex, transform);
00119     BOOST_INSTALL_PROPERTY(vertex, keyframe_flag);
00120     BOOST_INSTALL_PROPERTY(vertex, debug_info);
00121     BOOST_INSTALL_PROPERTY(vertex, timestamp);
00122 
00123     BOOST_INSTALL_PROPERTY(edge, kp_idx_map);
00124     BOOST_INSTALL_PROPERTY(edge, transform);
00125     BOOST_INSTALL_PROPERTY(edge, rel_scale_error);
00126 
00127     BOOST_INSTALL_PROPERTY(graph, points);
00129 
00131 }
00132 
00133 
00134 namespace vslam{
00138 using boost::vertex_kp;
00139 using boost::vertex_desc;
00140 using boost::vertex_fix_idx;
00141 using boost::vertex_seq;
00142 using boost::vertex_transform;
00143 using boost::vertex_keyframe_flag;
00144 using boost::vertex_debug_info;
00145 using boost::vertex_timestamp;
00146 using boost::edge_kp_idx_map;
00147 using boost::edge_transform;
00148 using boost::edge_rel_scale_error;
00149 
00150 using boost::vertex_kp_t;
00151 using boost::vertex_desc_t;
00152 using boost::vertex_fix_idx_t;
00153 using boost::vertex_seq_t;
00154 using boost::vertex_transform_t;
00155 using boost::vertex_keyframe_flag_t;
00156 using boost::vertex_debug_info_t;
00157 using boost::vertex_timestamp_t;
00158 using boost::edge_kp_idx_map_t;
00159 using boost::edge_transform_t;
00160 using boost::edge_rel_scale_error_t;
00161 
00162 using std::list;
00163 using std::map;
00164 
00165 using boost::graph_traits; using boost::property_map; using boost::tie;
00166 
00167 
00168 const int BAD_INDEX = -1; 
00169 
00170 
00172 template<class G> class FeatureID{
00173     public:
00174         typename graph_traits<G>::vertex_descriptor vd;
00175         int vidx;
00176         
00177         FeatureID(typename graph_traits<G>::vertex_descriptor _vd, int _vidx) : 
00178                 vd(_vd), vidx(_vidx) {}
00179 };
00180 
00182 template<class G> bool isLandmakFeature(const G& g, const FeatureID<G>& fid){
00183     get(vertex_fix_idx, g, fid.vd)[0];
00184     return get(vertex_fix_idx, g, fid.vd)[fid.vidx]!=BAD_INDEX;
00185 }
00186 
00191 template<typename G> struct Point;
00192 
00193 namespace lmdetails{
00194     template<class G> class PointsLoc; 
00195 }
00196 
00202 template<class G> class Points{
00203     private:
00204         lmdetails::PointsLoc<G> points;
00205 
00206     public:
00207         EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00208 
00209         void activateLandmarks(
00210                 const G&g, typename graph_traits<G>::vertex_descriptor v, int keep_num);
00211 
00212         const Point<G> & getPoint(int idx) const;
00213 
00214         void lmEstimateUpd(int lm_id, Vector3d& new_estimate);
00215 
00216         void lmEstimateUpdChecked(int lm_id, Vector3d& new_estimate);
00217 
00218         void deleteLmObs(G&g, const FeatureID<G>& obs);
00219 
00220         int size() const;
00221 
00222 
00223         bool fixNewLandmark( FeatureID<G> fa, FeatureID<G> fm, FeatureID<G> fb, G& g);
00224 
00225         bool fixNewObservation( FeatureID<G> fa, FeatureID<G> fb, G& g);
00226 };
00227 
00228 
00233 
00234 class VertexDebugInfo{
00235     public:
00236         uint64_t seq;
00237         uint64_t timestamp;
00238         bool is_kf; // is keyframe
00239         //int num_kpts;
00240         //int num_kpts_nms; // # of kpts after NMS.
00241         //int num_2view_kpts;
00242         //int num_2view_kpts_max;
00243         int num_init_landmarks; // seen landmarks that are initialized
00244         int num_uinit_landmarks;
00245         double avg_reprojection_error;
00246         double max_reprojection_error;
00247         int num_discontinued_landmarks;
00248         int num_extended_landmarks;
00249         SE3 gt_T_wc;
00250         map<std::string, double> double_propmap;
00251 };
00252 
00253 
00254 
00256 
00257 typedef boost::adjacency_list<
00258         boost::vecS,
00259         boost::vecS, 
00260         boost::directedS,
00261         boost::property<vertex_kp_t, std::vector<cv::KeyPoint>, 
00262             boost::property<vertex_desc_t, cv::Mat,
00263                 boost::property<vertex_fix_idx_t, vector<int>,
00264                     boost::property<vertex_seq_t, int,
00265                         boost::property<boost::vertex_keyframe_flag_t, int,
00266                             boost::property<boost::vertex_debug_info_t, VertexDebugInfo,
00267                                 boost::property<boost::vertex_timestamp_t, uint64_t,
00268                                     boost::property<vertex_transform_t, SE3> > > > > > > >,
00269         boost::property<edge_kp_idx_map_t, map<int,int>,
00270             boost::property<edge_transform_t, SE3,
00271                 boost::property<edge_rel_scale_error_t, double> > > > PoseGraph;
00272 
00273 typedef graph_traits<PoseGraph>::vertex_descriptor PGVertexD;
00274 typedef graph_traits<PoseGraph>::edge_descriptor PGEdgeD;
00275 
00276 typedef ALIGNED<pair<int, Vector3d> >::vector IdxPoint3dVec;
00277 
00278 
00285 template<class G> class PerformanceLogger{
00286     public:
00287         typedef typename boost::graph_traits<G>::vertex_descriptor VDT;
00288     private:
00289         G& g;
00290         VDT vd;
00291         std::string str;
00292         ros::WallTime start_time;
00293         bool stop_forced;
00294     public:
00295         PerformanceLogger(G& _g, VDT _vd, std::string name_tag) : g(_g), vd(_vd){
00296             str = "timings_" + name_tag + "_d_x";
00297             start_time = ros::WallTime::now();
00298             stop_forced = false;
00299         }
00300 
00301         ~PerformanceLogger(){
00302             if(!stop_forced) forceStop();
00303         }
00304 
00305         void forceStop(){
00306             assert(!stop_forced);
00307             ros::WallDuration duration = ros::WallTime::now() - start_time;
00308             map<std::string, double> & propmap = get(vertex_debug_info, g, vd).double_propmap;
00309             if(propmap.find(str)!=propmap.end()){
00310                 str += "x";
00311             }
00312             propmap[str] = duration.toSec();
00313             stop_forced=true;
00314         }
00315 };
00316 /*------------------------------------------------------------------------------------------*/
00327 template<typename G> class EdgeBuilder{
00328     public:
00329         typedef typename graph_traits<G>::vertex_descriptor VertexD;
00330         typedef typename graph_traits<G>::edge_descriptor EdgeD;
00331 
00332     protected:
00333         static void featureSelection(G& g, VertexD vd, int target_num, vector<int>& keep_idxs, 
00334                 vector<cv::KeyPoint>& sel_keypoints, cv::Mat& sel_descriptors);
00335 
00336     public:
00350         bool build(const VertexD & src, const VertexD & dst, Points<G> & points, G & g){
00351             return buildImpl(src, dst, points, g);
00352         }
00353 
00354         virtual bool buildImpl(
00355                 const VertexD & src, const VertexD & dst, Points<G> & points, G & g) = 0;
00356 };
00357 
00358 
00359 
00363 template<typename G> class MonoFtrClassEdgeBuilder : public EdgeBuilder<G>{
00364     public:
00365         typedef typename graph_traits<G>::vertex_descriptor VertexD;
00366         typedef typename graph_traits<G>::edge_descriptor EdgeD;
00367     protected:
00368         std::tr1::shared_ptr<RobustFeatureMatcher> rmatcher;
00369 
00370         static void compute3viewStructure(VertexD vad, VertexD vbd, VertexD vcd, G & g,
00371         IdxPoint3dVec&, SE3&);
00372 
00373         static void matchScaleFindNewLandmarks(
00374                 VertexD vsrc, VertexD vdest, Points<G> & points, G & g);
00375 
00376         static void computeScale(VertexD contactvd, VertexD newvd, G & g, Points<G>& points, 
00377                 SE3& scaled_T_vbd_vcd);
00378 
00379         bool unguidedMatching(
00380                 const vector<cv::KeyPoint>& sel_tvd_keypoints,
00381                 const vector<cv::KeyPoint>& sel_qvd_keypoints,
00382                 const cv::Mat& sel_tvd_descriptors,
00383                 const cv::Mat& sel_qvd_descriptors,
00384                 SE3& T_tvd_qvd,
00385                 std::vector<cv::DMatch>& global_dmatches_c1c2);
00386 
00387         void guidedMatching( G& g, VertexD c1vd, VertexD c2vd); 
00388     public:
00389         MonoFtrClassEdgeBuilder<G>(std::tr1::shared_ptr<RobustFeatureMatcher> _rmatcher) :
00390                 rmatcher(_rmatcher) {}
00391 
00392 
00393         virtual bool buildImpl(
00394                 const VertexD & src, const VertexD & dst, Points<G> & points, G & g);
00395 };
00396 
00397 
00398 
00399 inline std::tr1::shared_ptr<RobustFeatureMatcher> constructRMatcher(
00400         std::tr1::shared_ptr<cv::DescriptorMatcher> _dmatcher,
00401         std::tr1::shared_ptr<EMatrixModelBuilder> _minbuilder, 
00402         std::tr1::shared_ptr<EMatrixModelBuilder> _builder = 
00403         std::tr1::shared_ptr<EMatrixModelBuilder>());
00405 /*------------------------------------------------------------------------------------------*/
00406 /*------------------------------------------------------------------------------------------*/
00409 
00411 class NMSOptions{
00412     public:
00413         bool do_nms;
00414         int target_num_points; 
00415 
00417         NMSOptions() : do_nms(false) {}
00419         NMSOptions(int _target_num_points) : do_nms(true), target_num_points(_target_num_points) {}
00420 };
00421 
00430 template<class PoseGraphT> class OneDetectorNodeBuilder {
00431     protected:
00432          shared_ptr<cv::DescriptorExtractor> extractor;
00433          shared_ptr<cv::FeatureDetector> detector;
00434          shared_ptr<cv::ORB> feature_2d_detector;
00435          cv::Mat mask;
00436          NMSOptions nms_options;
00437 
00438         OneDetectorNodeBuilder(NMSOptions _nms_options = NMSOptions()) : nms_options(_nms_options) {
00439             cv::Mat mask0 = cv::imread(image_mask_file);
00440             cv::cvtColor(mask0, mask, CV_RGB2GRAY);
00441         }
00442     public:
00443         typedef cv::Mat InputType;
00444 
00445         cv::Mat getPoseImage(const InputType& in){
00446             return in.clone();
00447         }
00448 
00460         bool build(const cv::Mat & image, int image_seq_num, uint64_t pose_timestamp,
00461                 typename graph_traits<PoseGraphT>::vertex_descriptor & vd, PoseGraphT& g);
00462 
00464         void demolish(PoseGraphT& g, Points<PoseGraphT>& points, 
00465                 typename graph_traits<PoseGraphT>::vertex_descriptor & vd);
00466 };
00467 
00468 template<class PoseGraphT>
00469 class CustomOneDetectorNodeBuilder : public OneDetectorNodeBuilder<PoseGraphT>{
00470     public:
00471         typedef cv::Mat InputType;
00472         CustomOneDetectorNodeBuilder(
00473                 std::tr1::shared_ptr<cv::FeatureDetector> _detector,
00474                 std::tr1::shared_ptr<cv::DescriptorExtractor> _extractor){
00475             this->detector=_detector;
00476             this->extractor=_extractor;
00477         }
00478 };
00479 
00480 template<class PoseGraphT>
00481 class CustomOneDetectorNodeBuilderFeature2D : public OneDetectorNodeBuilder<PoseGraphT>{
00482     public:
00483         typedef cv::Mat InputType;
00484         CustomOneDetectorNodeBuilderFeature2D(
00485                 std::tr1::shared_ptr<cv::ORB> _feature_2d_detector) : 
00486                 OneDetectorNodeBuilder<PoseGraphT>(NMSOptions(4000)){
00487             this->feature_2d_detector=_feature_2d_detector;
00488         }
00489 };
00490 
00493 } //namespace vslam
00494 
00495 /*------------------------------------------------------------------------------------------*/
00496 //boost stuff for running dijkstra algorithm on the pose-graph.
00497 /*------------------------------------------------------------------------------------------*/
00498 
00499 #include <boost/graph/dijkstra_shortest_paths.hpp>
00500 
00501 #include <iostream>
00502 #include <cmath>
00503 #include <tr1/functional>
00504 namespace vslam{
00506     template<class PoseGraphT> class AllWeightsOneWeightMap {
00507         PoseGraphT* dummy;
00508     };
00509 }
00510 
00511 namespace boost{
00513     template<class PoseGraphT> struct property_traits<vslam::AllWeightsOneWeightMap<PoseGraphT> >{
00514         typedef int value_type;
00515         typedef int reference;
00516         typedef typename graph_traits<PoseGraphT>::edge_descriptor key_type;
00517         typedef readable_property_map_tag category;
00518     };
00519 }
00520 
00521 namespace vslam{
00526     template<class PoseGraphT> int get(
00527             AllWeightsOneWeightMap<PoseGraphT> pmap, 
00528             typename boost::property_traits<AllWeightsOneWeightMap<PoseGraphT> >::key_type vd){
00529         return 1;
00530     };
00531 }
00532 
00533 
00534 
00535 #include "graph_builder.h"
00536 #endif
00537 
 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