00001
00063
00064 #include <opencv2/core/core.hpp>
00065 #include <cv.h>
00066 #include <highgui.h>
00067
00068
00069 #include <boost/program_options.hpp>
00070 #include <boost/timer.hpp>
00071 #include <boost/make_shared.hpp>
00072
00073
00074 #include <pcl/point_types.h>
00075 #include <pcl/io/pcd_io.h>
00076 #include <pcl/PointIndices.h>
00077 #include <pcl/features/normal_3d.h>
00078 #include <pcl/visualization/pcl_visualizer.h>
00079 #include <pcl/visualization/point_cloud_handlers.h>
00080
00081
00082 #include "cob_3d_mapping_common/point_types.h"
00083 #include "cob_3d_features/organized_normal_estimation.h"
00084 #include "cob_3d_features/organized_curvature_estimation_omp.h"
00085 #include "cob_3d_features/curvature_classifier.h"
00086 #include "cob_3d_features/impl/curvature_classifier.hpp"
00087
00088
00089 using namespace std;
00090 using namespace pcl;
00091
00092 typedef visualization::PointCloudColorHandlerRGBField<PointXYZRGB> ColorHdlRGB;
00093
00094 string file_in_, file_out_, file_cluster_;
00095 float rn_;
00096 int rfp_;
00097 float ex_th_;
00098 bool en_one_;
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 ("in,i", value<string>(&file_in_), "input pcd file")
00107 ("cl,c", value<string>(&file_cluster_), "input indices file")
00108 ("out,o", value<string>(&file_out_), "output pcd file")
00109 ("normal,n", value<float>(&rn_)->default_value(0.025),
00110 "set normal estimation radius")
00111 ("feature,f", value<int>(&rfp_)->default_value(20),
00112 "set 3d edge estimation radius")
00113 ("extraction_th,x", value<float>(&ex_th_)->default_value(0.1),
00114 "set the strength threshold for edge extraction")
00115 ("one", "use organized normal estimation (one) instead of original normal estimation (ne)")
00116 ;
00117
00118 positional_options_description p_opt;
00119 p_opt.add("in", 1);
00120 variables_map vm;
00121 store(command_line_parser(argc, argv).options(options).positional(p_opt).run(), vm);
00122 notify(vm);
00123
00124 if (vm.count("help"))
00125 {
00126 cout << options << endl;
00127 exit(0);
00128 }
00129 en_one_ = vm.count("one");
00130 }
00131
00132 int main(int argc, char** argv)
00133 {
00134 readOptions(argc, argv);
00135 boost::timer t;
00136
00137
00138 PointCloud<PointXYZRGB>::Ptr p(new PointCloud<PointXYZRGB>);
00139 PointCloud<Normal>::Ptr n(new PointCloud<Normal>);
00140 PointCloud<PrincipalCurvatures>::Ptr pc(new PointCloud<PrincipalCurvatures>);
00141 PointCloud<PointLabel>::Ptr l(new PointCloud<PointLabel>);
00142
00143 PCDReader r;
00144 if (r.read(file_in_, *p) == -1) return(0);
00145
00146 vector<PointIndices> indices;
00147 ifstream fs;
00148
00149 string line;
00150 fs.open(file_cluster_.c_str());
00151 if (fs.is_open())
00152 {
00153 while(fs.good())
00154 {
00155 getline (fs,line);
00156 istringstream iss(line);
00157 PointIndices pi;
00158 do
00159 {
00160 int temp;
00161 iss >> temp;
00162 pi.indices.push_back(temp);
00163 } while(iss);
00164 if(pi.indices.size()>0)
00165 indices.push_back(pi);
00166 }
00167 }
00168 std::cout << "indices file read successfully" << std::endl;
00169
00170
00171 if (en_one_)
00172 {
00173 t.restart();
00174 cob_3d_features::OrganizedNormalEstimation<PointXYZRGB, Normal, PointLabel>one;
00175 one.setInputCloud(p);
00176 one.setOutputLabels(l);
00177
00178 one.setPixelSearchRadius(8,2,2);
00179 one.setSkipDistantPointThreshold(12);
00180 one.compute(*n);
00181 cout << t.elapsed() << "s\t for Organized Normal Estimation" << endl;
00182 }
00183 else
00184 {
00185 t.restart();
00186 #ifdef PCL_VERSION_COMPARE //fuerte
00187 pcl::search::KdTree<PointXYZRGB>::Ptr tree (new pcl::search::KdTree<PointXYZRGB>());
00188 #else //electric
00189 pcl::KdTreeFLANN<PointXYZRGB>::Ptr tree (new pcl::KdTreeFLANN<PointXYZRGB> ());
00190 #endif
00191 NormalEstimation<PointXYZRGB, Normal> ne;
00192 ne.setRadiusSearch(rn_);
00193 ne.setSearchMethod(tree);
00194 ne.setInputCloud(p);
00195 ne.compute(*n);
00196 cout << t.elapsed() << "s\t for normal estimation" << endl;
00197 }
00198 cob_3d_features::OrganizedCurvatureEstimationOMP<PointXYZRGB, Normal, PointLabel, PrincipalCurvatures> oce;
00199 oce.setInputCloud(p);
00200 oce.setInputNormals(n);
00201 oce.setPixelSearchRadius(8,2,2);
00202 oce.setSkipDistantPointThreshold(12);
00203
00204
00205
00206
00207 if (indices.size() == 0)
00208 {
00209 oce.setOutputLabels(l);
00210 oce.compute(*pc);
00211 cob_3d_features::CurvatureClassifier<PrincipalCurvatures, PointLabel>cc;
00212 cc.setInputCloud(pc);
00213 cc.classify(*l);
00214 }
00215 else
00216 {
00217 for(unsigned int i=0; i<indices.size(); i++)
00218 {
00219 std::cout << "cluster " << i << " has " << indices[i].indices.size() << " points" << std::endl;
00220 if(i==3)
00221 {
00222
00223
00224
00225
00226 t.restart();
00227 boost::shared_ptr<PointIndices> ind_ptr = boost::make_shared<PointIndices>(indices[i]);
00228 std::cout << ind_ptr->indices.size() << std::endl;
00229 oce.setIndices(ind_ptr);
00230 oce.setOutputLabels(l);
00231 oce.compute(*pc);
00232 cout << t.elapsed() << "s\t for principal curvature estimation" << endl;
00233
00234 cob_3d_features::CurvatureClassifier<PrincipalCurvatures, PointLabel>cc;
00235 cc.setInputCloud(pc);
00236 cc.setIndices(ind_ptr);
00237 cc.classify(*l);
00238 }
00239 }
00240 }
00241
00242 for (size_t i = 0; i < l->points.size(); i++)
00243 {
00244
00245 if (l->points[i].label == I_UNDEF)
00246 {
00247 p->points[i].r = 0;
00248 p->points[i].g = 0;
00249 p->points[i].b = 0;
00250 }
00251 else if (l->points[i].label == I_NAN)
00252 {
00253 p->points[i].r = 0;
00254 p->points[i].g = 255;
00255 p->points[i].b = 0;
00256 }
00257 else if (l->points[i].label == I_EDGE)
00258 {
00259 p->points[i].r = 0;
00260 p->points[i].g = 0;
00261 p->points[i].b = 255;
00262 }
00263 else if (l->points[i].label == I_BORDER)
00264 {
00265 p->points[i].r = 255;
00266 p->points[i].g = 0;
00267 p->points[i].b = 0;
00268 }
00269 else if (l->points[i].label == I_PLANE)
00270 {
00271 p->points[i].r = 255;
00272 p->points[i].g = 255;
00273 p->points[i].b = 0;
00274 }
00275 else if (l->points[i].label == I_CYL)
00276 {
00277 p->points[i].r = 255;
00278 p->points[i].g = 0;
00279 p->points[i].b = 255;
00280 }
00281 else
00282 {
00283 p->points[i].r = 255;
00284 p->points[i].g = 255;
00285 p->points[i].b = 255;
00286 }
00287 }
00288
00289 visualization::PCLVisualizer v;
00290 v.setBackgroundColor(0,127,127);
00291 ColorHdlRGB col_hdl(p);
00292 v.addPointCloud<PointXYZRGB>(p,col_hdl, "segmented");
00293
00294 while(!v.wasStopped())
00295 {
00296 v.spinOnce(100);
00297 usleep(100000);
00298 }
00299
00300
00301 return(0);
00302 }