Go to the documentation of this file.00001
00002 #ifndef CLOUD_ALGOS_SVM_CLASSIFICATION_H
00003 #define CLOUD_ALGOS_SVM_CLASSIFICATION_H
00004
00005
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
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
00036
00037
00038 typedef pcl::PointCloud<GRSDSignature21> InputType;
00039 typedef pcl::PointCloud<GRSDSignature21> OutputType;
00040
00041
00042 std::string model_file_name_;
00043 std::string scale_file_name_;
00044 bool scale_self_;
00045 bool scale_file_;
00046
00047
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
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
00065 SVMClassification () : CloudAlgo ()
00066 {
00067 model_file_name_ = std::string ("svm/fpfh.model");
00068
00069 scale_file_name_ = std::string ("svm/teapot_smooth_fpfh.scp");
00070 scale_self_ = false;
00071 scale_file_ = true;
00072 }
00073
00074 static inline double
00075 scaleFeature (int index, double value, double **min_max_values, double lower, double upper)
00076 {
00077
00078 if(min_max_values[0][index] == min_max_values[1][index])
00079 return (0);
00080
00081
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
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
00094 static inline double**
00095 computeScaleParameters (const boost::shared_ptr<const InputType>& cloud, int startIdx, int nr_values)
00096 {
00097
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
00112 for (size_t cp = 0; cp < cloud->points.size (); cp++)
00113 {
00114
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
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
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
00141
00142
00143 std::ifstream fs;
00144
00145
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
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
00165 fs >> lower >> upper;
00166
00167
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
00181 fs.close ();
00182
00183
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
00195 ros::NodeHandle nh_;
00196
00197
00198
00199 boost::shared_ptr<sensor_msgs::PointCloud> cloud_svm_;
00200 };
00201
00202 }
00203 #endif
00204