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 }