svm_classification.h
Go to the documentation of this file.
00001 
00002 #ifndef CLOUD_ALGOS_SVM_CLASSIFICATION_H
00003 #define CLOUD_ALGOS_SVM_CLASSIFICATION_H
00004 
00005 // TODO: keep only needed ones
00006 #include <float.h>
00007 #include <iostream>
00008 #include <sstream>
00009 #include <fstream>
00010 #include <string>
00011 #include <string.h>
00012 #include <algorithm>
00013 #include <vector>
00014 #include <set>
00015 #include <stdio.h>
00016 #include <stdlib.h>
00017 #include <sys/types.h>
00018 #include <sys/stat.h>
00019 #include <unistd.h>
00020 #include <fcntl.h>
00021 #include <sys/mman.h>
00022 
00023 #include <libsvm/svm.h>
00024 // #include <pcl/io/pcd_io.h>
00025 #include <pcl_cloud_algos/cloud_algos.h>
00026 #include <pcl_cloud_algos/pcl_cloud_algos_point_types.h>
00027 
00028 namespace pcl_cloud_algos
00029 {
00030 
00031 class SVMClassification : public CloudAlgo
00032 {
00033  public:
00034 
00035   // Input/output type
00036   // typedef sensor_msgs::PointCloud OutputType;
00037   // typedef sensor_msgs::PointCloud InputType;
00038     typedef pcl::PointCloud<GRSDSignature21> InputType;
00039     typedef pcl::PointCloud<GRSDSignature21> OutputType;
00040 
00041   // Options
00042   std::string model_file_name_; // filename where the model should be loaded from
00043   std::string scale_file_name_; // filename where the scale parameters should be loaded from
00044   bool scale_self_;             // should features be scaled with their maximum to 1 and minimum to -1 or not (also see: scale_file_)
00045   bool scale_file_;             // if scale_self_ disabled, sets if scale parameters from scale_file_name_ should be used or not
00046 
00047   // Default names
00048   static std::string default_input_topic ()
00049     {return std::string ("cloud_pcd");}
00050   static std::string default_output_topic ()
00051     {return std::string ("cloud_svm");};
00052   static std::string default_node_name () 
00053     {return std::string ("svm_classification_node");};
00054 
00055   // Algorithm methods
00056   void init (ros::NodeHandle& nh);
00057   void pre ();
00058   void post ();
00059   std::vector<std::string> requires  ();
00060   std::vector<std::string> provides ();
00061   std::string process (const boost::shared_ptr<const InputType>&);
00062   boost::shared_ptr<const OutputType> output ();
00063 
00064   // Constructor-Destructor
00065   SVMClassification () : CloudAlgo ()
00066   {
00067     model_file_name_ = std::string ("svm/fpfh.model");
00068     // scale_file_name_ = std::string ("svm/fpfh.scp");
00069     scale_file_name_ = std::string ("svm/teapot_smooth_fpfh.scp");
00070     scale_self_ = false;
00071     scale_file_ = true; // gets considered only if scale_self is false
00072   }
00073 
00074   static inline double
00075     scaleFeature (int index, double value, double **min_max_values, double lower, double upper)
00076   {
00077     // Skip single-valued attributes
00078     if(min_max_values[0][index] == min_max_values[1][index])
00079       return (0);
00080 
00081     // TODO: do the first two cases help?
00082     if (value <= min_max_values[0][index])
00083       value = lower;
00084     else if (value >= min_max_values[1][index])
00085       value = upper;
00086     else
00087       // Linear interpolation
00088       value = lower + (upper - lower) * (value - min_max_values[0][index]) / (min_max_values[1][index] - min_max_values[0][index]);
00089 
00090     return value;
00091   }
00092 
00093   // TODO make this a general function which gets a list of channels / all channels... point_cloud_mapping::statistics doesn't have it
00094   static inline double**
00095     computeScaleParameters (const boost::shared_ptr<const InputType>& cloud, int startIdx, int nr_values)
00096   {
00097     // Allocate result vector for min and max values
00098     double*  p   = new double[2*nr_values];
00099     for (int i = 0; i < nr_values; i++)
00100     {
00101       p[i] = DBL_MAX;
00102       p[nr_values + i] = -DBL_MAX;
00103     }
00104     double** res = new double*[2];
00105     for (int i = 0; i < 2; i++)
00106       res[i] = & ( p[i*nr_values] );
00107 
00108     for (int i = 0; i < nr_values; i++)
00109       std::cerr << i << ": " << res[0][i] << " " << res[1][i] << std::endl;
00110 
00111     // Go through all the channels and compute min&max
00112     for (size_t cp = 0; cp < cloud->points.size (); cp++)
00113     {
00114       // TODO: parallelize, maybe put this as outer for
00115       for (int i = 0; i < nr_values; i++)
00116       {
00117         if (res[0][i] > cloud->channels[startIdx+i].values[cp])
00118           res[0][i] = cloud->channels[startIdx+i].values[cp];
00119         else if (res[1][i] < cloud->channels[startIdx+i].values[cp])
00120           res[1][i] = cloud->channels[startIdx+i].values[cp];
00121       }
00122     }
00123 
00124     for (int i = 0; i < nr_values; i++)
00125       std::cerr << i << ": " << res[0][i] << " " << res[1][i] << std::endl;
00126 
00127     // Return result
00128     return res;
00129   }
00130 
00131   static inline double**
00132     parseScaleParameterFile (const char *fileName, double &lower, double &upper, int nr_values, bool verbose = true)
00133   {
00134     // Allocate result vector for min and max values
00135     double*  p   = new double[2*nr_values];
00136     for (int i = 0; i < 2*nr_values; i++) p[i] = 0.0;
00137     double** res = new double*[2];
00138     for (int i = 0; i < 2; i++)
00139       res[i] = & ( p[i*nr_values] );
00140     //ANNpointArray res = annAllocPts (2, nr_values, 0);
00141 
00142     // For reading from files
00143     std::ifstream fs;
00144 
00145     // Open file
00146     fs.open (fileName);
00147     if (!fs.is_open ())
00148     {
00149       if (verbose)
00150         ROS_ERROR ("Couldn't open %s for reading!", fileName);
00151       return NULL;
00152     }
00153 
00154     // Get the type
00155     std::string mystring;
00156     fs >> mystring;
00157     if (mystring.substr (0, 1) != "x")
00158     {
00159       if (verbose)
00160         ROS_WARN ("X scaling not found in %s or unknown!", fileName);
00161       return NULL;
00162     }
00163 
00164     // Get the bounds
00165     fs >> lower >> upper;
00166 
00167     // Get the min and max values
00168     while (!fs.eof ())
00169     {
00170       int idx;
00171       float fmin, fmax;
00172       fs >> idx >> fmin >> fmax;
00173       if (idx <= nr_values)
00174       {
00175         res[0][idx-1] = fmin;
00176         res[1][idx-1] = fmax;
00177       }
00178     }
00179 
00180     // Close file
00181     fs.close ();
00182 
00183     // Return result
00184     return res;
00185   }
00186 
00187   ros::Publisher createPublisher (ros::NodeHandle& nh)
00188   {
00189     ros::Publisher p = nh.advertise<OutputType> (default_output_topic (), 5);
00190     return p;
00191   }
00192  private:
00193 
00194   // ROS stuff
00195   ros::NodeHandle nh_;
00196   //ros::Publisher pub_;
00197 
00198   // ROS messages
00199   boost::shared_ptr<sensor_msgs::PointCloud> cloud_svm_;
00200 };
00201 
00202 }
00203 #endif
00204 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends Defines


pcl_cloud_algos
Author(s): Nico Blodow, Dejan Pangercic, Zoltan-Csaba Marton
autogenerated on Sun Oct 6 2013 12:05:19