ScanDirectoryParser.cpp
Go to the documentation of this file.
1 #include <iomanip>
2 #include <sstream>
3 #include <boost/format.hpp>
4 
6 #include "lvr2/io/IOUtils.hpp"
9 
10 using namespace boost::filesystem;
11 
12 namespace lvr2
13 {
14 
15 ScanDirectoryParser::~ScanDirectoryParser()
16 {
17  // Delete scan descriptions
18  for(auto i : m_scans)
19  {
20  delete i;
21  }
22 }
23 
24 ScanDirectoryParser::ScanDirectoryParser(const std::string& directory) noexcept
25 {
26  // Check if directory exists and save path
27  Path dir(directory);
28  if(!exists(directory))
29  {
30  std::cout << timestamp << "Directory " << directory << " does not exist." << std::endl;
31  }
32  else
33  {
34  m_directory = directory;
35  }
36 
37  // Set default prefixes and extension
38  m_pointExtension = ".txt";
39  m_poseExtension = ".dat";
40  m_pointPrefix = "scan";
41  m_posePrefix = "scan";
42 
43  m_start = 0;
44  m_end = 0;
45 }
46 
47 void ScanDirectoryParser::setPointCloudPrefix(const std::string& prefix)
48 {
49  m_pointPrefix = prefix;
50 }
51 void ScanDirectoryParser::setPointCloudExtension(const std::string& extension)
52 {
53  cout << extension << endl;
54  m_pointExtension = extension;
55 }
56 void ScanDirectoryParser::setPosePrefix(const std::string& prefix)
57 {
58  m_posePrefix = prefix;
59 }
60 void ScanDirectoryParser::setPoseExtension(const std::string& extension)
61 {
62  m_poseExtension = extension;
63 }
64 
65 void ScanDirectoryParser::setStart(int s)
66 {
67  m_start = s;
68 }
69 void ScanDirectoryParser::setEnd(int e)
70 {
71  m_end = e;
72 }
73 
74 
75 size_t ScanDirectoryParser::examinePLY(const std::string& filename)
76 {
77  return getNumberOfPointsInPLY(filename);
78 }
79 
80 size_t ScanDirectoryParser::examineASCII(const std::string& filename)
81 {
82  Path p(filename);
83  return countPointsInFile(p);
84 }
85 
86 PointBufferPtr ScanDirectoryParser::octreeSubSample(const double& voxelSize, const size_t& minPoints)
87 {
88  ModelPtr out_model(new Model);
89 
90  for(auto i : m_scans)
91  {
92  std::cout << timestamp << "Reading " << i->m_filename << std::endl;
93  ModelPtr model = ModelFactory::readModel(i->m_filename);
94  if(model)
95  {
96  PointBufferPtr buffer = model->m_pointCloud;
97  if(buffer)
98  {
99  std::cout << timestamp << "Building octree with voxel size " << voxelSize << " from " << i->m_filename << std::endl;
100  OctreeReduction oct(buffer, voxelSize, 5);
101  PointBufferPtr reduced = oct.getReducedPoints();
102 
103  // Apply transformation
104  std::cout << timestamp << "Transforming reduced point cloud" << std::endl;
105  out_model->m_pointCloud = reduced;
106  transformPointCloud<double>(out_model, i->m_pose);
107 
108  // Write reduced data
109  std::stringstream name_stream;
110  Path p(i->m_filename);
111  name_stream << p.stem().string() << "_reduced" << ".ply";
112  std::cout << timestamp << "Saving data to " << name_stream.str() << std::endl;
113  ModelFactory::saveModel(out_model, name_stream.str());
114 
115  std::cout << timestamp << "Points written: " << reduced->numPoints() << std::endl;
116  }
117  }
118  }
119  return PointBufferPtr(new PointBuffer);
120 }
121 
122 PointBufferPtr ScanDirectoryParser::randomSubSample(const size_t& tz)
123 {
124  ModelPtr out_model(new Model);
125 
126  // Compute global reduction ratio and clamp
127  size_t actual_points = 0;
128 
129  for(auto i : m_scans)
130  {
131  ModelPtr model = ModelFactory::readModel(i->m_filename);
132  if(model)
133  {
134  PointBufferPtr buffer = model->m_pointCloud;
135  if(buffer)
136  {
137  PointBufferPtr reduced = 0;
138  int target_size = 0;
139  if(tz > 0)
140  {
141  // Calc number of points to sample
142  float total_ratio = (float)i->m_numPoints / m_numPoints;
143  float target_ratio = total_ratio * tz;
144 
145 
146  target_size = (int)(target_ratio + 0.5);
147  std::cout << timestamp << "Sampling " << target_size << " points from " << i->m_filename << std::endl;
148 
149  // Sub-sample buffer
150  reduced = subSamplePointBuffer(buffer, target_size);
151  }
152  else
153  {
154  std::cout << timestamp << "Using orignal points from " << i->m_filename << std::endl;
155  reduced = buffer;
156  target_size = buffer->numPoints();
157  }
158 
159  // Apply transformation
160  std::cout << timestamp << "Transforming point cloud" << std::endl;
161  out_model->m_pointCloud = reduced;
162  transformPointCloud<double>(out_model, i->m_pose);
163 
164  // Write reduced data
165  std::stringstream name_stream;
166  Path p(i->m_filename);
167  name_stream << p.stem().string() << "_reduced" << ".ply";
168  std::cout << timestamp << "Saving data to " << name_stream.str() << std::endl;
169  ModelFactory::saveModel(out_model, name_stream.str());
170 
171  actual_points += target_size;
172  std::cout << timestamp << "Points written: " << actual_points << " / " << tz << std::endl;
173  }
174  }
175  }
176  return out_model->m_pointCloud;
177 }
178 
179 void ScanDirectoryParser::parseDirectory()
180 {
181  std::cout << timestamp << "Parsing directory" << m_directory << std::endl;
182  std::cout << timestamp << "Point prefix and extension: " << m_pointPrefix << " " << m_pointExtension << std::endl;
183  std::cout << timestamp << "Pose prefix and extension: " << m_posePrefix << " " << m_poseExtension << std::endl;
184 
185  m_numPoints = 0;
186  for(size_t i = m_start; i <= m_end; i++)
187  {
188  // Construct name of current file
189  std::stringstream point_ss;
190  point_ss << m_pointPrefix << boost::format("%03d") % i << m_pointExtension;
191  std::string pointFileName = point_ss.str();
192  Path pointPath = Path(m_directory)/Path(pointFileName);
193 
194  // Construct name of transformation file
195  std::stringstream pose_ss;
196  pose_ss << m_posePrefix << boost::format("%03d") % i << m_poseExtension;
197  std::string poseFileName = pose_ss.str();
198  Path posePath = Path(m_directory)/Path(poseFileName);
199 
200  // Check for file and get number of points
201  size_t n = 0;
202  if(exists(pointPath))
203  {
204  std::cout << timestamp << "Counting points in file " << pointPath << std::endl;
205  if(pointPath.extension() == ".3d" || pointPath.extension() == ".txt" || pointPath.extension() == ".pts")
206  {
207  n = examineASCII(pointPath.string());
208  }
209  else if(pointPath.extension() == ".ply")
210  {
211  n = examinePLY(pointPath.string());
212  }
213  m_numPoints += n;
214  }
215  else
216  {
217  std::cout << timestamp << "Point cloud file " << pointPath << " does not exist." << std::endl;
218  }
219 
220  // Check for pose information file
221  Transformd matrix = Transformd::Identity();
222 
223  if(exists(posePath))
224  {
225  matrix = getTransformationFromFile<double>(posePath.string());
226  std::cout << timestamp << "Found transformation: " << posePath << " @ " << std::endl << matrix << std::endl;
227  }
228  else
229  {
230  std::cout << timestamp << "Scan pose file " << posePath << "does not exist. Will not transfrom." << std::endl;
231  }
232 
233 
234 
235  ScanInfo* info = new ScanInfo;
236  info->m_filename = std::string(pointPath.string());
237  info->m_numPoints = n;
238  info->m_pose = matrix;
239 
240  m_scans.push_back(info);
241  }
242  std::cout << timestamp << "Finished parsing. Directory contains " << m_scans.size() << " scans with " << m_numPoints << " points." << std::endl;
243 }
244 
245 
246 
247 } // namespace lvr2
A class to handle point information with an arbitrarily large number of attribute channels...
Definition: PointBuffer.hpp:51
static Timestamp timestamp
A global time stamp object for program runtime measurement.
Definition: Timestamp.hpp:116
PointBufferPtr getReducedPoints()
std::shared_ptr< PointBuffer > PointBufferPtr
Transform< double > Transformd
4x4 double precision transformation matrix
Definition: MatrixTypes.hpp:71
size_t getNumberOfPointsInPLY(const std::string &filename)
Get the Number Of Points (element points if present, vertex count otherwise) in a PLY file...
Definition: IOUtils.cpp:295
SharedPointer p
PointBufferPtr subSamplePointBuffer(PointBufferPtr src, const size_t &n)
Computes a random sub-sampling of a point buffer by creating a uniform distribution over all point in...
Definition: IOUtils.cpp:405
std::shared_ptr< Model > ModelPtr
Definition: Model.hpp:80
boost::filesystem::path Path
size_t countPointsInFile(const boost::filesystem::path &inFile)
Counts the number of points (i.e. number of lines) in the given file.
Definition: IOUtils.cpp:132


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:09