HDF5Kernel.cpp
Go to the documentation of this file.
5 
6 namespace lvr2
7 {
8 
9 HDF5Kernel::HDF5Kernel(const std::string& rootFile) : FileKernel(rootFile)
10 {
11  m_hdf5File = hdf5util::open(rootFile);
13 }
14 
16  const std::string &group,
17  const std::string &container,
18  const MeshBufferPtr &buffer) const
19 {
20 
21 }
22 
24  const std::string &group,
25  const std::string &container,
26  const PointBufferPtr &buffer) const
27 {
29 
30  for(auto elem : *buffer)
31  {
32  this->template save(g, elem.first, elem.second);
33  }
34 }
35 
36 
38  const std::string &groupName,
39  const std::string &datasetName,
40  const cv::Mat &img) const
41 {
42  if(m_hdf5File && m_hdf5File->isValid())
43  {
44  HighFive::Group group = hdf5util::getGroup(m_hdf5File, groupName, true);
45 
46  int w = img.cols;
47  int h = img.rows;
48  const char* interlace = "INTERLACE_PIXEL";
49 
50  // TODO: need to remove dataset if exists because of H5IMmake_image_8bit. do it better
51 
52  if(img.type() == CV_8U)
53  {
54  if(group.exist(datasetName))
55  {
56  H5Ldelete(group.getId(), datasetName.data(), H5P_DEFAULT);
57  }
58  H5IMmake_image_8bit(group.getId(), datasetName.c_str(), w, h, img.data);
59  }
60  else if(img.type() == CV_8UC3)
61  {
62  if(group.exist(datasetName))
63  {
64  H5Ldelete(group.getId(), datasetName.data(), H5P_DEFAULT);
65  }
66  // bgr -> rgb?
67  H5IMmake_image_24bit(group.getId(), datasetName.c_str(), w, h, interlace, img.data);
68  }
69  else
70  {
71  // std::cout << "[Hdf5IO - ImageIO] WARNING: OpenCV type not implemented -> "
72  // << img.type() << ". Saving image as data blob." << std::endl;
73 
74  // Couldnt write as H5Image, write as blob
75 
76  std::vector<size_t> dims = {static_cast<size_t>(img.rows), static_cast<size_t>(img.cols)};
77  std::vector<hsize_t> chunkSizes = {static_cast<hsize_t>(img.rows), static_cast<hsize_t>(img.cols)};
78 
79  if(img.channels() > 1)
80  {
81  dims.push_back(img.channels());
82  chunkSizes.push_back(img.channels());
83  }
84 
85  HighFive::DataSpace dataSpace(dims);
87 
88  // if(m_hdf5File->m_chunkSize)
89  // {
90  // for(size_t i = 0; i < chunkSizes.size(); i++)
91  // {
92  // if(chunkSizes[i] > dims[i])
93  // {
94  // chunkSizes[i] = dims[i];
95  // }
96  // }
97  // properties.add(HighFive::Chunking(chunkSizes));
98  // }
99  // if(m_hdf5File->m_compress)
100  // {
101  // properties.add(HighFive::Deflate(9));
102  // }
103 
104  // Single Channel Type
105  const int SCTYPE = img.type() % 8;
106 
107 
108  if(SCTYPE == CV_8U)
109  {
110  std::unique_ptr<HighFive::DataSet> dataset = hdf5util::createDataset<unsigned char>(
111  group, datasetName, dataSpace, properties
112  );
113  const unsigned char* ptr = reinterpret_cast<unsigned char*>(img.data);
114  dataset->write(ptr);
115  }
116  else if(SCTYPE == CV_8S)
117  {
118  std::unique_ptr<HighFive::DataSet> dataset = hdf5util::createDataset<char>(
119  group, datasetName, dataSpace, properties
120  );
121  const char* ptr = reinterpret_cast<char*>(img.data);
122  dataset->write(ptr);
123  }
124  else if(SCTYPE == CV_16U)
125  {
126  std::unique_ptr<HighFive::DataSet> dataset = hdf5util::createDataset<unsigned short>(
127  group, datasetName, dataSpace, properties
128  );
129  const unsigned short* ptr = reinterpret_cast<unsigned short*>(img.data);
130  dataset->write(ptr);
131  }
132  else if(SCTYPE == CV_16S)
133  {
134  std::unique_ptr<HighFive::DataSet> dataset = hdf5util::createDataset<short>(
135  group, datasetName, dataSpace, properties
136  );
137  const short* ptr = reinterpret_cast<short*>(img.data);
138  dataset->write(ptr);
139  }
140  else if(SCTYPE == CV_32S)
141  {
142  std::unique_ptr<HighFive::DataSet> dataset = hdf5util::createDataset<int>(
143  group, datasetName, dataSpace, properties
144  );
145  const int* ptr = reinterpret_cast<int*>(img.data);
146  dataset->write(ptr);
147  }
148  else if(SCTYPE == CV_32F)
149  {
150  std::unique_ptr<HighFive::DataSet> dataset = hdf5util::createDataset<float>(
151  group, datasetName, dataSpace, properties
152  );
153  const float* ptr = reinterpret_cast<float*>(img.data);
154  dataset->write(ptr);
155  }
156  else if(SCTYPE == CV_64F)
157  {
158  std::unique_ptr<HighFive::DataSet> dataset = hdf5util::createDataset<double>(
159  group, datasetName, dataSpace, properties
160  );
161  const double* ptr = reinterpret_cast<double*>(img.data);
162  dataset->write(ptr);
163  }
164  else
165  {
166  std::cout << timestamp << "HDF5Kernel:SaveImage: Warning: unknown opencv type " << img.type() << std::endl;
167  }
168  }
169  m_hdf5File->flush();
170 
171  }
172  else
173  {
174  throw std::runtime_error("[Hdf5IO - ChannelIO]: Hdf5 file not open.");
175  }
176 }
177 
179  const std::string &group,
180  const std::string &metaName,
181  const YAML::Node &node) const
182 {
183  cout << "SaveMetaYAML: " << group << " / " << metaName << std::endl;
185 
186  if(hg.isValid() && node["sensor_type"] )
187  {
188  std::string sensor_type = node["sensor_type"].as<std::string>();
189  if(sensor_type == "ScanPosition")
190  {
191 
193  }
194  else if(sensor_type == "Scan")
195  {
196  m_metaDescription->saveScan(hg, node);
197  }
198  else if(sensor_type == "ScanCamera")
199  {
201  }
202  else if(sensor_type == "ScanProject")
203  {
205  }
206  else if(sensor_type == "HyperspectralCamera")
207  {
209  }
210  else if(sensor_type == "HyperspectralPanoramaChannel")
211  {
213  }
214  else
215  {
216  std::cout << timestamp
217  << "HDF5Kernel::SaveMetaYAML(): Warning: Sensor type '"
218  << sensor_type << "' is not defined." << std::endl;
219  }
220  m_hdf5File->flush();
221  }
222 }
223 
225  const std::string &group,
226  const std::string container) const
227 {
228  return MeshBufferPtr(new MeshBuffer);
229 }
230 
232  const std::string &group,
233  const std::string &container) const
234 {
236  PointBufferPtr ret;
237 
238  // check if flags are correct
239  // if(!isPointCloud(group) )
240  // {
241  // std::cout << "[Hdf5IO - PointCloudIO] WARNING: flags of " << group.getId() << " are not correct." << std::endl;
242  // return ret;
243  // }
244 
245  for(auto name : g.listObjectNames() )
246  {
247  std::unique_ptr<HighFive::DataSet> dataset;
248 
249  try {
250  dataset = std::make_unique<HighFive::DataSet>(
251  g.getDataSet(name)
252  );
253  } catch(HighFive::DataSetException& ex) {
254 
255  }
256 
257  if(dataset)
258  {
259  // name is dataset
260  boost::optional<PointBuffer::val_type> opt_vchannel
261  = this->template load<PointBuffer::val_type>(group, name);
262 
263  if(opt_vchannel)
264  {
265  if(!ret)
266  {
267  ret.reset(new PointBuffer);
268  }
269  ret->insert({
270  name,
271  *opt_vchannel
272  });
273  }
274 
275  }
276 
277  }
278 
279  return ret;
280 }
281 
282 boost::optional<cv::Mat> HDF5Kernel::loadImage(
283  const std::string &groupName,
284  const std::string &datasetName) const
285 {
286  boost::optional<cv::Mat> ret;
287 
288  if(m_hdf5File && m_hdf5File->isValid())
289  {
290  HighFive::Group group = hdf5util::getGroup(m_hdf5File, groupName);
291  if(group.exist(datasetName))
292  {
293  if(H5IMis_image(group.getId(), datasetName.c_str()))
294  {
295  long long unsigned int w, h, planes;
296  long long int npals;
297  char interlace[256];
298 
299  int err = H5IMget_image_info(group.getId(), datasetName.c_str(), &w, &h, &planes, interlace, &npals);
300 
301  if(planes == 1) {
302  // 1 channel image
303  ret = cv::Mat(h, w, CV_8U);
304  H5IMread_image(group.getId(), datasetName.c_str(), ret->data);
305  } else if(planes == 3) {
306  // 3 channel image
307  ret = cv::Mat(h, w, CV_8UC3);
308  H5IMread_image(group.getId(), datasetName.c_str(), ret->data);
309  } else {
310  // ERROR
311  }
312  } else {
313  // data blob
314  // std::cout << "[Hdf5 - ImageIO] WARNING: Dataset is not formatted as image. Reading data as blob." << std::endl;
315  // Data is not an image, load as blob
316 
317  HighFive::DataSet dataset = group.getDataSet(datasetName);
318  std::vector<size_t> dims = dataset.getSpace().getDimensions();
319  HighFive::DataType dtype = dataset.getDataType();
320 
322  ret = createMat<unsigned char>(dims);
323  dataset.read(reinterpret_cast<unsigned char*>(ret->data));
324  } else if(dtype == HighFive::AtomicType<char>()) {
325  ret = createMat<char>(dims);
326  dataset.read(reinterpret_cast<char*>(ret->data));
327  } else if(dtype == HighFive::AtomicType<unsigned short>()) {
328  ret = createMat<unsigned short>(dims);
329  dataset.read(reinterpret_cast<unsigned short*>(ret->data));
330  } else if(dtype == HighFive::AtomicType<short>()) {
331  ret = createMat<short>(dims);
332  dataset.read(reinterpret_cast<short*>(ret->data));
333  } else if(dtype == HighFive::AtomicType<int>()) {
334  ret = createMat<int>(dims);
335  dataset.read(reinterpret_cast<int*>(ret->data));
336  } else if(dtype == HighFive::AtomicType<float>()) {
337  ret = createMat<float>(dims);
338  dataset.read(reinterpret_cast<float*>(ret->data));
339  } else if(dtype == HighFive::AtomicType<double>()) {
340  ret = createMat<double>(dims);
341  dataset.read(reinterpret_cast<double*>(ret->data));
342  } else {
343  std::cout << timestamp << "HDF5Kernel::loadImage(): Warning: Could'nt load blob. Datatype unkown." << std::endl;
344  }
345  }
346  }
347 
348  }
349  else
350  {
351  throw std::runtime_error("[Hdf5 - ImageIO]: Hdf5 file not open.");
352  }
353 
354 
355  return ret;
356 }
357 
358 void HDF5Kernel::loadMetaData(const YAML::Node& node)
359 {
360 
361 }
362 
364  const std::string &group,
365  const std::string &container,
366  YAML::Node& node) const
367 {
369 
370  if(hg.isValid() && node["sensor_type"] )
371  {
372  YAML::Node n;
373  std::string sensor_type = node["sensor_type"].as<std::string>();
374  if(sensor_type == "ScanPosition")
375  {
377  }
378  else if(sensor_type == "Scan")
379  {
380  n = m_metaDescription->scan(hg);
381  }
382  else if(sensor_type == "ScanCamera")
383  {
384  n = m_metaDescription->scanCamera(hg);
385  }
386  else if(sensor_type == "ScanProject")
387  {
389  }
390  else if(sensor_type == "HyperspectralCamera")
391  {
393  }
394  else if(sensor_type == "HyperspectralPanoramaChannel")
395  {
397  }
398  else
399  {
400  std::cout << timestamp
401  << "HDF5Kernel::LoadMetaYAML(): Warning: Sensor type '"
402  << sensor_type << "' is not defined." << std::endl;
403  }
404  node = n;
405  }
406  else
407  {
408  std::cout << timestamp
409  << "HDF5Kernel::loadMetaYAML(): Warning: Sensor type field missing."
410  << std::endl;
411  }
412 }
413 
415  const std::string &group,
416  const std::string &container,
417  std::vector<size_t> &dims) const
418 {
419  return this->template loadArray<unsigned char>(group, container, dims);
420 }
421 
423  const std::string &group,
424  const std::string &container,
425  std::vector<size_t> &dims) const
426 {
427  return this->template loadArray<float>(group, container, dims);
428 }
429 
431  const std::string &group,
432  const std::string &container,
433  std::vector<size_t> &dims) const
434 {
435  return this->template loadArray<double>(group, container, dims);
436 }
437 
439  const std::string &groupName,
440  const std::string &datasetName,
441  const std::vector<size_t> &dimensions,
442  const boost::shared_array<float> &data) const
443 {
444  this->template saveArray<float>(groupName, datasetName, dimensions, data);
445 }
446 
448  const std::string &groupName, const std::string &datasetName,
449  const std::vector<size_t> &dimensions,
450  const boost::shared_array<double> &data) const
451 {
452  this->template saveArray<double>(groupName, datasetName, dimensions, data);
453 }
454 
456  const std::string &groupName, const std::string &datasetName,
457  const std::vector<size_t> &dimensions,
458  const boost::shared_array<unsigned char> &data) const
459 {
460  this->template saveArray<unsigned char>(groupName, datasetName, dimensions, data);
461 }
462 
463 bool HDF5Kernel::exists(const std::string &group) const
464 {
465  return hdf5util::exist(m_hdf5File, group);
466 }
467 
468 bool HDF5Kernel::exists(const std::string &group, const std::string &container) const
469 {
471  return hdf5util::exist(g, container);
472 }
473 
474 void HDF5Kernel::subGroupNames(const std::string &group, std::vector<string> &subGroupNames) const
475 {
476 
478  subGroupNames = h5Group.listObjectNames();
479 }
480 
481 void HDF5Kernel::subGroupNames(const std::string &group, const std::regex &filter, std::vector<string> &subGroupNames) const
482 {
483 
484 }
485 
486 bool HDF5Kernel::getChannel(const std::string group, const std::string name, FloatChannelOptional& channel) const
487 {
488  return getChannel<float>(group, name, channel);
489 }
490 
491 
492 bool HDF5Kernel::getChannel(const std::string group, const std::string name, IndexChannelOptional& channel) const
493 {
494  return getChannel<unsigned int>(group, name, channel);
495 }
496 
497 
498 bool HDF5Kernel::getChannel(const std::string group, const std::string name, UCharChannelOptional& channel) const
499 {
500  return getChannel<unsigned char>(group, name, channel);
501 }
502 
503 
504 bool HDF5Kernel::addChannel(const std::string group, const std::string name, const FloatChannel& channel) const
505 {
506  return addChannel<float>(group, name, channel);
507 }
508 
509 
510 bool HDF5Kernel::addChannel(const std::string group, const std::string name, const IndexChannel& channel) const
511 {
512  return addChannel<unsigned int>(group, name, channel);
513 }
514 
515 
516 bool HDF5Kernel::addChannel(const std::string group, const std::string name, const UCharChannel& channel) const
517 {
518  return addChannel<unsigned char>(group, name, channel);
519 }
520 
521 } // namespace lvr2
DataSpace getSpace() const
getSpace
A class to handle point information with an arbitrarily large number of attribute channels...
Definition: PointBuffer.hpp:51
virtual void saveMeshBuffer(const std::string &group, const std::string &container, const MeshBufferPtr &buffer) const
Definition: HDF5Kernel.cpp:15
void read(T &array) const
virtual void saveScan(HighFive::Group &g, const YAML::Node &h) const =0
Exception specific to HighFive DataSet interface.
std::shared_ptr< MeshBuffer > MeshBufferPtr
Definition: MeshBuffer.hpp:217
virtual void saveScanCamera(HighFive::Group &g, const YAML::Node &n) const =0
virtual void saveHyperspectralCamera(HighFive::Group &g, const YAML::Node &n) const =0
virtual doubleArr loadDoubleArray(const std::string &group, const std::string &container, std::vector< size_t > &dims) const
Definition: HDF5Kernel.cpp:430
hid_t getId() const
getId
void loadMetaData(const YAML::Node &node)
Definition: HDF5Kernel.cpp:358
virtual YAML::Node scan(const HighFive::Group &g) const =0
virtual void saveMetaYAML(const std::string &group, const std::string &metaName, const YAML::Node &node) const
Definition: HDF5Kernel.cpp:178
static Timestamp timestamp
A global time stamp object for program runtime measurement.
Definition: Timestamp.hpp:116
std::shared_ptr< HighFive::File > m_hdf5File
Definition: HDF5Kernel.hpp:246
virtual void saveDoubleArray(const std::string &groupName, const std::string &datasetName, const std::vector< size_t > &dimensions, const boost::shared_array< double > &data) const
Definition: HDF5Kernel.cpp:447
virtual void saveImage(const std::string &group, const std::string &container, const cv::Mat &image) const
Definition: HDF5Kernel.cpp:37
boost::shared_array< double > doubleArr
Definition: DataStruct.hpp:134
virtual void savePointBuffer(const std::string &group, const std::string &container, const PointBufferPtr &buffer) const
Definition: HDF5Kernel.cpp:23
bool getChannel(const std::string group, const std::string name, FloatChannelOptional &channel) const
getChannel Reads a float attribute channel in the given group with the given name ...
Definition: HDF5Kernel.cpp:486
boost::shared_array< unsigned char > ucharArr
Definition: DataStruct.hpp:137
virtual YAML::Node scanCamera(const HighFive::Group &g) const =0
virtual void subGroupNames(const std::string &group, std::vector< string > &subGroupNames) const
Definition: HDF5Kernel.cpp:474
UCharChannel::Optional UCharChannelOptional
Definition: Channel.hpp:96
std::shared_ptr< PointBuffer > PointBufferPtr
virtual PointBufferPtr loadPointBuffer(const std::string &group, const std::string &container) const
Definition: HDF5Kernel.cpp:231
virtual YAML::Node scanProject(const HighFive::Group &g) const =0
bool isValid() const
isValid
virtual YAML::Node hyperspectralPanoramaChannel(const HighFive::Group &g) const =0
virtual boost::optional< cv::Mat > loadImage(const std::string &group, const std::string &container) const
Definition: HDF5Kernel.cpp:282
bool exist(const std::string &node_name) const
check a dataset or group exists in the current node / group
DataSet getDataSet(const std::string &dataset_name, const DataSetAccessProps &accessProps=DataSetAccessProps()) const
get an existing dataset in the current file
create an HDF5 DataType from a C++ type
Definition: H5DataType.hpp:41
HDF5Kernel()=delete
DataType getDataType() const
getDataType
virtual void loadMetaYAML(const std::string &group, const std::string &container, YAML::Node &node) const
Definition: HDF5Kernel.cpp:363
virtual bool exists(const std::string &group) const
Definition: HDF5Kernel.cpp:463
boost::shared_array< float > floatArr
Definition: DataStruct.hpp:133
virtual YAML::Node scanPosition(const HighFive::Group &g) const =0
HDF5 Data Type.
Definition: H5DataType.hpp:21
void filter(lvr2::PointBufferPtr &cloud, lvr2::indexArray &inlier, size_t j)
FloatChannel::Optional FloatChannelOptional
Definition: Channel.hpp:88
virtual floatArr loadFloatArray(const std::string &group, const std::string &container, std::vector< size_t > &dims) const
Definition: HDF5Kernel.cpp:422
virtual ucharArr loadUCharArray(const std::string &group, const std::string &container, std::vector< size_t > &dims) const
Definition: HDF5Kernel.cpp:414
virtual void saveFloatArray(const std::string &groupName, const std::string &datasetName, const std::vector< size_t > &dimensions, const boost::shared_array< float > &data) const
Definition: HDF5Kernel.cpp:438
virtual YAML::Node hyperspectralCamera(const HighFive::Group &g) const =0
virtual MeshBufferPtr loadMeshBuffer(const std::string &group, const std::string container) const
Definition: HDF5Kernel.cpp:224
IndexChannel::Optional IndexChannelOptional
Definition: Channel.hpp:100
bool addChannel(const std::string group, const std::string name, const AttributeChannel< T > &channel) const
virtual void saveUCharArray(const std::string &groupName, const std::string &datasetName, const std::vector< size_t > &dimensions, const boost::shared_array< unsigned char > &data) const
Definition: HDF5Kernel.cpp:455
virtual void saveScanPosition(HighFive::Group &g, const YAML::Node &n) const =0
HDF5MetaDescriptionBase * m_metaDescription
Definition: HDF5Kernel.hpp:248
virtual void saveHyperspectralPanoramaChannel(HighFive::Group &g, const YAML::Node &n) const =0
std::vector< std::string > listObjectNames() const
list all leaf objects name of the node / group
std::shared_ptr< HighFive::File > open(const std::string &filename)
Definition: Hdf5Util.cpp:202
The MeshBuffer Mesh representation for I/O modules.
Definition: MeshBuffer.hpp:41
std::vector< size_t > getDimensions() const
getDimensions
HighFive::Group getGroup(std::shared_ptr< HighFive::File > hdf5_file, const std::string &groupName, bool create=true)
Definition: Hdf5Util.cpp:58
void save(std::string groupName, std::string datasetName, const Channel< T > &channel) const
bool exist(std::shared_ptr< HighFive::File > hdf5_file, const std::string &groupName)
Definition: Hdf5Util.cpp:136
virtual void saveScanProject(HighFive::Group &g, const YAML::Node &n) const =0


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