Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef VFHCLASSIFICATION_H_
00039 #define VFHCLASSIFICATION_H_
00040
00041 #include <fstream>
00042 #include <pcl/point_types.h>
00043 #include <pcl/io/pcd_io.h>
00044 #include <pcl/features/vfh.h>
00045 #include <pcl/features/normal_3d.h>
00046 #include <pcl/apps/nn_classification.h>
00047 #include <sensor_msgs/PointCloud2.h>
00048
00049 namespace pcl
00050 {
00056 template <typename PointT> pcl::PointCloud<pcl::VFHSignature308>::Ptr
00057 computeVFH (typename PointCloud<PointT>::ConstPtr cloud, double radius)
00058 {
00059 using namespace pcl;
00060
00061
00062
00063 typename pcl::search::KdTree<PointT>::Ptr tree (new pcl::search::KdTree<PointT> ());
00064
00065
00066 NormalEstimation<PointT, Normal> ne;
00067 ne.setInputCloud (cloud);
00068 ne.setSearchMethod (tree);
00069
00070
00071 PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
00072 ne.setRadiusSearch (radius);
00073 ne.compute (*normals);
00074
00075
00076 VFHEstimation<PointT, Normal, VFHSignature308> vfh;
00077 vfh.setInputCloud (cloud);
00078 vfh.setInputNormals (normals);
00079 vfh.setSearchMethod (tree);
00080
00081
00082 PointCloud<VFHSignature308>::Ptr vfhs (new PointCloud<VFHSignature308>);
00083
00084
00085 vfh.compute (*vfhs);
00086 return vfhs;
00087 }
00088
00093 class VFHClassifierNN
00094 {
00095 public:
00096
00097 typedef pcl::PointCloud<pcl::VFHSignature308> FeatureCloud;
00098 typedef pcl::PointCloud<pcl::VFHSignature308>::Ptr FeatureCloudPtr;
00099 typedef pcl::PointCloud<pcl::VFHSignature308>::ConstPtr FeatureCloudConstPtr;
00100 typedef NNClassification<pcl::VFHSignature308>::Result Result;
00101 typedef NNClassification<pcl::VFHSignature308>::ResultPtr ResultPtr;
00102
00103 private:
00104
00106 FeatureCloudPtr training_features_;
00108 std::vector<std::string> labels_;
00110 NNClassification<pcl::VFHSignature308> classifier_;
00111
00112 public:
00113
00114 VFHClassifierNN () : training_features_ (), labels_ (), classifier_ ()
00115 {
00116 reset ();
00117 }
00118
00119 void reset ()
00120 {
00121 training_features_.reset (new FeatureCloud);
00122 labels_.clear ();
00123 classifier_ = NNClassification<pcl::VFHSignature308> ();
00124 }
00125
00127 void finalizeTraining ()
00128 {
00129 finalizeTree ();
00130 finalizeLabels ();
00131 }
00132
00134 void finalizeTree ()
00135 {
00136 classifier_.setTrainingFeatures(training_features_);
00137 }
00138
00140 void finalizeLabels ()
00141 {
00142 classifier_.setTrainingLabels(labels_);
00143 }
00144
00150 bool saveTrainingFeatures(std::string file_name, std::string labels_file_name)
00151 {
00152 if (labels_.size () == training_features_->points.size ())
00153 {
00154 if (pcl::io::savePCDFile (file_name.c_str (), *training_features_) != 0)
00155 return false;
00156 std::ofstream f (labels_file_name.c_str ());
00157 BOOST_FOREACH (std::string s, labels_)
00158 f << s << "\n";
00159 return true;
00160 }
00161 return false;
00162 }
00163
00170 bool addTrainingFeatures (const FeatureCloudPtr training_features, const std::vector<std::string> &labels)
00171 {
00172 if (labels.size () == training_features->points.size ())
00173 {
00174 labels_.insert (labels_.end (), labels.begin (), labels.end ());
00175 training_features_->points.insert (training_features_->points.end (), training_features->points.begin (), training_features->points.end ());
00176 training_features_->header = training_features->header;
00177 training_features_->height = 1;
00178 training_features_->width = static_cast<uint32_t> (training_features_->points.size ());
00179 training_features_->is_dense &= training_features->is_dense;
00180 training_features_->sensor_origin_ = training_features->sensor_origin_;
00181 training_features_->sensor_orientation_ = training_features->sensor_orientation_;
00182 return true;
00183 }
00184 return false;
00185 }
00186
00193 bool loadTrainingFeatures(std::string file_name, std::string labels_file_name)
00194 {
00195 FeatureCloudPtr cloud (new FeatureCloud);
00196 if (pcl::io::loadPCDFile (file_name.c_str (), *cloud) != 0)
00197 return false;
00198 std::vector<std::string> labels;
00199 std::ifstream f (labels_file_name.c_str ());
00200 std::string label;
00201 while (getline (f, label))
00202 if (label.size () > 0)
00203 labels.push_back(label);
00204 return addTrainingFeatures (cloud, labels);
00205 }
00206
00214 bool loadTrainingData (std::string file_name, std::string label)
00215 {
00216 sensor_msgs::PointCloud2 cloud_blob;
00217 if (pcl::io::loadPCDFile (file_name.c_str (), cloud_blob) != 0)
00218 return false;
00219 return addTrainingData (cloud_blob, label);
00220 }
00221
00228 bool addTrainingData (const sensor_msgs::PointCloud2 &training_data, std::string &label)
00229 {
00230
00231 std::vector<std::string> labels;
00232 labels.push_back (label);
00233
00234
00235 FeatureCloudPtr vfhs = computeFeature (training_data);
00236 return addTrainingFeatures(vfhs, labels);
00237 }
00238
00245 ResultPtr classify (const sensor_msgs::PointCloud2 &testing_data, double radius = 300, double min_score = 0.002)
00246 {
00247
00248 FeatureCloudPtr vfhs = computeFeature (testing_data);
00249
00250 float gaussian_param = - static_cast<float> (radius / log (min_score));
00251
00252 return classifier_.classify(vfhs->points.at (0), radius, gaussian_param);
00253 }
00254
00260 FeatureCloudPtr computeFeature (const sensor_msgs::PointCloud2 &points, double radius = 0.03)
00261 {
00262 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ> ());
00263 pcl::fromROSMsg (points, *cloud);
00264 return pcl::computeVFH<pcl::PointXYZ> (cloud, radius);
00265 }
00266 };
00267 }
00268
00269 #endif