00001
00063
00064 #include <boost/program_options.hpp>
00065
00066
00067 #include <pcl/point_types.h>
00068 #include <pcl/io/pcd_io.h>
00069 #include <pcl/filters/voxel_grid.h>
00070 #include <pcl/visualization/pcl_visualizer.h>
00071 #include <pcl/visualization/point_cloud_handlers.h>
00072
00073
00074 #include <cob_3d_mapping_common/label_defines.h>
00075 #include "cob_3d_segmentation/plane_extraction.h"
00076
00077 std::string file_in_;
00078 std::string label_out_;
00079 bool borders_;
00080
00081 typedef pcl::PointXYZRGB PointT;
00082
00083 void readOptions(int argc, char* argv[])
00084 {
00085 using namespace boost::program_options;
00086 options_description options("Options");
00087 options.add_options()
00088 ("help", "produce help message")
00089 ("in,i", value<std::string>(&file_in_), "input pcd file")
00090 ("label_out,l", value<std::string>(&label_out_), "save labeled file to")
00091 ("borders,b", "enable border visuaization")
00092 ;
00093
00094 positional_options_description p_opt;
00095 p_opt.add("in", 1);
00096 variables_map vm;
00097 store(command_line_parser(argc, argv).options(options).positional(p_opt).run(), vm);
00098 notify(vm);
00099
00100 if (vm.count("help") || argc == 1)
00101 {
00102 std::cout << options << std::endl;
00103 exit(0);
00104 }
00105 if (vm.count("borders")) borders_=true;
00106 else borders_=false;
00107 }
00108
00109 int main(int argc, char** argv)
00110 {
00111 readOptions(argc, argv);
00112
00113 pcl::PointCloud<PointT>::Ptr p(new pcl::PointCloud<PointT>);
00114 pcl::PointCloud<PointT>::Ptr p_vox(new pcl::PointCloud<PointT>);
00115 pcl::PointCloud<PointT>::Ptr p_out(new pcl::PointCloud<PointT>);
00116 pcl::PointCloud<PointT>::Ptr p_hull(new pcl::PointCloud<PointT>);
00117 pcl::io::loadPCDFile<PointT> (file_in_, *p);
00118 std::cout << "loaded " << p->size() << " Points..." << std::endl;
00119
00120 *p_out = *p;
00121
00122 pcl::VoxelGrid<PointT> voxel;
00123 voxel.setSaveLeafLayout(true);
00124 voxel.setInputCloud(p);
00125 voxel.setLeafSize(0.03,0.03,0.03);
00126 voxel.filter(*p_vox);
00127
00128 for(pcl::PointCloud<PointT>::iterator it=p_vox->begin(); it!=p_vox->end(); ++it) { it->rgba = LBL_SPH; }
00129
00130 std::vector<pcl::PointCloud<PointT>, Eigen::aligned_allocator<pcl::PointCloud<PointT> > > v_cloud_hull;
00131 std::vector<std::vector<pcl::Vertices> > v_hull_polygons;
00132 std::vector<pcl::ModelCoefficients> v_coefficients_plane;
00133 PlaneExtraction pe;
00134 pe.setSaveToFile(false);
00135 pe.setClusterTolerance(0.06);
00136 pe.setMinPlaneSize(150);
00137 pe.setAlpha(0.2);
00138 pe.extractPlanes(p_vox, v_cloud_hull, v_hull_polygons, v_coefficients_plane);
00139
00140 for (size_t i=0; i<v_coefficients_plane.size(); ++i)
00141 {
00142 std::cout << v_coefficients_plane[i].values[0] << ","
00143 << v_coefficients_plane[i].values[1] << ","
00144 << v_coefficients_plane[i].values[2] << std::endl;
00145 }
00146
00147
00148 const float rand_max_inv = 1.0f/ RAND_MAX;
00149 for (size_t pl=0; pl<pe.extracted_planes_indices_.size(); ++pl)
00150 {
00151 int r = (float)rand() * rand_max_inv * 255;
00152 int g = (float)rand() * rand_max_inv * 255;
00153 int b = (float)rand() * rand_max_inv * 255;
00154 int color = ( r << 16 | g << 8 | b );
00155 for(std::vector<int>::iterator idx=pe.extracted_planes_indices_[pl].begin(); idx!=pe.extracted_planes_indices_[pl].end(); ++idx)
00156 {
00157 p_vox->points[*idx].rgba = color;
00158 }
00159 }
00160
00161
00162 for (pcl::PointCloud<PointT>::iterator it=p_out->begin(); it!=p_out->end(); ++it)
00163 {
00164 if (it->z != it->z) { it->rgba = LBL_UNDEF; }
00165 else { it->rgba = p_vox->points[voxel.getCentroidIndex(*it)].rgba; }
00166 }
00167
00168 if (borders_)
00169 {
00170
00171 int mask[] = { -p_out->width, 1, p_out->width, -1 };
00172 int x, y, count, curr_color;
00173 pcl::PointCloud<PointT>::Ptr p_copy(new pcl::PointCloud<PointT>);
00174 *p_copy = *p_out;
00175 for (int idx=0; idx<p_out->size(); ++idx)
00176 {
00177 curr_color = (*p_copy)[idx].rgba;
00178 x = idx % p_out->width; y = idx / p_out->width;
00179 if (x==0 || y==0 || x == p_out->width-1 || y == p_out->height-1) { (*p_out)[idx].rgba = LBL_BORDER; continue; }
00180 count = 0;
00181 for(int i=0;i<4;++i) { if (curr_color != (*p_copy)[idx+mask[i]].rgba) { ++count; } }
00182 if (count > 3 || count < 1)
00183 {
00184 if ((*p_copy)[idx].rgba != LBL_SPH) { (*p_out)[idx].rgba = LBL_PLANE; }
00185 continue;
00186 }
00187 (*p_out)[idx].rgba = LBL_BORDER;
00188 }
00189 }
00190
00191 for (size_t pl=0; pl<v_cloud_hull.size(); ++pl)
00192 {
00193 int r = (float)rand() * rand_max_inv * 255;
00194 int g = (float)rand() * rand_max_inv * 255;
00195 int b = (float)rand() * rand_max_inv * 255;
00196 int color = ( r << 16 | g << 8 | b );
00197
00198 for (size_t p_idx=0; p_idx<v_cloud_hull[pl].size(); ++p_idx)
00199 {
00200 p_hull->push_back(v_cloud_hull[pl].points[p_idx]);
00201 p_hull->back().rgba = color;
00202 }
00203 }
00204
00205 p_hull->width = p_hull->points.size();
00206 p_hull->height = 1;
00207
00208
00209 if (label_out_ != "")
00210 {
00211 pcl::io::savePCDFileASCII<PointT>(label_out_, *p_out);
00212 return 0;
00213 }
00214 pcl::visualization::PCLVisualizer v;
00215 pcl::visualization::PointCloudColorHandlerRGBField<PointT> chdl_p(p_out);
00216 pcl::visualization::PointCloudColorHandlerRGBField<PointT> chdl_hull(p_hull);
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 int v1(0);
00229 v.createViewPort(0.0, 0.0, 0.5, 1.0, v1);
00230 v.addPointCloud<PointT>(p_out, chdl_p, "planes", v1);
00231
00232 int v2(0);
00233 v.createViewPort(0.5, 0.0, 1.0, 1.0, v2);
00234 v.addPointCloud<PointT>(p_hull, chdl_hull, "hull", v2);
00235
00236 while(!v.wasStopped())
00237 {
00238 v.spinOnce(100);
00239 usleep(100000);
00240 }
00241
00242 return 0;
00243 }
00244
00245