00001
00068 #include <cob_3d_mapping_common/label_defines.h>
00069
00070 #include <boost/program_options.hpp>
00071
00072 #include <pcl/io/pcd_io.h>
00073 #include <pcl/point_cloud.h>
00074 #include <pcl/point_types.h>
00075
00076 using namespace std;
00077 using namespace pcl;
00078
00079 vector<string> in_label;
00080 vector<string> in_feature;
00081 string out;
00082
00083 bool plane, edge, cor, cyl, sph;
00084
00085
00086 void readOptions(int argc, char* argv[])
00087 {
00088 using namespace boost::program_options;
00089 options_description options("Options");
00090 options.add_options()
00091 ("help", "produce help message")
00092 ("in_label,l", value<vector<string> >(&in_label),
00093 "pcd file containting rgb labeled points")
00094 ("in_feature,f", value<vector<string> >(&in_feature),
00095 "pcd file containting feature values")
00096 ("out,o", value<string>(&out)->default_value(""),
00097 "output folder")
00098 ("plane,p", value<bool>(&plane)->default_value(true),
00099 "extract points labeled as plane")
00100 ("edge,e", value<bool>(&edge)->default_value(true),
00101 "extract points labeled as edge")
00102 ("corner,o", value<bool>(&cor)->default_value(true),
00103 "extract points labeled as corner")
00104 ("cyl,c", value<bool>(&cyl)->default_value(true),
00105 "extract points labeled as cylinder")
00106 ("sph,s", value<bool>(&sph)->default_value(true),
00107 "extract points labeled as sphere")
00108 ;
00109
00110 positional_options_description p_opt;
00111 p_opt.add("out", 1);
00112 variables_map vm;
00113 store(command_line_parser(argc, argv).options(options).positional(p_opt).run(), vm);
00114 notify(vm);
00115
00116 if (vm.count("help"))
00117 {
00118 cout << "extract feature values (RSD, PC or FPFH) of a classified point cloud "
00119 << "and store them separated for each class" << endl;
00120 cout << options << endl;
00121 exit(0);
00122 }
00123 if (in_label.size() != in_feature.size() || in_label.size() == 0)
00124 cout << "please define an equal number of label and feature files" << endl;
00125 }
00126
00127 template<typename PointT>
00128 void extractIndices(const PointCloud<PointT>& points,
00129 const string& folder,
00130 const string& prefix,
00131 const vector< vector<int> >& indices)
00132 {
00133 PointCloud<PointT> p_ex;
00134
00135 if (indices[0].size() != 0)
00136 {
00137 copyPointCloud<PointT>(points, indices[0], p_ex);
00138 io::savePCDFileASCII<PointT>(folder + prefix + "_plane.pcd", p_ex);
00139 }
00140 if (indices[1].size() != 0)
00141 {
00142 copyPointCloud<PointT>(points, indices[1], p_ex);
00143 io::savePCDFileASCII<PointT>(folder + prefix + "_edge.pcd", p_ex);
00144 }
00145 if (indices[2].size() != 0)
00146 {
00147 copyPointCloud<PointT>(points, indices[2], p_ex);
00148 io::savePCDFileASCII<PointT>(folder + prefix + "_cor.pcd", p_ex);
00149 }
00150 if (indices[3].size() != 0)
00151 {
00152 copyPointCloud<PointT>(points, indices[3], p_ex);
00153 io::savePCDFileASCII<PointT>(folder + prefix + "_cyl.pcd", p_ex);
00154 }
00155 if (indices[4].size() != 0)
00156 {
00157 copyPointCloud<PointT>(points, indices[4], p_ex);
00158 io::savePCDFileASCII<PointT>(folder + prefix + "_sph.pcd", p_ex);
00159 }
00160 }
00161
00162
00163 int main(int argc, char** argv)
00164 {
00165 readOptions(argc, argv);
00166 PointCloud<PointXYZRGB>::Ptr p_label (new PointCloud<PointXYZRGB>);
00167 PointCloud<PointXYZRGB>::Ptr p (new PointCloud<PointXYZRGB>);
00168
00169 PointCloud<PrincipalRadiiRSD>::Ptr f1 (new PointCloud<PrincipalRadiiRSD>);
00170 PointCloud<PrincipalCurvatures>::Ptr f2 (new PointCloud<PrincipalCurvatures>);
00171 PointCloud<FPFHSignature33>::Ptr f3 (new PointCloud<FPFHSignature33>);
00172
00173 PointCloud<PrincipalRadiiRSD>::Ptr f1b (new PointCloud<PrincipalRadiiRSD>);
00174 PointCloud<PrincipalCurvatures>::Ptr f2b (new PointCloud<PrincipalCurvatures>);
00175 PointCloud<FPFHSignature33>::Ptr f3b (new PointCloud<FPFHSignature33>);
00176 pcl::PCLPointCloud2::Ptr cloud (new pcl::PCLPointCloud2);
00177
00178 vector<int> idx_plane;
00179 vector<int> idx_edge;
00180 vector<int> idx_cor;
00181 vector<int> idx_cyl;
00182 vector<int> idx_sph;
00183
00184 vector< vector<int> > indices(5, vector<int>());
00185 int mode = 0;
00186
00187 io::loadPCDFile(in_feature[0], *cloud);
00188 if (getFieldIndex(*cloud, "r_max") != -1)
00189 {
00190 cout << "Point cloud with RSD features selected." << endl;
00191 mode = 1;
00192 }
00193 else if (getFieldIndex(*cloud, "pc1") != -1)
00194 {
00195 cout << "Point cloud with principal curvatures selected." << endl;
00196 mode = 2;
00197 }
00198 else if (getFieldIndex(*cloud, "fpfh") != -1)
00199 {
00200 cout << "Point cloud with FPFH selected." << endl;
00201 mode = 3;
00202 }
00203
00204 for (size_t i=0;i<in_label.size();i++)
00205 {
00206 io::loadPCDFile(in_label[i], *p);
00207 *p_label += *p;
00208 switch (mode)
00209 {
00210 case 1:
00211 io::loadPCDFile(in_feature[i], *f1b);
00212 *f1 += *f1b;
00213 break;
00214 case 2:
00215 io::loadPCDFile(in_feature[i], *f2b);
00216 *f2 += *f2b;
00217 break;
00218 case 3:
00219 io::loadPCDFile(in_feature[i], *f3b);
00220 *f3 += *f3b;
00221 break;
00222 default:
00223 exit(0);
00224 }
00225 }
00226
00227 cout<<"selected "<<p_label->size()<<" points from "<<in_label.size()<<" pcd files."<<endl;
00228 cout<<"selected "<<p_label->points.size()<<" points from "<<in_label.size()<<" pcd files."<<endl;
00229 cout<<"selected "<<f3->size()<<" feature points"<<endl;
00230
00231 uint32_t rgb;
00232 for (size_t i = 0; i < p_label->size(); ++i)
00233 {
00234
00235 rgb = *reinterpret_cast<int*>(&(p_label->points[i].rgb));
00236
00237 switch(rgb)
00238 {
00239 case LBL_PLANE:
00240 indices[0].push_back(i);
00241 break;
00242
00243 case LBL_EDGE:
00244 indices[1].push_back(i);
00245 break;
00246
00247 case LBL_COR:
00248 indices[2].push_back(i);
00249 break;
00250
00251 case LBL_CYL:
00252 indices[3].push_back(i);
00253 break;
00254
00255 case LBL_SPH:
00256 indices[4].push_back(i);
00257 break;
00258
00259 default:
00260 break;
00261 }
00262 }
00263
00264 if(!plane)
00265 indices[0].clear();
00266 if(!edge)
00267 indices[1].clear();
00268 if(!cor)
00269 indices[2].clear();
00270 if(!cyl)
00271 indices[3].clear();
00272 if(!sph)
00273 indices[4].clear();
00274
00275 switch(mode)
00276 {
00277 case 1:
00278 extractIndices<PrincipalRadiiRSD>(*f1, out, "rsd", indices);
00279 break;
00280 case 2:
00281 extractIndices<PrincipalCurvatures>(*f2, out, "pc", indices);
00282 break;
00283 case 3:
00284 extractIndices<FPFHSignature33>(*f3, out, "fpfh", indices);
00285 break;
00286 default:
00287 break;
00288 }
00289
00290 return 1;
00291 }