HDF5Tool.cpp
Go to the documentation of this file.
1 
36 #include <iostream>
37 #include <vector>
38 #include <algorithm>
39 #include <string.h>
40 #include <string>
41 #include <sstream>
42 #include <algorithm>
43 #include <cstring>
44 
45 #include "lvr2/io/ModelFactory.hpp"
46 #include "lvr2/io/Timestamp.hpp"
47 #include "lvr2/io/HDF5IO.hpp"
48 #include "lvr2/types/Hyperspectral.hpp"
53 #include "lvr2/io/IOUtils.hpp"
54 
55 #include "Options.hpp"
56 
57 #include <boost/filesystem.hpp>
58 
59 #include <opencv2/core/core.hpp>
60 #include <opencv2/highgui/highgui.hpp>
61 
62 using namespace lvr2;
63 using boost::filesystem::path;
64 using boost::filesystem::directory_iterator;
65 
66 bool compare_path(boost::filesystem::path p1, boost::filesystem::path p2)
67 {
68  std::string ply_file_name1 = p1.stem().string();
69  std::string number1 = ply_file_name1.substr(15);
70 
71  std::string ply_file_name2 = p2.stem().string();
72  std::string number2 = ply_file_name2.substr(15);
73 
74  std::stringstream ss1(number1);
75  std::stringstream ss2(number2);
76  int first1 = 0;
77  int second1 = 0;
78 
79  int first2 = 0;
80  int second2 = 0;
81  char dummy;
82  ss1 >> first1 >> dummy >> second1;
83  ss2 >> first2 >> dummy >> second2;
84 
85  return ((first1 << 16) + second1) < ((first2 << 16) + second2);
86 }
87 
88 bool checkPNGDir(path& dataDir, std::string number, int numExspected)
89 {
90  bool consistency = true;
91  path png_dir = dataDir/"panoramas_fixed"/("panorama_channels_"+number);
92  try
93  {
94  int numPNGs = std::count_if(
95  directory_iterator(png_dir),
96  directory_iterator(),
97  static_cast<bool(*)(const path&)>(boost::filesystem::is_regular_file) );
98 
99  if(numPNGs != numExspected)
100  {
101  consistency = false;
102  }
103  }
104  catch(boost::filesystem::filesystem_error)
105  {
106  consistency = false;
107  }
108  return consistency;
109 }
110 
111 // HyperspectralPanorama getSpectralCalibration(path& dataDir, std::string number)
112 // {
113 // HyperspectralPanorama pano;
114 // path calibrationFile = dataDir/("calibration_"+number+".txt");
115 // std::ifstream in(calibrationFile.string());
116 // if(in.good())
117 // {
118 // in >> pano.distortion(0, 0) >> pano.distortion(1, 0) >> pano.distortion(2, 0);
119 // in >> pano.rotation(0, 0) >> pano.rotation(1, 0) >> pano.rotation(2, 0);
120 // in >> pano.origin(0, 0) >> pano.origin(1, 0) >> pano.origin(2, 0);
121 // in >> pano.principal(0, 0);
122 // }
123 // else
124 // {
125 // std::cout << timestamp << "Could not open calibration file "
126 // << calibrationFile.string() << std::endl;
127 // }
128 // return pano;
129 // }
130 
131 int main( int argc, char ** argv )
132 {
134 
135  path dataDir(options.getDataDir());
136 
137  HDF5IO hdf5("hyper.h5", true);
138 
139  // Find all annotated scans and sort them
140  vector<boost::filesystem::path> annotated_scans;
141  directory_iterator end;
142  for(directory_iterator it(dataDir); it != end; ++it)
143  {
144  std::string ext = it->path().extension().string();
145  std::string stem = it->path().stem().string();
146  if(ext == ".ply" && stem.find("scan_annotated_") != string::npos)
147  {
148  annotated_scans.push_back(it->path());
149  }
150  }
151  std::sort(annotated_scans.begin(), annotated_scans.end(), compare_path);
152 
153  // Create scan data objects and add them to hdf5 file
154  int scanNr = 0;
155  for(auto it : annotated_scans)
156  {
157 
158 
159  std::string ply_file_name = it.stem().string();
160  std::string number = ply_file_name.substr(15);
161  size_t numExspectedPNGs = (size_t)options.numPanoramaImages();
162  // Check panoram dir for correct number of scans
163  if(checkPNGDir(dataDir, number, numExspectedPNGs))
164  {
165  // Read transformation
166  path matrix_file = dataDir/path("scan_" + number + "_transformation.txt");
167  std::cout << timestamp << "Reading transformation: " << matrix_file.string() << std::endl;
168  Transformd transformation = loadFromFile<double>(matrix_file.string());
169 
170  // Read scan data
171  std::cout << timestamp << "Reading scan data: " << it << std::endl;
172  ModelPtr model = ModelFactory::readModel(it.string());
173 
174  // Compute bounding box
175  PointBufferPtr pointCloud = model->m_pointCloud;
176 
177  std::cout << timestamp << "Calculating bounding box..." << std::endl;
179  floatArr points = pointCloud->getPointArray();
180  for(int i = 0; i < pointCloud->numPoints(); i++)
181  {
183  points[3 * i],
184  points[3 * i + 1],
185  points[3 * i + 2]));
186  }
187 
188  // Setup scan data object
189  ScanPtr data = ScanPtr(new Scan());
190  data->m_points = pointCloud;
191  data->m_boundingBox = bBox;
192  data->m_registration = transformation;
193 
194  std::cout << timestamp << " Adding raw scan data" << endl;
195  // Add objects to hdf5 file
196  hdf5.addRawScan(scanNr, data);
197 
198 
199  // Get hyperspectral calibration parameters
200  // HyperspectralPanorama cal = getSpectralCalibration(dataDir, number);
201  // hdf5.addHyperspectralCalibration(scanNr, cal);
202 
203  // Create "hyperspectral cube"
204  path imgFile = dataDir/"panoramas_fixed"/("panorama_channels_"+number)/"channel0.png";
205  cv::Mat img = cv::imread(imgFile.string(), cv::IMREAD_GRAYSCALE);
206 
207  size_t img_x = img.cols;
208  size_t img_y = img.rows;
209  unsigned char* cube = new unsigned char[numExspectedPNGs * img.rows * img.cols];
210  for(int i = 0; i < numExspectedPNGs; i++)
211  {
212  char buffer[256];
213  sprintf(buffer, "channel%d.png", i);
214  path imgFile = dataDir/"panoramas_fixed"/("panorama_channels_"+number)/buffer;
215  cv::Mat img = cv::imread(imgFile.string(), cv::IMREAD_GRAYSCALE);
216  memcpy(cube + i * (img_y * img_x), img.data, img_y * img_x * sizeof(unsigned char));
217  }
218 
219  char groupName[256];
220  std::vector<size_t> dim = {numExspectedPNGs, img_y, img_x};
221 
222  // Priliminary experiments showed that this chunking delivered
223  // best compression of hyperspectral image data
224  std::vector<hsize_t> chunks =
225  {options.getHSPChunk0(), options.getHSPChunk1(), options.getHSPChunk2()};
226 
227  sprintf(groupName, "/raw/spectral/position_%05d", scanNr);
228  std::cout << timestamp << "Adding spectral dataset to " << groupName << " with dims "
229  << options.getHSPChunk0() << " " << options.getHSPChunk1() << " " << options.getHSPChunk2() << endl;
230 
231  hdf5.addArray(groupName, "spectral", dim, chunks, ucharArr(cube));
232 
233 
234  scanNr++;
235  }
236  else
237  {
238  std::cout << timestamp << "Will not add data from "
239  << ply_file_name <<". Spectral data is not consistent." << std::endl;
240  }
241  }
242 
243  return 0;
244 }
245 // // Parse command line arguments
246 // hdf5tool::Options options(argc, argv);
247 
248 // std::cout << options << ::std::endl;
249 
250 // // Get directory with hyperspectral PNG files
251 // boost::filesystem::path pngPath(options.getPNGDir());
252 // boost::filesystem::directory_iterator end;
253 
254 // // Count files in directory
255 // int numPNGs = 0;
256 // for(boost::filesystem::directory_iterator it(pngPath); it != end; ++it)
257 // {
258 // std::string ext = it->path().extension().string();
259 // if(ext == ".png")
260 // {
261 // numPNGs++;
262 // }
263 // }
264 
265 // // Sort files according to channel nummer
266 // char buffer[512];
267 // std::vector<string> pngFiles(numPNGs);
268 // int channel_nr = 0;
269 // for(boost::filesystem::directory_iterator it(pngPath); it != end; ++it)
270 // {
271 // std::string ext = it->path().extension().string();
272 // if(ext == ".png")
273 // {
274 // string pngFilePath = it->path().string();
275 // string pngFileName = it->path().filename().string();
276 // sscanf(pngFileName.c_str(), "channel%d.png", &channel_nr);
277 // pngFiles[channel_nr] = pngFilePath;
278 // }
279 // }
280 
281 // // Try to open the given HDF5 file
282 // HighFive::File hdf5_file(
283 // "out.h5",
284 // HighFive::File::ReadWrite | HighFive::File::Create | HighFive::File::Truncate);
285 
286 // if (!hdf5_file.isValid())
287 // {
288 // throw "Could not open file.";
289 // }
290 
291 // // Generate high level structure of nested groups for raw scan and spectral
292 // // data within the hdf5 file
293 // HighFive::Group raw_data_group = hdf5_file.createGroup("/raw_data");
294 // HighFive::Group pose_group = hdf5_file.createGroup("raw_data/pose001");
295 // HighFive::Group spectral_group = hdf5_file.createGroup("raw_data/pose001/spectral");
296 // HighFive::Group scan_group = hdf5_file.createGroup("raw_data/pose001/scan");
297 
298 // // Write information about number of channels and sprectral range
299 // int numChannels = 150;
300 // int minSpectral = 400;
301 // int maxSpectral = 1000;
302 // spectral_group.createDataSet<int>("numChannels", HighFive::DataSpace::From(numChannels)).write(numChannels);
303 // spectral_group.createDataSet<int>("minSpectral", HighFive::DataSpace::From(minSpectral)).write(minSpectral);
304 // spectral_group.createDataSet<int>("maxSpectral", HighFive::DataSpace::From(maxSpectral)).write(maxSpectral);
305 
306 // // Create groups for the spectral pngs if the single channles
307 // int i = 0;
308 // for(auto it : pngFiles)
309 // {
310 // // Parse channel name
311 // sprintf(buffer, "channel%03d", i);
312 // string group_name = "raw_data/pose001/spectral/" + string(buffer);
313 
314 // // Create group
315 // HighFive::Group channel_group = hdf5_file.createGroup(group_name);
316 
317 // // Read png images and write them into the created group
318 // cv::Mat image = cv::imread(it, cv::IMREAD_GRAYSCALE);
319 
320 // int w = image.cols;
321 // int h = image.rows;
322 
323 // channel_group.createDataSet<int>("width", HighFive::DataSpace::From(w)).write(w);
324 // channel_group.createDataSet<int>("height", HighFive::DataSpace::From(h)).write(h);
325 // H5IMmake_image_8bit(channel_group.getId(), "spectral_image", w, h, image.data);
326 // i++;
327 // }
328 
329 // // Read .ply file with scan data
330 // ModelPtr model = ModelFactory::readModel(options.getPLYFile());
331 // PointBufferPtr point_buffer = model->m_pointCloud;
332 // size_t n = point_buffer->numPoints();
333 // floatArr points = point_buffer->getPointArray();
334 
335 // // Write scan data to group
336 // scan_group.createDataSet<int>("numPoints", HighFive::DataSpace::From(n)).write(n);
337 // scan_group.createDataSet<float>("points", HighFive::DataSpace(n * 3)).write(points.get());
338 
339 // size_t n_spec;
340 // unsigned n_channels;
341 // floatArr spec = point_buffer->getFloatArray("spectral_channels", n_spec, n_channels);
342 
343 // if (n_spec)
344 // {
345 // HighFive::Group pointclouds_group = hdf5_file.createGroup("/pointclouds");
346 // HighFive::Group cloud001_group = hdf5_file.createGroup("pointclouds/cloud001");
347 // HighFive::Group cloud001_points_group = hdf5_file.createGroup("pointclouds/cloud001/points");
348 // HighFive::Group cloud001_spectral_group = hdf5_file.createGroup("pointclouds/cloud001/spectralChannels");
349 
350 // cloud001_points_group.createDataSet<int>("numPoints", HighFive::DataSpace::From(n_spec)).write(n_spec);
351 // cloud001_points_group.createDataSet<float>("points", HighFive::DataSpace(n_spec * 3)).write(points.get());
352 
353 // cloud001_spectral_group.createDataSet<int>("numPoints", HighFive::DataSpace::From(n_spec)).write(n_spec);
354 // cloud001_spectral_group.createDataSet<int>("numChannels", HighFive::DataSpace::From(n_channels)).write(n_channels);
355 // cloud001_spectral_group.createDataSet<int>("minSpectral", HighFive::DataSpace::From(minSpectral)).write(minSpectral);
356 // cloud001_spectral_group.createDataSet<int>("maxSpectral", HighFive::DataSpace::From(maxSpectral)).write(maxSpectral);
357 // cloud001_spectral_group.createDataSet<float>("spectralChannels", HighFive::DataSpace(n_spec * n_channels)).write(spec.get());
358 // }
359 
360 // std::cout << "Done" << std::endl;
361 
lvr2::floatArr
boost::shared_array< float > floatArr
Definition: DataStruct.hpp:133
BaseVector.hpp
Options.hpp
lvr2::BaseVector< float >
HDF5IO.hpp
lvr2::HDF5IO::addArray
void addArray(std::string groupName, std::string datasetName, unsigned int size, boost::shared_array< T > data)
ColorMap.hpp
lvr2::Transformd
Transform< double > Transformd
4x4 double precision transformation matrix
Definition: MatrixTypes.hpp:71
lvr2::PointBufferPtr
std::shared_ptr< PointBuffer > PointBufferPtr
Definition: PointBuffer.hpp:130
IOUtils.hpp
lvr2::Scan
Definition: ScanTypes.hpp:24
options
const kaboom::Options * options
Definition: src/tools/lvr2_kaboom/Main.cpp:45
lvr2::timestamp
static Timestamp timestamp
A global time stamp object for program runtime measurement.
Definition: Timestamp.hpp:116
MatrixTypes.hpp
compare_path
bool compare_path(boost::filesystem::path p1, boost::filesystem::path p2)
Definition: HDF5Tool.cpp:66
lvr2::HDF5IO::addRawScan
void addRawScan(int nr, ScanPtr scan)
Definition: HDF5IO.cpp:799
lvr2::BoundingBox
A dynamic bounding box class.
Definition: BoundingBox.hpp:49
argc
int argc
Definition: tests_high_five_parallel.cpp:27
lvr2::BoundingBox::expand
void expand(T v)
Expands the bounding box if the given Vector v} is outside the current volume.
hdf5tool::Options
A class to parse the program options for the reconstruction executable.
Definition: src/tools/lvr2_hdf5_builder/Options.hpp:59
lvr2::ucharArr
boost::shared_array< unsigned char > ucharArr
Definition: DataStruct.hpp:137
Matrix4.hpp
lvr2
Definition: BaseBufferManipulators.hpp:39
lvr2::ModelPtr
std::shared_ptr< Model > ModelPtr
Definition: Model.hpp:80
lvr2::HDF5IO
Definition: descriptions/HDF5IO.hpp:13
Timestamp.hpp
lvr2::ModelFactory::readModel
static ModelPtr readModel(std::string filename)
Definition: ModelFactory.cpp:65
ModelFactory.hpp
checkPNGDir
bool checkPNGDir(path &dataDir, std::string number, int numExspected)
Definition: HDF5Tool.cpp:88
main
int main(int argc, char **argv)
Definition: HDF5Tool.cpp:131
argv
char ** argv
Definition: tests_high_five_parallel.cpp:28
lvr2::ScanPtr
std::shared_ptr< Scan > ScanPtr
Shared pointer to scans.
Definition: ScanTypes.hpp:98


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 Wed Mar 2 2022 00:37:23