$search
00001 #include "ros/ros.h" 00002 #include "std_msgs/String.h" 00003 #include "sensor_msgs/PointCloud2.h" 00004 #include <flann/io/hdf5.h> 00005 #include "boost/filesystem/operations.hpp" 00006 #include "boost/filesystem/path.hpp" 00007 #include <boost/lexical_cast.hpp> 00008 #include <boost/algorithm/string/replace.hpp> 00009 #include <boost/algorithm/string.hpp> 00010 #include <fstream> 00011 #include <iostream> 00012 #include <algorithm> 00013 #include <pcl/common/common.h> 00014 #include <pcl/features/normal_3d.h> 00015 #include <pcl/features/vfh.h> 00016 #include <pcl/features/cvfh.h> 00017 #include <pcl/ros/conversions.h> 00018 #include <pcl/io/pcd_io.h> 00019 #include <pcl/segmentation/extract_clusters.h> 00020 #include <flann/flann.h> 00021 #include <vector> 00022 #include <pcl/registration/transforms.h> 00023 #include <pcl/filters/voxel_grid.h> 00024 #include <pcl/registration/registration.h> 00025 #include <pcl/registration/icp.h> 00026 #include <pcl_ros/point_cloud.h> 00027 #include <ros/message_traits.h> 00028 #include <ros/serialization.h> 00029 #include "geometry_msgs/Pose.h" 00030 #include "tf/transform_datatypes.h" 00031 #include "LinearMath/btTransform.h" 00032 #include <string> 00033 #include <Eigen/Geometry> 00034 00035 #include <math.h> 00036 #include <limits> 00037 00038 #include "cv.h" 00039 00040 #define PI 3.14159265 00041 00042 namespace bf = boost::filesystem; 00043 namespace ser = ros::serialization; 00044 00045 namespace vfh_recognition 00046 { 00047 00048 typedef std::pair<std::string, std::vector<float> > vfh_model_db; 00049 typedef pcl::PointCloud<pcl::PointXYZ> PointCloud; 00050 typedef pcl::PointCloud<pcl::PointNormal> PointCloudAndNormals; 00051 typedef std::pair<int, float> index_score; 00052 const int nr_bins = 90; 00053 00054 inline bool 00055 ICPredicate (const index_score& d1, const index_score& d2) 00056 { 00057 return d1.second < d2.second; 00058 } 00059 00060 template<template<class> class Distance> 00061 class VFHRecognizer 00062 { 00063 00064 typedef Distance<float> DistT; 00065 00066 protected: 00067 std::vector<vfh_model_db> models_; 00068 flann::Matrix<float> data_; 00069 int knn_; 00070 flann::Index<DistT> * index_; 00071 std::vector<int> roll_rotation_angles_; 00072 00073 std::vector<Eigen::Vector4f,Eigen::aligned_allocator< Eigen::Vector4f > > centroid_results_; 00074 std::vector<Eigen::Vector4f,Eigen::aligned_allocator< Eigen::Vector4f > > centroid_inputs_; 00075 std::vector<Eigen::Matrix4f,Eigen::aligned_allocator< Eigen::Matrix4f > > icp_transformations_; 00076 00077 /*std::vector < Eigen::Matrix4f > icp_transformations_; 00078 std::vector < Eigen::Vector4f > centroid_inputs_; 00079 std::vector < Eigen::Vector4f > centroid_results_;*/ 00080 00081 bool apply_voxel_grid_; 00082 bool apply_radius_removal_; 00083 bool perform_icp_; 00084 int icp_iterations_; 00085 bool use_old_vfh_; //true - use old vfh false - use new vfh 00086 bool normalize_vfh_bins_; 00087 bool use_cluster_centroids_; 00088 00089 bool 00090 loadFileList (std::vector<vfh_model_db> &models, const std::string &filename); 00091 00093 00097 void 00098 saveFileList (const std::vector<vfh_model_db> &models, const std::string &filename); 00099 00100 void 00101 nearestKSearch (flann::Index<DistT> * index, const vfh_model_db &model, int k, 00102 flann::Matrix<int> &indices, flann::Matrix<float> &distances); 00103 00104 void 00105 filterNormalsWithHighCurvature(pcl::PointCloud<pcl::PointNormal> & cloud, std::vector<int> & indices_out, std::vector<int> & indices_in, float threshold); 00106 00107 void 00108 computeTransformToZAxes(Eigen::Vector4f & centroid, Eigen::Affine3f & transform); 00109 00110 void 00111 computeRollTransform(Eigen::Vector4f & centroidInput, Eigen::Vector4f & centroidResult, double roll_angle, Eigen::Affine3f & final_trans); 00112 00113 virtual bool 00114 getPointCloudFromId (pcl::PointCloud<pcl::PointNormal> & cloud, std::string id)=0; 00115 00116 virtual bool 00117 getVFHRollOrientationFromId (pcl::PointCloud<pcl::VFHSignature308> & vfh_orientation_signature, std::string id)=0; 00118 00119 virtual bool 00120 getVFHRollOrientationFromIdThroughView (pcl::PointCloud<pcl::VFHSignature308> & vfh_orientation_signature, std::string id)=0; 00121 00122 virtual bool 00123 getVFHCentroidFromVFHid (std::vector<float> & centroid, std::string id)=0; 00124 00125 virtual bool 00126 getViewCentroidFromVFHid (std::vector<float> & centroid, std::string id)=0; 00127 00128 virtual bool 00129 getPoseFromId(std::string id, geometry_msgs::Pose & pose)=0; 00130 00131 virtual std::string 00132 getModelId (std::string id)=0; 00133 00134 virtual int 00135 getVFHId (std::string id)=0; 00136 00137 public: 00138 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00139 pcl::PointCloud<pcl::PointNormal> input_filtered; 00140 pcl::PointCloud<pcl::VFHSignature308> vfh_histogram_processed; 00141 int view_id_being_processed_; //temporal thing 00142 std::vector<float> roll_histogram_errors_; 00143 std::vector<float> roll_histogram_errors_flipped_; 00144 std::vector < float > fitness_scores_; 00145 bool fill_size_component_; 00146 00147 int 00148 computeAngleRollOrientationFrequency (cv::Mat & hist_fft, cv::Mat & hist_fft_input, int nr_bins_, 00149 Eigen::Vector4f centroid_view, Eigen::Vector4f centroid_input, 00150 const pcl::PointCloud<pcl::PointNormal> & view, const pcl::PointCloud< 00151 pcl::PointNormal> & input, int jj, pcl::PointCloud<pcl::VFHSignature308> & hist_view, pcl::PointCloud<pcl::VFHSignature308> & hist_input); 00152 00153 virtual bool 00154 getVFHHistogramFromVFHId (pcl::PointCloud<pcl::VFHSignature308> & vfh_descriptor, std::string vfh_id)=0; 00155 00156 void 00157 getRollRotationAngles(std::vector<int> * roll_angles); 00158 00159 void 00160 getCentroids(std::vector<Eigen::Vector4f,Eigen::aligned_allocator< Eigen::Vector4f > > * centroids); 00161 00162 void 00163 getCentroidsResults(std::vector<Eigen::Vector4f,Eigen::aligned_allocator< Eigen::Vector4f > > * centroids); 00164 00165 void 00166 getICPTransformations( std::vector<Eigen::Matrix4f,Eigen::aligned_allocator< Eigen::Matrix4f > > * icp_transformations); 00167 00168 bool 00169 computeVFH (pcl::PointCloud<pcl::PointXYZ>::Ptr input, pcl::PointCloud<pcl::PointNormal>::Ptr cloud_normals, 00170 std::vector<pcl::PointCloud<pcl::VFHSignature308>,Eigen::aligned_allocator< pcl::PointCloud<pcl::VFHSignature308> > > & vfh_signatures, 00171 std::vector<Eigen::Vector3f> & centroids_dominant_orientations); 00172 00173 bool 00174 computeNormals (pcl::PointCloud<pcl::PointXYZ>::Ptr input, 00175 pcl::PointCloud<pcl::PointNormal>::Ptr cloud_normals); 00176 00177 void 00178 computeVFHRollOrientation (pcl::PointCloud<pcl::PointNormal>::Ptr input, 00179 pcl::PointCloud<pcl::VFHSignature308>::Ptr vfh_signature, 00180 Eigen::Vector3f & centroid, cv::Mat & frequency_domain); 00181 00182 bool 00183 detect_ (const sensor_msgs::PointCloud2ConstPtr& msg, int nModels, std::vector<std::string>& model_ids, std::vector< 00184 geometry_msgs::Pose> & poses, std::vector<float>& confidences, std::vector<std::string>& vfh_ids, bool use_fitness_score = true); 00185 00186 void 00187 setApplyVoxelGrid(bool apply) { 00188 apply_voxel_grid_ = apply; 00189 }; 00190 00191 void 00192 setApplyRadiusRemoval(bool apply) { 00193 apply_radius_removal_ = apply; 00194 }; 00195 00196 void 00197 setApplyICP(bool apply) { 00198 perform_icp_ = apply; 00199 }; 00200 00201 void 00202 setICPIterations(int iter) { 00203 icp_iterations_ = iter; 00204 }; 00205 00206 void setUseOldVFH(bool use) { 00207 this->use_old_vfh_ = use; 00208 }; 00209 00210 void setNormalizeVFHBins(bool normalize) { 00211 this->normalize_vfh_bins_ = normalize; 00212 }; 00213 00214 void setUseClusterCentroids(bool use) { 00215 use_cluster_centroids_ = use; 00216 } 00217 ~VFHRecognizer(); 00218 00219 VFHRecognizer(); 00220 }; 00221 }