00001
00063 #include <stdlib.h>
00064 #include <fstream>
00065 #include <boost/program_options.hpp>
00066
00067 #include <pcl/io/pcd_io.h>
00068 #include <pcl/point_types.h>
00069
00070 #include <pcl/filters/passthrough.h>
00071 #include <pcl/kdtree/kdtree.h>
00072 #include <pcl/kdtree/kdtree_flann.h>
00073 #include <pcl/surface/mls.h>
00074 #include <pcl/features/normal_3d_omp.h>
00075
00076 #include <pcl/features/principal_curvatures.h>
00077 #include <pcl/features/fpfh_omp.h>
00078
00079 using namespace pcl;
00080 using namespace std;
00081
00082 string folder_, config_file_;
00083 vector<string> scenes_;
00084 float r_min_, r_max_, r_step_, limit_;
00085
00086 string fl2label(float f, size_t precision)
00087 {
00088 if (f == 0)
00089 return string(precision, '0');
00090
00091 stringstream ss;
00092 ss << f;
00093 string s = ss.str();
00094 s = s.substr(2,s.length());
00095 if (precision > s.length())
00096 s += string(precision - s.length(), '0');
00097 return (s);
00098 }
00099
00100 void readOptions(int argc, char* argv[])
00101 {
00102 using namespace boost::program_options;
00103 options_description options("Options");
00104 options.add_options()
00105 ("help", "produce help message")
00106 ("config,c", value<string>(&config_file_), "cfg file")
00107 ("folder", value<string>(&folder_), "set folder")
00108 ("scenes", value<vector<string> >(&scenes_), "name of used scenes")
00109 ("r_min", value<float>(&r_min_)->default_value(0.02f), "radius to start with")
00110 ("r_max", value<float>(&r_max_)->default_value(0.03f), "radius to end with")
00111 ("r_step", value<float>(&r_step_)->default_value(0.005f), "radius step width")
00112 ("z_limit", value<float>(&limit_)->default_value(3.5f), "z distance limit")
00113 ;
00114
00115 positional_options_description p_opt;
00116 p_opt.add("folder", 1);
00117 variables_map vm;
00118 store(command_line_parser(argc, argv).options(options).positional(p_opt).run(), vm);
00119 notify(vm);
00120
00121 if (vm.count("help") || !vm.count("folder"))
00122 {
00123 cout << options << endl;
00124 exit(0);
00125 }
00126 ifstream ifs(config_file_.c_str());
00127 if (!ifs)
00128 {
00129 ifstream ifs2( (folder_ + "generate_settings.cfg").c_str() );
00130 if (!ifs2)
00131 {
00132 cout << "cannot open config file!" << endl;
00133 }
00134 else
00135 {
00136 store(parse_config_file(ifs2, options), vm);
00137 notify(vm);
00138 }
00139 }
00140 else
00141 {
00142 store(parse_config_file(ifs, options), vm);
00143 notify(vm);
00144 }
00145
00146
00147
00148
00149
00150
00151
00152 }
00153
00154 int main(int argc, char** argv)
00155 {
00156 readOptions(argc, argv);
00157
00158 PointCloud<PointXYZRGB>::Ptr in(new PointCloud<PointXYZRGB>);
00159 PointCloud<Normal>::Ptr n(new PointCloud<Normal>);
00160 PointCloud<Normal>::Ptr n_mls(new PointCloud<Normal>);
00161 PointCloud<PointXYZRGB>::Ptr p_mls(new PointCloud<PointXYZRGB>);
00162 PointCloud<FPFHSignature33>::Ptr fpfh(new PointCloud<FPFHSignature33>);
00163 PointCloud<PrincipalCurvatures>::Ptr pc(new PointCloud<PrincipalCurvatures>);
00164
00165
00166 for (size_t i = 0; i < scenes_.size(); i++)
00167 {
00168 io::loadPCDFile<PointXYZRGB>(folder_ + "raw_labeled/" + scenes_[i] + ".pcd", *in);
00169 PassThrough<PointXYZRGB> pass;
00170 pass.setInputCloud(in);
00171 pass.setFilterFieldName("z");
00172 pass.setFilterLimits(0.0f, limit_);
00173 pass.filter(*in);
00174
00175 #ifdef PCL_VERSION_COMPARE //fuerte
00176 pcl::search::KdTree<PointXYZRGB>::Ptr tree (new pcl::search::KdTree<PointXYZRGB>());
00177 #else //electric
00178 pcl::KdTreeFLANN<PointXYZRGB>::Ptr tree (new pcl::KdTreeFLANN<PointXYZRGB> ());
00179 #endif
00180 tree->setInputCloud(in);
00181
00182 for (float r_n = r_min_; r_n <= r_max_; r_n += r_step_)
00183 {
00184 string str_rn = fl2label(r_n,3) + "rn";
00185
00186 NormalEstimationOMP<PointXYZRGB, Normal> norm;
00187 norm.setNumberOfThreads(1);
00188 norm.setInputCloud(in);
00189 norm.setSearchMethod(tree);
00190 norm.setRadiusSearch(r_n);
00191 norm.compute(*n);
00192
00193 #ifdef PCL_MINOR_VERSION
00194 #if PCL_MINOR_VERSION >=6
00195 std::cerr << "current implementation of mls doesn't work with pcl1.7" << std::endl;
00196 exit(-1);
00197 #else
00198 MovingLeastSquares<PointXYZRGB, Normal> mls;
00199 mls.setInputCloud(in);
00200 mls.setOutputNormals(n_mls);
00201 mls.setPolynomialFit(true);
00202 mls.setPolynomialOrder(2);
00203 mls.setSearchMethod(tree);
00204 mls.setSearchRadius(r_n);
00205 mls.reconstruct(*p_mls);
00206 #endif
00207 #endif
00208
00209 for (size_t p = 0; p < n_mls->points.size(); ++p)
00210 {
00211 flipNormalTowardsViewpoint(p_mls->points[p], 0.0f, 0.0f, 0.0f,
00212 n_mls->points[p].normal[0],
00213 n_mls->points[p].normal[1],
00214 n_mls->points[p].normal[2]);
00215 }
00216
00217 io::savePCDFileASCII<PointXYZRGB>(folder_+"normals/"+scenes_[i]+
00218 "/mls_"+scenes_[i]+"_"+str_rn+".pcd",*p_mls);
00219
00220 #ifdef PCL_VERSION_COMPARE //fuerte
00221 pcl::search::KdTree<PointXYZRGB>::Ptr tree_mls (new pcl::search::KdTree<PointXYZRGB>());
00222 #else //electric
00223 pcl::KdTreeFLANN<PointXYZRGB>::Ptr tree_mls (new pcl::KdTreeFLANN<PointXYZRGB> ());
00224 #endif
00225 tree_mls->setInputCloud(p_mls);
00226
00227 for (float r_f = r_n; r_f <= r_max_; r_f += r_step_)
00228 {
00229 cout << "scene: " << scenes_[i] << "\tnormals: " << r_n << "\tfeatures: " << r_f << endl;
00230 string str_rf = fl2label(r_f,3) + "rf";
00231
00232 FPFHEstimationOMP<PointXYZRGB, Normal, FPFHSignature33> fpfh_est;
00233 fpfh_est.setNumberOfThreads(1);
00234 fpfh_est.setInputCloud(in);
00235 fpfh_est.setInputNormals(n);
00236 fpfh_est.setSearchMethod(tree);
00237 fpfh_est.setRadiusSearch(r_f);
00238 fpfh_est.compute(*fpfh);
00239
00240
00241
00242 io::savePCDFileASCII<FPFHSignature33>(folder_ + "0_fpfh/" + scenes_[i] +
00243 "/fpfh_" + scenes_[i] +"_"+str_rn+"_"+str_rf+".pcd",
00244 *fpfh);
00245
00246 FPFHEstimationOMP<PointXYZRGB, Normal, FPFHSignature33> fpfh_est_mls;
00247 fpfh_est_mls.setNumberOfThreads(1);
00248 fpfh_est_mls.setInputCloud(p_mls);
00249 fpfh_est_mls.setInputNormals(n_mls);
00250 fpfh_est_mls.setSearchMethod(tree_mls);
00251 fpfh_est_mls.setRadiusSearch(r_f);
00252 fpfh_est_mls.compute(*fpfh);
00253 io::savePCDFileASCII<FPFHSignature33>(folder_ + "0_fpfh/" + scenes_[i] +
00254 "/fpfh_" + scenes_[i] +"_"+str_rn+"mls_"+str_rf+".pcd",
00255 *fpfh);
00256
00257 PrincipalCurvaturesEstimation<PointXYZRGB, Normal, PrincipalCurvatures> pc_est;
00258 pc_est.setInputCloud(in);
00259 pc_est.setInputNormals(n);
00260 pc_est.setSearchMethod(tree);
00261 pc_est.setRadiusSearch(r_f);
00262 pc_est.compute(*pc);
00263 io::savePCDFileASCII<PrincipalCurvatures>(folder_ + "0_pc/" + scenes_[i] +
00264 "/pc_" + scenes_[i] +"_"+str_rn+"_"+str_rf+".pcd",
00265 *pc);
00266
00267 PrincipalCurvaturesEstimation<PointXYZRGB, Normal, PrincipalCurvatures> pc_est_mls;
00268 pc_est_mls.setInputCloud(p_mls);
00269 pc_est_mls.setInputNormals(n_mls);
00270 pc_est_mls.setSearchMethod(tree_mls);
00271 pc_est_mls.setRadiusSearch(r_f);
00272 pc_est_mls.compute(*pc);
00273 io::savePCDFileASCII<PrincipalCurvatures>(folder_ + "0_pc/" + scenes_[i] +
00274 "/pc_" + scenes_[i] +"_"+str_rn+"mls_"+str_rf+".pcd",
00275 *pc);
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 }
00299 }
00300 }
00301
00302 return 0;
00303 }