node.h
Go to the documentation of this file.
00001 /* This file is part of RGBDSLAM.
00002  * 
00003  * RGBDSLAM is free software: you can redistribute it and/or modify
00004  * it under the terms of the GNU General Public License as published by
00005  * the Free Software Foundation, either version 3 of the License, or
00006  * (at your option) any later version.
00007  * 
00008  * RGBDSLAM is distributed in the hope that it will be useful,
00009  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  * GNU General Public License for more details.
00012  * 
00013  * You should have received a copy of the GNU General Public License
00014  * along with RGBDSLAM.  If not, see <http://www.gnu.org/licenses/>.
00015  */
00016 
00017 
00018 #ifndef RGBD_SLAM_NODE_H_
00019 #define RGBD_SLAM_NODE_H_
00020 
00021 
00022 #include "ros/ros.h"
00023 #include <vector>
00024 #include <opencv2/core/core.hpp>
00025 #include <opencv2/features2d/features2d.hpp>
00026 #include <Eigen/Core>
00027 //#include <image_geometry/pinhole_camera_model.h>
00028 #include <sensor_msgs/PointCloud2.h>
00029 #include <sensor_msgs/CameraInfo.h>
00030 #include <pcl/registration/icp.h>
00031 #include <pcl/registration/registration.h>
00032 #include "parameter_server.h"
00033 //for ground truth
00034 #include <tf/transform_datatypes.h>
00035 #include <QMutex>
00036 
00037 // ICP_1 for external binary
00038 //#define USE_ICP_BIN
00039 
00040 // ICP_2 for included function
00041 //#define USE_ICP_CODE
00042 
00043 //#define USE_SIFT_GPU
00044 
00045 #ifdef USE_ICP_BIN
00046 #include "gicp-fallback.h"
00047 #endif
00048 
00049 #ifdef USE_ICP_CODE
00050 #include "gicp/gicp.h"
00051 #include "gicp/transform.h"
00052 #endif
00053 
00054 #include "matching_result.h" 
00055 #include <Eigen/StdVector>
00056 
00058 class Node {
00059 public:
00063         Node(const cv::Mat& visual,
00064                          const cv::Mat& depth,
00065                          const cv::Mat& detection_mask,
00066        const sensor_msgs::CameraInfoConstPtr& cam_info, 
00067        std_msgs::Header depth_header,
00068                          cv::Ptr<cv::FeatureDetector> detector,
00069                          cv::Ptr<cv::DescriptorExtractor> extractor);
00073         Node(const cv::Mat visual,
00074                          cv::Ptr<cv::FeatureDetector> detector,
00075                          cv::Ptr<cv::DescriptorExtractor> extractor,
00076                          pointcloud_type::Ptr point_cloud,
00077                          const cv::Mat detection_mask = cv::Mat());
00078         //default constructor. TODO: still needed?
00079         Node(){}
00081         ~Node();
00082 
00084   MatchingResult matchNodePair(const Node* older_node);
00085   //MatchingResult matchNodePair2(const Node* older_node);
00086 
00088   void setOdomTransform(tf::StampedTransform odom);
00090   void setGroundTruthTransform(tf::StampedTransform gt);
00092   void setBase2PointsTransform(tf::StampedTransform& b2p);
00094   tf::StampedTransform getOdomTransform();
00096   tf::StampedTransform getGroundTruthTransform();
00098   tf::StampedTransform getBase2PointsTransform();
00099 
00101         bool getRelativeTransformationTo(const Node* target_node, 
00102                         std::vector<cv::DMatch>* initial_matches,
00103                         Eigen::Matrix4f& resulting_transformation, 
00104                         float& rmse,
00105                         std::vector<cv::DMatch>& matches) const;
00106 
00107 #ifdef USE_ICP_BIN
00108         // initial_transformation: optional transformation applied to this->pc before
00109         // using icp
00110         bool getRelativeTransformationTo_ICP_bin(const Node* target_node,Eigen::Matrix4f& transformation,
00111                         const Eigen::Matrix4f* initial_transformation = NULL);
00112 #endif
00113         
00114 
00116         void publish(ros::Time timestamp, ros::Publisher pub);
00117 
00118         void buildFlannIndex();
00121         unsigned int featureMatching(const Node* other, std::vector<cv::DMatch>* matches) const;
00122 
00123 #ifdef USE_ICP_CODE
00124         bool getRelativeTransformationTo_ICP_code(const Node* target_node,
00125                                             Eigen::Matrix4f& transformation,
00126                                             const Eigen::Matrix4f& initial_transformation);
00127         
00128         static const double gicp_epsilon = 1e-4;
00129         static const double gicp_d_max = 0.20; // 10cm
00130         static const int gicp_max_iterations = 10;
00131         static const int gicp_min_point_cnt = 100;
00132                 
00133         bool gicp_initialized;
00134         void Eigen2GICP(const Eigen::Matrix4f& m, dgc_transform_t g_m);
00135         void GICP2Eigen(const dgc_transform_t g_m, Eigen::Matrix4f& m);
00136         void gicpSetIdentity(dgc_transform_t m);
00137   dgc::gicp::GICPPointSet* getGICPStructure(unsigned int max_count = 0) const;
00138   void clearGICPStructure() const;
00139   protected:
00140     mutable dgc::gicp::GICPPointSet* gicp_point_set_;
00141 
00142   public:
00143 #endif
00144 
00145   void clearFeatureInformation();
00146   void addPointCloud(pointcloud_type::Ptr pc_col);
00147 
00148 
00150   void clearPointCloud();
00151         //PointCloud pc;
00153         unsigned int id_; 
00154   pointcloud_type::Ptr pc_col;
00156         cv::Mat feature_descriptors_;         
00157 
00159         std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> > feature_locations_3d_;  
00160         std::vector<float> siftgpu_descriptors;
00161 
00163         std::vector<cv::KeyPoint> feature_locations_2d_; 
00165   std::vector<std::pair<float, float> > feature_depth_stats_;
00166 
00167 
00168 
00169 
00170 protected:
00171   static QMutex gicp_mutex;
00172   static QMutex siftgpu_mutex;
00173         cv::flann::Index* flannIndex;
00174   tf::StampedTransform base2points_; 
00175   tf::StampedTransform ground_truth_transform_;
00176   tf::StampedTransform odom_transform_;        
00177   int initial_node_matches_;
00178   //void computeKeypointDepthStats(const cv::Mat& depth_img, const std::vector<cv::KeyPoint> keypoints);
00179 
00180 #ifdef USE_SIFT_GPU
00181 
00182         void projectTo3DSiftGPU(std::vector<cv::KeyPoint>& feature_locations_2d,
00183                           std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> >& feature_locations_3d,
00184                             const pointcloud_type::Ptr point_cloud, 
00185                             std::vector<float>& descriptors_in, cv::Mat& descriptors_out);
00187         void projectTo3DSiftGPU(std::vector<cv::KeyPoint>& feature_locations_2d,
00188                           std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> >& feature_locations_3d,
00189                           const cv::Mat& depth,
00190                           const sensor_msgs::CameraInfoConstPtr& cam_info,
00191                           std::vector<float>& descriptors_in, cv::Mat& descriptors_out);
00192 #endif
00193 
00194         void projectTo3D(std::vector<cv::KeyPoint>& feature_locations_2d,
00195                    std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> >& feature_locations_3d,
00196                    const pointcloud_type::ConstPtr point_cloud);
00198         void projectTo3D(std::vector<cv::KeyPoint>& feature_locations_2d,
00199                    std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> >& feature_locations_3d,
00200                    const cv::Mat& depth,
00201                    const sensor_msgs::CameraInfoConstPtr& cam_info);
00202 
00203         // helper for ransac
00204         template<class CONTAINER>
00205         Eigen::Matrix4f getTransformFromMatchesUmeyama(const Node* other_node, CONTAINER matches) const;
00206         // helper for ransac
00207         // check for distances only if max_dist_cm > 0
00208         template<class CONTAINER>
00209         Eigen::Matrix4f getTransformFromMatches(const Node* other_node, 
00210                                           const CONTAINER & matches,
00211                                           bool& valid, 
00212                                           float max_dist_m = -1) const;
00213         //std::vector<cv::DMatch> const* matches,
00214         //pcl::TransformationFromCorrespondences& tfc);
00215 
00217         void mat2dist(const Eigen::Matrix4f& t, double &dist){
00218                 dist = sqrt(t(0,3)*t(0,3)+t(1,3)*t(1,3)+t(2,3)*t(2,3));
00219         }
00220 
00221   
00223   void retrieveBase2CamTransformation();
00224         // helper for ransac
00225   template<class CONTAINER>
00226         void computeInliersAndError(const CONTAINER & initial_matches,
00227                               const Eigen::Matrix4f& transformation,
00228                               const std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> >& origins,
00229                               const std::vector<std::pair<float, float> > origins_depth_stats,
00230                               const std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> >& targets,
00231                               const std::vector<std::pair<float, float> > targets_depth_stats,
00232                               std::vector<cv::DMatch>& new_inliers, //output var
00233                               double& mean_error, std::vector<double>& errors,
00234                               double squaredMaxInlierDistInM = 0.0009) const; //output var;
00235 
00236 public:
00237         EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00238 };
00239 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends Defines


rgbdslam
Author(s): Felix Endres, Juergen Hess, Nikolas Engelhard
autogenerated on Wed Dec 26 2012 15:53:08