00001
00063
00064 #include <boost/program_options.hpp>
00065 #include <boost/lexical_cast.hpp>
00066
00067
00068 #include <pcl/point_types.h>
00069 #include <pcl/io/pcd_io.h>
00070 #include <pcl/visualization/pcl_visualizer.h>
00071 #include <pcl/visualization/point_cloud_handlers.h>
00072
00073
00074 #include "cob_3d_mapping_common/stop_watch.h"
00075 #include "cob_3d_mapping_common/point_types.h"
00076 #include "cob_3d_mapping_common/label_defines.h"
00077 #include "cob_3d_features/organized_normal_estimation.h"
00078 #include "cob_3d_segmentation/depth_segmentation.h"
00079 #include "cob_3d_segmentation/cluster_classifier.h"
00080
00081 #include "cob_3d_segmentation/polygon_extraction/polygon_extraction.h"
00082
00083 using namespace std;
00084 using namespace pcl;
00085
00086 typedef cob_3d_segmentation::PredefinedSegmentationTypes SegTypes;
00087
00088 string file_in_;
00089 string label_out_, type_out_;
00090 float d_th_, upper_;
00091
00092 void readOptions(int argc, char* argv[])
00093 {
00094 using namespace boost::program_options;
00095 options_description options("Options");
00096 options.add_options()
00097 ("help", "produce help message")
00098 ("in,i", value<string>(&file_in_), "input pcd file")
00099 ("skip_distant_point,d", value<float>(&d_th_)->default_value(8), "threshold to ignore distant points in neighborhood")
00100 ("upper,u", value<float>(&upper_)->default_value(6.0), "upper curvature threshold (edge)")
00101 ("label_out,l", value<string>(&label_out_), "save labeled file to")
00102 ("type_out,t", value<string>(&type_out_), "save classified file to")
00103 ;
00104
00105 positional_options_description p_opt;
00106 p_opt.add("in", 1);
00107 variables_map vm;
00108 store(command_line_parser(argc, argv).options(options).positional(p_opt).run(), vm);
00109 notify(vm);
00110
00111 if (vm.count("help") || argc == 1)
00112 {
00113 cout << "\"pns\" stands for \"pixel neighborhood size\" and refers to N x N mask for nearest neighbor search\n"
00114 << "\t where N = 2 * pns + 1\n" << endl;
00115 cout << options << endl;
00116 exit(0);
00117 }
00118 }
00119
00120 int main(int argc, char** argv)
00121 {
00122 readOptions(argc, argv);
00123
00124 PointCloud<PointXYZRGB>::Ptr p(new PointCloud<PointXYZRGB>);
00125 PointCloud<PointXYZRGB>::Ptr p2(new PointCloud<PointXYZRGB>);
00126 PointCloud<PointXYZRGB>::Ptr pt(new PointCloud<PointXYZRGB>);
00127 PointCloud<PointXYZRGB>::Ptr pbp(new PointCloud<PointXYZRGB>);
00128 PointCloud<Normal>::Ptr n(new PointCloud<Normal>);
00129 PointCloud<Normal>::Ptr n_org(new PointCloud<Normal>);
00130 PointCloud<Normal>::Ptr n_bp(new PointCloud<Normal>);
00131 PointCloud<PointLabel>::Ptr l(new PointCloud<PointLabel>);
00132
00133 PCDReader r;
00134 if (r.read(file_in_, *p) == -1) return(0);
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 *pt = *p2 = *p;
00149 PrecisionStopWatch t;
00150 t.precisionStart();
00151 cob_3d_features::OrganizedNormalEstimation<PointXYZRGB, Normal, PointLabel>one;
00152 one.setInputCloud(p);
00153 one.setOutputLabels(l);
00154 one.setPixelSearchRadius(8,2,2);
00155 one.setSkipDistantPointThreshold(d_th_);
00156 one.compute(*n);
00157 cout << t.precisionStop() << "s\t for Organized Normal Estimation" << endl;
00158 *n_org = *n;
00159
00160 t.precisionStart();
00161 SegTypes::Graph::Ptr g(new SegTypes::Graph);
00162 cob_3d_segmentation::DepthSegmentation<SegTypes::Graph, SegTypes::Point, SegTypes::Normal, SegTypes::Label> seg;
00163 seg.setInputCloud(p);
00164 seg.setNormalCloudIn(n);
00165 seg.setLabelCloudInOut(l);
00166 seg.setClusterGraphOut(g);
00167 std::cout << "initial segmentation..." << std::endl;
00168 seg.performInitialSegmentation();
00169 std::cout << "num initial clusters: " << g->clusters()->numClusters() << std::endl;
00170 g->clusters()->mapClusterColor(p2);
00171 std::cout << "refine segmentation.." << std::endl;
00172 seg.refineSegmentation();
00173 g->clusters()->mapClusterColor(p);
00174 g->edges()->mapBoundaryPoints(pbp,n_bp);
00175
00176
00177
00178
00179
00180
00181 g->clusters()->mapTypeColor(pt);
00182
00183
00184 g->clusters()->mapClusterBorders(pt);
00185 cout << t.precisionStop() << "s\t for depth segmentation" << endl;
00186
00187 if (label_out_ != "")
00188 {
00189 io::savePCDFileASCII<PointXYZRGB>(label_out_, *p);
00190 return 0;
00191 }
00192 if (type_out_ != "")
00193 {
00194 io::savePCDFileASCII<PointXYZRGB>(type_out_, *pt);
00195 return 0;
00196 }
00197
00198 PointCloud<PointXYZ>::Ptr centroids(new PointCloud<PointXYZ>);
00199 PointCloud<PointXYZ>::Ptr ints_centroids(new PointCloud<PointXYZ>);
00200 PointCloud<Normal>::Ptr ints_comp1(new PointCloud<Normal>);
00201 PointCloud<Normal>::Ptr ints_comp2(new PointCloud<Normal>);
00202 PointCloud<Normal>::Ptr ints_comp3(new PointCloud<Normal>);
00203 PointCloud<Normal>::Ptr connection(new PointCloud<Normal>);
00204 PointCloud<Normal>::Ptr plane_normals(new PointCloud<Normal>);
00205 PointCloud<PointXYZ>::Ptr plane_centroids(new PointCloud<PointXYZ>);
00206
00207 g->clusters()->mapClusterNormalIntersectionResults(ints_centroids, ints_comp1, ints_comp2, ints_comp3, centroids, connection);
00208
00209 cob_3d_segmentation::PolygonExtraction pe_;
00210 PointCloud<PointXYZRGB>::Ptr borders(new PointCloud<PointXYZRGB>);
00211 Normal ni;
00212 PointXYZ pi;
00213 for (SegTypes::CH::ClusterPtr c = g->clusters()->begin(); c != g->clusters()->end(); ++c)
00214 {
00215 if (c->type != I_PLANE) continue;
00216 ni.getNormalVector3fMap() = c->pca_point_comp3;
00217 plane_normals->points.push_back(ni);
00218 pi.getVector3fMap() = c->getCentroid();
00219 plane_centroids->points.push_back(pi);
00220 cob_3d_segmentation::PolygonContours<cob_3d_segmentation::PolygonPoint> poly;
00221 pe_.outline(p->width, p->height, c->border_points, poly);
00222 for (int i = 0; i < poly.polys_.size(); ++i)
00223 {
00224 for (std::vector<cob_3d_segmentation::PolygonPoint>::iterator it = poly.polys_[i].begin(); it != poly.polys_[i].end(); ++it)
00225 {
00226 borders->points.push_back(p->points[cob_3d_segmentation::PolygonPoint::getInd(it->x, it->y)]);
00227 }
00228 }
00229 }
00230
00231 visualization::PCLVisualizer v;
00232 visualization::PointCloudColorHandlerRGBField<PointXYZRGB> chdl_p(p);
00233 visualization::PointCloudColorHandlerRGBField<PointXYZRGB> chdl_pt(pt);
00234 visualization::PointCloudColorHandlerRGBField<PointXYZRGB> chdl_p2(p2);
00235 visualization::PointCloudColorHandlerCustom<PointXYZ> blue_hdl (centroids, 0,0,255);
00236 visualization::PointCloudColorHandlerRGBField<PointXYZRGB> border_hdl (borders);
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 int v1(0);
00247 v.createViewPort(0.0, 0.5, 0.5, 1.0, v1);
00248
00249 v.addPointCloud<PointXYZRGB>(p, chdl_p, "segmented", v1);
00250
00251
00252 v.addPointCloud<PointXYZ>(centroids, blue_hdl, "ints_centroid", v1);
00253 v.addPointCloudNormals<PointXYZ,Normal>(centroids, ints_comp1, 1, 1.0, "ints_comp1", v1);
00254 v.addPointCloudNormals<PointXYZ,Normal>(plane_centroids, plane_normals, 1, 1.0, "plane_normals", v1);
00255
00256
00257 v.setPointCloudRenderingProperties(visualization::PCL_VISUALIZER_COLOR, 1.0, 0.0, 0.0, "ints_comp1", v1);
00258 v.setPointCloudRenderingProperties(visualization::PCL_VISUALIZER_COLOR, 0.0, 1.0, 0.0, "plane_normals", v1);
00259
00260
00261
00262
00263 int v2(0);
00264 v.createViewPort(0.5, 0.5, 1.0, 1.0, v2);
00265
00266 v.addPointCloud<PointXYZRGB>(pt, chdl_pt, "classified", v2);
00267 v.addPointCloudNormals<PointXYZRGB, Normal>(pt, n, 5, 0.04, "normals_new", v2);
00268
00269
00270
00271
00272 int v3(0);
00273 v.createViewPort(0.0, 0.0, 0.5, 0.5, v3);
00274
00275 v.addPointCloud<PointXYZRGB>(borders, border_hdl, "boundary_points", v3);
00276
00277
00278 int v4(0);
00279 v.createViewPort(0.5, 0.0, 1.0, 0.5, v4);
00280
00281 v.addPointCloud<PointXYZRGB>(p2, chdl_p2, "segmented_first", v4);
00282 v.addPointCloudNormals<PointXYZRGB, Normal>(pbp, n_bp, 1, 0.02, "boundary_normals", v4);
00283
00284
00285 while(!v.wasStopped())
00286 {
00287 v.spinOnce(100);
00288 usleep(100000);
00289 }
00290
00291 return 0;
00292 }