00001 
00063 #include <boost/program_options.hpp>
00064 
00065 #include <pcl/point_types.h>
00066 #include <pcl/io/pcd_io.h>
00067 #include <pcl/visualization/pcl_visualizer.h>
00068 #include <pcl/visualization/point_cloud_handlers.h>
00069 
00070 #include "cob_3d_mapping_common/point_types.h"
00071 #include "cob_3d_features/organized_normal_estimation.h"
00072 
00073 
00074 std::string file_in_;
00075 
00076 void readOptions(int argc, char* argv[])
00077 {
00078   using namespace boost::program_options;
00079   options_description options("Options");
00080   options.add_options()
00081     ("help", "produce help message")
00082     ("in,i", value<std::string>(&file_in_), "input pcd file")
00083     ;
00084 
00085   positional_options_description p_opt;
00086   p_opt.add("in", 1);
00087   variables_map vm;
00088   store(command_line_parser(argc, argv).options(options).positional(p_opt).run(), vm);
00089   notify(vm);
00090 
00091   if (vm.count("help"))
00092   {
00093     cout << options << endl;
00094     exit(0);
00095   }
00096 }
00097 
00098 typedef pcl::PointXYZRGB PointT;
00099 typedef pcl::Normal NormalT;
00100 
00101 typedef pcl::PointCloud<PointT> PCloud;
00102 typedef pcl::PointCloud<NormalT> NCloud;
00103 
00104 int main(int argc, char** argv)
00105 {
00106   readOptions(argc, argv);
00107   PCloud::Ptr p(new PCloud);
00108   NCloud::Ptr n1(new NCloud);
00109   NCloud::Ptr n2(new NCloud);
00110   NCloud::Ptr n3(new NCloud);
00111   pcl::PointCloud<PointLabel>::Ptr l(new pcl::PointCloud<PointLabel>);
00112 
00113   pcl::PCDReader r;
00114   r.read(file_in_, *p);
00115   cob_3d_features::OrganizedNormalEstimation<PointT, NormalT, PointLabel> one;
00116   one.setPixelSearchRadius(8,2,2);
00117   one.setSkipDistantPointThreshold(8);
00118   one.setOutputLabels(l);
00119   one.setInputCloud(p);
00120   one.compute(*n1);
00121 
00122   n2->resize(n1->size());
00123   n3->resize(n1->size());
00124   int w = n3->width = n2->width = n1->width;
00125   int h = n3->height = n2->height = n1->height;
00126   *n2 = *n1;
00127 
00128 
00129 
00130 
00131 
00132 
00133 
00134 
00135 
00136 
00137 
00138 
00139 
00140 
00141 
00142 
00143 
00144 
00145 
00146 
00147 
00148 
00149 
00150 
00151 
00152 
00153 
00154   int mask_x[] = { -1, 0, 1 };
00155   int mask_y[] = { -w, 0, -w };
00156   float kernel[] = { 0.25f, 0.5f, 0.25f };
00157   
00158   int kernel_size = 3;
00159 
00160   for(int i=1; i<h*w; ++i) {
00161     memset(&((*n2)[i].normal), 0, 3*sizeof(float));
00162 
00163     for(int k=0; k<kernel_size; ++k) {
00164       if( (*n1)[ i + mask_x[k] ].normal[2] != (*n1)[ i + mask_x[k] ].normal[2] ) {
00165         (*n2)[i].getNormalVector3fMap() = (*n1)[i].getNormalVector3fMap();
00166         break;
00167       }
00168       (*n2)[i].getNormalVector3fMap() += kernel[k] * (*n1)[ i + mask_x[k] ].getNormalVector3fMap();
00169     }
00170   }
00171 
00172   for(int i=0; i<w; ++i)
00173     (*n3)[i].normal[0] = (*n3)[i].normal[1] = (*n3)[i].normal[2] = std::numeric_limits<float>::quiet_NaN();
00174   for(int i=h*(w-1); i<h*w; ++i)
00175     (*n3)[i].normal[0] = (*n3)[i].normal[1] = (*n3)[i].normal[2] = std::numeric_limits<float>::quiet_NaN();
00176 
00177   for(int i=w; i<h*(w-1); ++i) {
00178     memset(&((*n3)[i].normal), 0, 3*sizeof(float));
00179 
00180     for(int k=0; k<kernel_size; ++k) {
00181       if( (*n2)[ i + mask_y[k] ].normal[2] != (*n2)[ i + mask_y[k] ].normal[2] ) {
00182         (*n3)[i].getNormalVector3fMap() = (*n2)[i].getNormalVector3fMap();
00183         break;
00184       }
00185       (*n3)[i].getNormalVector3fMap() += kernel[k] * (*n2)[ i + mask_y[k] ].getNormalVector3fMap();
00186     }
00187 
00188     if( (*n3)[i].normal[2] == (*n3)[i].normal[2] )
00189       (*n3)[i].getNormalVector3fMap() = (*n3)[i].getNormalVector3fMap().normalized();
00190   }
00191 
00192   for(int i=0; i<h*w; ++i) {
00193     if( (*n3)[i].normal[2] != (*n3)[i].normal[2] ) continue;
00194     Eigen::Vector3f n_org = (*n1)[i].getNormalVector3fMap();
00195     Eigen::Vector3f n_dif = n_org - (*n3)[i].getNormalVector3fMap();
00196     if(n_dif(0) * n_dif(0) + n_dif(1) * n_dif(1) + n_dif(2) * n_dif(2) > 0.001f)
00197       (*n2)[i].getNormalVector3fMap() = (n_org + n_dif).normalized();
00198     else
00199       (*n2)[i].getNormalVector3fMap() = (*n3)[i].getNormalVector3fMap();
00200   }
00201 
00202   visualization::PCLVisualizer v;
00203   visualization::PointCloudColorHandlerCustom<PointT> blue_hdl (p, 0 ,0 ,230);
00204   int v1(0), v2(0);
00205   v.createViewPort(0.0, 0.0, 0.5, 1.0, v1);
00206   v.createViewPort(0.5, 0.0, 1.0, 1.0, v2);
00207 
00208   v.addPointCloud<PointT>(p, blue_hdl, "l_points", v1);
00209   v.addPointCloudNormals<PointT,NormalT>(p, n3, 10, 0.05, "l_normal", v1);
00210 
00211   v.addPointCloud<PointT>(p, blue_hdl, "r_points", v2);
00212   v.addPointCloudNormals<PointT,NormalT>(p, n2, 10, 0.05, "r_normal", v2);
00213 
00214   while(!v.wasStopped())
00215   {
00216     v.spinOnce(100);
00217     usleep(100000);
00218   }
00219 
00220 }