PCDIO.cpp
Go to the documentation of this file.
1 
28 #include "lvr2/io/PCDIO.hpp"
29 #include <fstream>
30 #ifdef LVR2_USE_PCL
31 #include <pcl/io/pcd_io.h>
32 #include <pcl/point_types.h>
33 #endif /* LVR2_USE_PCL */
34 
35 #define isnan(x) ((x) != (x))
36 
37 namespace lvr2
38 {
39 
40 #ifdef LVR2_USE_PCL
41 
43 {
44  pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloud( new pcl::PointCloud<pcl::PointXYZRGBNormal> );
45 
46  if ( pcl::io::loadPCDFile<pcl::PointXYZRGBNormal>( filename, *cloud ) == -1)
47  {
48  std::cerr << "Couldn't read file “" << filename << "”." << std::endl;
49  ModelPtr m;
50  return m;
51  }
52 
53  bool has_normals = false;
54  bool has_colors = false;
55 
56  floatArr points = floatArr( new float[ cloud->points.size() * 3 ] );
57  ucharArr colors = ucharArr( new unsigned char[ cloud->points.size() * 3] );
58  floatArr normals = floatArr( new float[ cloud->points.size() * 3] );
59  /* model->m_pointCloud->setPointColorArray( pointColors, numPoints ); */
60  for ( size_t i(0); i < cloud->points.size(); i++ )
61  {
62  if(!isnan(cloud->points[i].x) && !isnan(cloud->points[i].y) && !isnan(cloud->points[i].z) )
63  {
64  points[i*3 + 0] = cloud->points[i].x;
65  points[i*3 + 1] = cloud->points[i].y;
66  points[i*3 + 2] = cloud->points[i].z;
67  }
68  else
69  {
70  points[i*3 + 0] = 0.0;
71  points[i*3 + 1] = 0.0;
72  points[i*3 + 2] = 0.0;
73  }
74 
75  if(!isnan(cloud->points[i].r) && !isnan(cloud->points[i].g) && !isnan(cloud->points[i].b) )
76  {
77  colors[i*3 + 0] = cloud->points[i].r;
78  colors[i*3 + 1] = cloud->points[i].g;
79  colors[i*3 + 2] = cloud->points[i].b;
80  has_colors = true;
81  }
82  else
83  {
84  colors[i*3 + 0] = 0;
85  colors[i*3 + 1] = 255;
86  colors[i*3 + 2] = 0;
87  }
88 
89  if(!isnan(cloud->points[i].normal_x) && !isnan(cloud->points[i].normal_y) && !isnan(cloud->points[i].normal_z) )
90  {
91  normals[i*3 + 0] = cloud->points[i].normal_x;
92  normals[i*3 + 1] = cloud->points[i].normal_y;
93  normals[i*3 + 2] = cloud->points[i].normal_z;
94  has_normals = true;
95  }
96  }
97 
98  ModelPtr model( new Model( PointBufferPtr( new PointBuffer )));
99  model->m_pointCloud->setPointArray( points, cloud->points.size() );
100 
101  if(has_colors)
102  {
103  model->m_pointCloud->setColorArray( colors, cloud->points.size() );
104  }
105 
106  if(has_normals)
107  {
108  model->m_pointCloud->setNormalArray( normals, cloud->points.size() );
109  }
110  m_model = model;
111  return model;
112 
113 }
114 #else /* LVR2_USE_PCL */
115 
116 ModelPtr PCDIO::read( string filename )
117 {
118  /* Without PCL we do not read pcd files. */
119  ModelPtr m( new Model );
120  return m;
121 }
122 #endif /* LVR2_USE_PCL */
123 
124 
125 void PCDIO::save( string filename )
126 {
127 
128  size_t pointcount(0), buf(0);
129  size_t w_color(0);
130 
131  floatArr points;
132  ucharArr pointColors;
133 
134  pointcount = m_model->m_pointCloud->numPoints();
135  points = m_model->m_pointCloud->getPointArray();
136  pointColors = m_model->m_pointCloud->getUCharArray("colors", buf, w_color);
137 
138  /* We need the same amount of color information and points. */
139  if ( pointcount != buf )
140  {
141  pointColors.reset();
142  std::cerr << "Amount of points and color information is"
143  " not equal. Color information won't be written." << std::endl;
144  }
145 
146  std::ofstream out( filename.c_str() );
147 
148  if ( !out.is_open() )
149  {
150  std::cerr << "Could not open file »" << filename << "«…"
151  << std::endl;
152  return;
153  }
154 
155  out << "# .PCD v.7 - Point Cloud Data file format" << std::endl;
156  out << "FIELDS x y z" << ( pointColors ? " rgb" : "" ) << std::endl;
157  out << "SIZE 4 4 4" << ( pointColors ? " 4" : "" ) << std::endl;
158  out << "TYPE F F F" << ( pointColors ? " F" : "" ) << std::endl;
159  out << "WIDTH " << pointcount << std::endl;
160  out << "HEIGHT 1" << std::endl;
161  out << "POINTS " << pointcount << std::endl;
162  out << "DATA ascii" << std::endl;
163 
164 
165  for ( size_t i(0); i < pointcount; i++ )
166  {
167  /* Write coordinates. */
168  out << points[i*3 + 0] << " " << points[i*3 + 1] << " " << points[i*3 + 2];
169 
170  /* Write color information if there are any. */
171  if ( pointColors )
172  {
173  /* Convert uchar array to float. */
174  float rgbf(0);
175  uint8_t* rgb = (uint8_t*) reinterpret_cast<uint8_t*>( &rgbf );
176  rgb[2] = pointColors[i*w_color + 0];
177  rgb[1] = pointColors[i*w_color + 1];
178  rgb[0] = pointColors[i*w_color + 2];
179 
180  /* Write data. */
181  out << " " << rgbf;
182 
183  }
184  out << std::endl;
185 
186  }
187 
188  out.close();
189 
190 }
191 
192 } // namespace lvr2
#define isnan(x)
Definition: PCDIO.cpp:35
boost::shared_array< unsigned char > ucharArr
Definition: DataStruct.hpp:137
std::shared_ptr< PointBuffer > PointBufferPtr
ModelPtr m_model
Definition: BaseIO.hpp:104
boost::shared_array< float > floatArr
Definition: DataStruct.hpp:133
virtual void save(string filename)
Definition: PCDIO.cpp:125
std::shared_ptr< Model > ModelPtr
Definition: Model.hpp:80
virtual ModelPtr read(string filename)
Reads the given file and stores point and normal information in the given parameters.
Definition: PCDIO.cpp:116
Read and write point clouds from PCD files.


lvr2
Author(s): Thomas Wiemann , Sebastian Pütz , Alexander Mock , Lars Kiesow , Lukas Kalbertodt , Tristan Igelbrink , Johan M. von Behren , Dominik Feldschnieders , Alexander Löhr
autogenerated on Mon Feb 28 2022 22:46:08