MEPP2 Project
compute_normals_pcl.cpp
Go to the documentation of this file.
1 // Copyright (c) 2012-2019 University of Lyon and CNRS (France).
2 // All rights reserved.
3 //
4 // This file is part of MEPP2; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published
6 // by the Free Software Foundation; either version 3 of the License,
7 // or (at your option) any later version.
8 //
9 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
10 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11 
12 #if 1
13 
14 // *** MEPP2 code calling PCL native filters. ***
15 // *** Point and normal stored in a FEVV::PCLPointCloud. ***
16 
18  // for FEVV::PCLPointCloud
20  // for boost::graph_traits< FEVV::PCLPointCloud >
22  // for FEVV::RetrieveKernel< FEVV::PCLPointCloud >
24  // for get(FEVV::PCLPointCloudPointMap&, ...)
26  // for FEVV::PMap_traits< FEVV::PCLPointCloud >
27 
29  // for FEVV::Filters::read_mesh< FEVV::PCLPointCloud >
31  // for FEVV::Filters::write_mesh< FEVV::PCLPointCloud >
32 
33 #include <pcl/search/impl/search.hpp>
34 #include <pcl/features/normal_3d.h>
35 #include <pcl/kdtree/kdtree_flann.h>
36 
37 
38 // main
39 int main(int argc, char *argv[])
40 {
41  // parse arguments
42  if(argc != 3)
43  {
44  std::cout << "Usage: " << argv[0]
45  << " input_mesh_filename output_mesh_filename" << std::endl;
46  std::cout << "Example: " << argv[0] << " ../Testing/Data/tetra.xyz tetra.out.ply"
47  << std::endl;
48  return EXIT_FAILURE;
49  }
50  std::string input_file = argv[1];
51  std::string output_file = argv[2];
52 
53  //----------------------------------
54 
55  // create point cloud
56  typedef FEVV::PCLPointCloud PointCloudT;
57  PointCloudT pc;
58 
59  // load point cloud
60  std::cout << "load point cloud" << std::endl;
61  FEVV::PMapsContainer pmaps_bag;
62  FEVV::Filters::read_mesh(input_file, pc, pmaps_bag);
63 
64  //----------------------------------
65 
66  // create vertex-normal property map
67  using VertexNormalMap = typename FEVV::PMap_traits< FEVV::vertex_normal_t,
68  PointCloudT >::pmap_type;
69  VertexNormalMap v_nm;
70  std::cout << "create vertex-normal map" << std::endl;
72 
73  // store property map in property maps bag
74  put_property_map(FEVV::vertex_normal, pc, pmaps_bag, v_nm);
75 
76  // compute normals
77  std::cout << "compute normals" << std::endl;
78 
79  //----------------------------------
80  // PCL specific section - begin
81  //----------------------------------
82 
83  typedef FEVV::PCLEnrichedPoint PointType;
84  typedef FEVV::PCLEnrichedPoint NormalType;
85  // use the cloud point to store the normal
86 
87  pcl::NormalEstimation< PointType, NormalType > normal_estimator;
88  normal_estimator.setInputCloud(pc.makeShared());
89 
90  pcl::search::KdTree< PointType >::Ptr kdtree(
91  new pcl::search::KdTree< PointType >);
92  normal_estimator.setSearchMethod(kdtree);
93 
94  normal_estimator.setRadiusSearch(0.03);
95  normal_estimator.compute(pc);
96 
97  //----------------------------------
98  // PCL specific section - end
99  //----------------------------------
100 
101  // save point cloud with normals
102  std::cout << "save point cloud with normals" << std::endl;
103  FEVV::Filters::write_mesh(output_file, pc, pmaps_bag);
104 
105  return 0;
106 }
107 
108 #else
109 
110 // *** PCL Native code. ***
111 
112 /*
113  * Software License Agreement (BSD License)
114  *
115  * Point Cloud Library (PCL) - www.pointclouds.org
116  * Copyright (c) 2014-, Open Perception, Inc.
117  *
118  * All rights reserved.
119  *
120  * Redistribution and use in source and binary forms, with or without
121  * modification, are permitted provided that the following conditions
122  * are met:
123  *
124  * * Redistributions of source code must retain the above copyright
125  * notice, this list of conditions and the following disclaimer.
126  * * Redistributions in binary form must reproduce the above
127  * copyright notice, this list of conditions and the following
128  * disclaimer in the documentation and/or other materials provided
129  * with the distribution.
130  * * Neither the name of the copyright holder(s) nor the names of its
131  * contributors may be used to endorse or promote products derived
132  * from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
137  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
138  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
139  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
140  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
141  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
142  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
143  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
144  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
145  * POSSIBILITY OF SUCH DAMAGE.
146  *
147  */
148 
149 // partially inspired by
150 // - pcl-1.8.1-src/doc/tutorials/content/sources/
151 // global_hypothesis_verification/global_hypothesis_verification.cpp
152 // - pcl-1.8.1-src/doc/tutorials/content/sources/
153 // correspondence_grouping/correspondence_grouping.cpp
154 
155 #include <iostream>
156 
157 #include <pcl/search/impl/search.hpp>
158 
159 #include <pcl/io/pcd_io.h>
160 #include <pcl/io/ascii_io.h>
161 #include <pcl/point_cloud.h>
162 #include <pcl/features/normal_3d.h>
163 #include <pcl/kdtree/kdtree_flann.h>
164 
165 #include <string>
166 
167 
168 // help
169 void
170 showHelp(char * program_name)
171 {
172  std::cout << std::endl;
173  std::cout << "Usage: " << program_name << " cloud_filename.xyz" << std::endl;
174 }
175 
176 
177 // print cloud
178 template< typename CloudType >
179 void
180 print_cloud(const CloudType &cloud)
181 {
182  std::cout << "*** PointCloud = \n" << cloud << std::endl;
183 
184  std::cout << "*** points = " << std::endl;
185  for(int i = 0; i < cloud.points.size(); i++)
186  {
187  std::cout << "cloud.points[" << i << "] = " << cloud.points[i]
188  << std::endl;
189  }
190 
191 #if 0
192  // how to access point and normal
193 
194  std::cout << "*** points.data = " << std::endl;
195  for(int i = 0; i < cloud.points.size(); i++)
196  {
197  for(int j = 0; j < 4; j++)
198  {
199  std::cout << "cloud.points[" << i << "].data[" << j << "] = " << cloud.points[i].data[j]
200  << std::endl;
201  }
202  }
203 
204  std::cout << "*** points.normal = " << std::endl;
205  for(int i = 0; i < cloud.points.size(); i++)
206  {
207  for(int j = 0; j < 4; j++)
208  {
209  std::cout << "cloud.points[" << i << "].normal[" << j << "] = " << cloud.points[i].normal[j]
210  << std::endl;
211  }
212  }
213 #endif
214 }
215 
216 // main function
217 int
218 main (int argc, char** argv)
219 {
220  // show help
221  if(argc != 2)
222  {
223  showHelp(argv[0]);
224  return 0;
225  }
226 
227  // fetch point cloud filename in arguments
228  std::string input_filename(argv[1]);
229 
230  // create datastructure to store points
231  typedef pcl::PointXYZ PointType;
232  pcl::PointCloud< PointType >::Ptr cloud(new pcl::PointCloud< PointType >());
233 
234  // load file
235  pcl::ASCIIReader reader;
236  reader.setInputFields< PointType >();
237  reader.setExtension(".xyz");
238 
239  if(reader.read(input_filename, *cloud) < 0)
240  {
241  std::cout << "Error loading point cloud from " << input_filename << std::endl
242  << std::endl;
243  return -1;
244  }
245  else
246  {
247  std::cout << "Point cloud successfully loaded from " << input_filename << std::endl;
248  }
249 
250  // print cloud after loading
251  std::cout << std::endl << "cloud after loading :" << std::endl;
252  print_cloud(*cloud);
253 
254  // compute normals
255  //typedef pcl::Normal NormalType;
256  typedef pcl::PointNormal NormalType;
257  pcl::NormalEstimation< PointType, NormalType > normal_estimation;
258  normal_estimation.setInputCloud(cloud);
259 
260  pcl::search::KdTree< PointType >::Ptr kdtree(
261  new pcl::search::KdTree< PointType >);
262  normal_estimation.setSearchMethod(kdtree);
263 
264  pcl::PointCloud< NormalType > normals;
265  normal_estimation.setRadiusSearch(0.03);
266  normal_estimation.compute(normals);
267 
268 #if 1
269  // Copy the xyz info from cloud_xyz and add it to cloud_normals as the xyz field in PointNormals estimation is zero
270  for(size_t i = 0; i < normals.points.size(); ++i)
271  {
272  normals.points[i].x = cloud->points[i].x;
273  normals.points[i].y = cloud->points[i].y;
274  normals.points[i].z = cloud->points[i].z;
275  }
276 #endif
277 
278  // print cloud with normal
279  std::cout << std::endl << "cloud with normals :" << std::endl;
280  print_cloud(normals);
281 
282 
283  // write Point cloud to file
284  std::string output_filename("test.pcd");
285  if(pcl::io::savePCDFile(output_filename, normals) < 0)
286  {
287  std::cout << "Error saving point cloud to " << output_filename << std::endl;
288  return -1;
289  }
290  else
291  {
292  std::cout << "Point cloud successfully saved to " << output_filename << std::endl;
293  }
294 
295  return 0;
296 }
297 
298 #endif
FEVV::put_property_map
void put_property_map(PropertyT p, const MeshT &, PMapsContainer &pmaps, const typename PMap_traits< PropertyT, MeshT >::pmap_type &pmap)
Definition: properties.h:664
pcl_point_cloud_writer.hpp
Graph_traits_pcl_point_cloud.h
Geometry_traits_pcl_point_cloud.h
Graph_properties_pcl_point_cloud.h
FEVV::PCLPointCloud
pcl::PointCloud< PCLEnrichedPoint > PCLPointCloud
Definition: DataStructures_pcl_point_cloud.h:28
FEVV::PMapsContainer
std::map< std::string, boost::any > PMapsContainer
Definition: properties.h:99
FEVV::vertex_normal_t
vertex_normal_t
Definition: properties.h:35
DataStructures_pcl_point_cloud.h
FEVV::Filters::read_mesh
void read_mesh(const std::string &filename, FEVV::CGALPointSet &g, PMapsContainer &pmaps, bool=false)
Load mesh from file.
Definition: cgal_point_set_reader.hpp:110
pcl_point_cloud_reader.hpp
properties_pcl_point_cloud.h
FEVV::Filters::write_mesh
void write_mesh(const std::string &filename, FEVV::CGALPointSet &g, PMapsContainer &pmaps)
Write mesh to file.
Definition: cgal_point_set_writer.hpp:42
FEVV::_PMap_traits
Definition: properties.h:376
main
int main(int argc, char *argv[])
Definition: compute_normals_pcl.cpp:39
FEVV::vertex_normal
@ vertex_normal
Definition: properties.h:35
FEVV::make_property_map
PMap_traits< PropertyT, MeshT >::pmap_type make_property_map(PropertyT, const MeshT &m)
Definition: properties.h:630
FEVV::PCLEnrichedPoint
pcl::PointXYZRGBNormal PCLEnrichedPoint
Definition: DataStructures_pcl_point_cloud.h:27