MEPP2 Project
shot_color_estimation_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 // *** Use FEVV::PCLPointCloud datastructure. ***
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 #include <pcl/features/shot_omp.h>
37 
38 #include <pcl/pcl_config.h>
39 
40 // main
41 int main(int argc, char *argv[])
42 {
43  // parse arguments
44  if(argc != 2)
45  {
46  std::cout << "Usage: " << argv[0] << " input_mesh_filename" << std::endl;
47  std::cout << "Example: " << argv[0] << " bun0.pcd" << std::endl;
48  return EXIT_FAILURE;
49  }
50  std::string input_file = argv[1];
51 
52  //----------------------------------
53 
54  // create point cloud
55  typedef FEVV::PCLPointCloud PointCloudT;
56  PointCloudT pc;
57 
58  // load point cloud
59  std::cout << "load point cloud" << std::endl;
60  FEVV::PMapsContainer pmaps_bag;
61  FEVV::Filters::read_mesh(input_file, pc, pmaps_bag);
62 
63  //----------------------------------
64 
65  // create vertex-normal property map
66  using VertexNormalMap = typename FEVV::PMap_traits< FEVV::vertex_normal_t,
67  PointCloudT >::pmap_type;
68  VertexNormalMap v_nm;
69  std::cout << "create vertex-normal map" << std::endl;
71 
72  // store property map in property maps bag
73  put_property_map(FEVV::vertex_normal, pc, pmaps_bag, v_nm);
74 
75  // compute shot color estimation
76  std::cout << "compute shot color estimation" << std::endl;
77 
78  //----------------------------------
79  // PCL specific section - begin
80  //----------------------------------
81 
82  typedef FEVV::PCLEnrichedPoint PointType;
83  typedef FEVV::PCLEnrichedPoint NormalType;
84  // use the cloud point to store the normal
85 
86  // init
87  std::vector< int > indices;
88  indices.resize(pc.points.size());
89  for(size_t i = 0; i < indices.size(); ++i)
90  indices[i] = static_cast< int >(i);
91  pcl::search::KdTree< PointType >::Ptr tree;
92  tree.reset(new pcl::search::KdTree< PointType >(false));
93  tree->setInputCloud(pc.makeShared());
94 
95  // estimate normals first
96  double mr = 0.002;
97  pcl::NormalEstimation< PointType, NormalType > n;
98  n.setInputCloud(pc.makeShared());
99 #if PCL_VERSION_COMPARE(<, 1, 11, 0)
100  boost::shared_ptr< std::vector< int > > indicesptr(new std::vector< int >(indices));
101 #else
102  std::shared_ptr< std::vector< int > > indicesptr(new std::vector< int >(indices));
103 #endif
104  n.setIndices(indicesptr);
105  n.setSearchMethod(tree);
106  n.setRadiusSearch(20 * mr);
107  n.compute(pc);
108 
109  // init kdtree
110  pcl::search::KdTree< PointType >::Ptr rgbaTree;
111  rgbaTree.reset(new pcl::search::KdTree< PointType >(false));
112 
113  // SHOT1344
114  pcl::SHOTColorEstimationOMP< PointType, NormalType, pcl::SHOT1344 > shot1344(
115  true, true);
116  shot1344.setInputNormals(pc.makeShared());
117  shot1344.setRadiusSearch(20 * mr);
118  pcl::PointCloud< pcl::SHOT1344 >::Ptr shots1344(new pcl::PointCloud< pcl::SHOT1344 >());
119  shot1344.setInputCloud(pc.makeShared());
120  shot1344.setIndices(indicesptr);
121  shot1344.setSearchMethod(rgbaTree);
122  shot1344.compute(*shots1344);
123 
124  //----------------------------------
125  // PCL specific section - end
126  //----------------------------------
127 
128  return 0;
129 }
130 
131 #else
132 
133 // *** PCL Native code. ***
134 
135 /*
136  * Software License Agreement (BSD License)
137  *
138  * Point Cloud Library (PCL) - www.pointclouds.org
139  * Copyright (c) 2014-, Open Perception, Inc.
140  *
141  * All rights reserved.
142  *
143  * Redistribution and use in source and binary forms, with or without
144  * modification, are permitted provided that the following conditions
145  * are met:
146  *
147  * * Redistributions of source code must retain the above copyright
148  * notice, this list of conditions and the following disclaimer.
149  * * Redistributions in binary form must reproduce the above
150  * copyright notice, this list of conditions and the following
151  * disclaimer in the documentation and/or other materials provided
152  * with the distribution.
153  * * Neither the name of the copyright holder(s) nor the names of its
154  * contributors may be used to endorse or promote products derived
155  * from this software without specific prior written permission.
156  *
157  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
158  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
159  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
160  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
161  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
162  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
163  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
164  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
165  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
166  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
167  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
168  * POSSIBILITY OF SUCH DAMAGE.
169  *
170  */
171 
172 // inspired by pcl-1.8.1-src/test/features/test_shot_estimation.cpp
173 
174 #include <pcl/point_cloud.h>
175 #include <pcl/features/normal_3d_omp.h>
176 #include <pcl/io/pcd_io.h>
177 #include <pcl/features/shot.h>
178 #include <pcl/features/shot_omp.h>
179 #include "pcl/features/shot_lrf.h"
180 #include <pcl/features/3dsc.h>
181 #include <pcl/features/usc.h>
182 
183 #include <iostream>
184 #include <cmath> // for fabs()
185 // must be the last include to avoid side effect of disabling NDEBUG
186 #undef NDEBUG // enable assert in release mode
187 #include <cassert>
188 
189 
190 // print cloud
191 template< typename CloudType >
192 void
193 print_cloud(const CloudType &cloud)
194 {
195  std::cout << "*** PointCloud = \n" << cloud << std::endl;
196 
197  std::cout << "*** points = " << std::endl;
198  for(int i = 0; i < cloud.points.size(); i++)
199  {
200  std::cout << "cloud.points[" << i << "] = " << cloud.points[i]
201  << std::endl;
202  }
203 }
204 
205 
206 #define EXPECT_NEAR(v1, v2, epsilon) assert(fabs((v1)-(v2)) <= (epsilon))
207 
208 
209 // main function
210 int
211 main(void)
212 {
213  // fetch point cloud filename in arguments
214  std::string input_filename("bun0.pcd");
215 
216  // create datastructure to store points
217  pcl::PointCloud<pcl::PointXYZ> cloud;
218 
219  // load file
220  if(pcl::io::loadPCDFile(input_filename, cloud) < 0)
221  {
222  std::cout << "Failed to load file '" << input_filename << "'." << std::endl;
223  std::cout << "This file is provided in PCL sources." << std::endl;
224  return -1; // failure
225  }
226 
227  // print cloud after loading
228  //std::cout << std::endl << "cloud after loading :" << std::endl;
229  //print_cloud(cloud);
230 
231  // init
232  std::vector< int > indices;
233  typedef pcl::search::KdTree<pcl::PointXYZ>::Ptr KdTreePtr;
234  KdTreePtr tree;
235  indices.resize(cloud.points.size());
236  for(size_t i = 0; i < indices.size(); ++i)
237  indices[i] = static_cast< int >(i);
238  tree.reset(new pcl::search::KdTree< pcl::PointXYZ >(false));
239  tree->setInputCloud(cloud.makeShared());
240 
241  // estimate normals first
242  double mr = 0.002;
243  pcl::NormalEstimation< pcl::PointXYZ, pcl::Normal > n;
244  pcl::PointCloud< pcl::Normal >::Ptr normals(new pcl::PointCloud< pcl::Normal >());
245  n.setInputCloud(cloud.makeShared());
246  boost::shared_ptr< std::vector< int > > indicesptr(new std::vector< int >(indices));
247  n.setIndices(indicesptr);
248  n.setSearchMethod(tree);
249  n.setRadiusSearch(20 * mr);
250  n.compute(*normals);
251  std::cout << "normals->points.size() = " << normals->points.size() << std::endl;
252 
253  // Create fake point cloud with colors
254  pcl::PointCloud< pcl::PointXYZRGBA > cloudWithColors;
255  for(int i = 0; i < static_cast< int >(cloud.points.size()); ++i)
256  {
257  pcl::PointXYZRGBA p;
258  p.x = cloud.points[i].x;
259  p.y = cloud.points[i].y;
260  p.z = cloud.points[i].z;
261 
262  //p.rgba = ((i % 255) << 16) + (((255 - i) % 255) << 8) + ((i * 37) % 255);
263  p.r = (i % 255);
264  p.g = ((255 - i) % 255);
265  p.b = ((i * 37) % 255);
266  cloudWithColors.push_back(p);
267  }
268 
269  // init kdtree
270  pcl::search::KdTree< pcl::PointXYZRGBA >::Ptr rgbaTree;
271  rgbaTree.reset(new pcl::search::KdTree< pcl::PointXYZRGBA >(false));
272 
273  // SHOT1344
274  pcl::SHOTColorEstimationOMP< pcl::PointXYZRGBA, pcl::Normal, pcl::SHOT1344 > shot1344(true,
275  true);
276  shot1344.setInputNormals(normals);
277  shot1344.setRadiusSearch(20 * mr);
278  pcl::PointCloud< pcl::SHOT1344 >::Ptr shots1344(new pcl::PointCloud< pcl::SHOT1344 >());
279  shot1344.setInputCloud(cloudWithColors.makeShared());
280  shot1344.setIndices(indicesptr);
281  shot1344.setSearchMethod(rgbaTree);
282 
283  // estimate
284  shot1344.compute(*shots1344);
285 
286  // check result
287  EXPECT_NEAR(shots1344->points[103].descriptor[10], 0.0020453099, 1e-5);
288  EXPECT_NEAR(shots1344->points[103].descriptor[11], 0.0021887729, 1e-5);
289  EXPECT_NEAR(shots1344->points[103].descriptor[21], 0.057930067, 1e-5);
290  EXPECT_NEAR(shots1344->points[103].descriptor[42], 0.011778189, 1e-5);
291  EXPECT_NEAR(shots1344->points[103].descriptor[53], 0.0065085669, 1e-5);
292  EXPECT_NEAR(shots1344->points[103].descriptor[54], 0.012025614, 1e-5);
293  EXPECT_NEAR(shots1344->points[103].descriptor[55], 0.0044803056, 1e-5);
294  EXPECT_NEAR(shots1344->points[103].descriptor[64], 0.0644530654, 1e-5);
295  EXPECT_NEAR(shots1344->points[103].descriptor[65], 0.0465045683, 1e-5);
296  EXPECT_NEAR(shots1344->points[103].descriptor[86], 0.011518310, 1e-5);
297 
298  EXPECT_NEAR(shots1344->points[103].descriptor[357], 0.0020453099, 1e-5);
299  EXPECT_NEAR(shots1344->points[103].descriptor[360], 0.0027993850, 1e-5);
300  EXPECT_NEAR(shots1344->points[103].descriptor[386], 0.0451327376, 1e-5);
301  EXPECT_NEAR(shots1344->points[103].descriptor[387], 0.0544394031, 1e-5);
302  EXPECT_NEAR(shots1344->points[103].descriptor[389], 0.0047547864, 1e-5);
303  EXPECT_NEAR(shots1344->points[103].descriptor[453], 0.0051176427, 1e-5);
304  EXPECT_NEAR(shots1344->points[103].descriptor[481], 0.0053625242, 1e-5);
305  EXPECT_NEAR(shots1344->points[103].descriptor[482], 0.012025614, 1e-5);
306  EXPECT_NEAR(shots1344->points[103].descriptor[511], 0.0057367259, 1e-5);
307  EXPECT_NEAR(shots1344->points[103].descriptor[512], 0.048375979, 1e-5);
308 
309  std::cout << "All checks passed." << std::endl;
310 
311  return 0;
312 }
313 
314 #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
main
int main(int argc, char *argv[])
Definition: shot_color_estimation_pcl.cpp:41
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::_PMap_traits
Definition: properties.h:376
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