utest/ui/IO.cpp
Go to the documentation of this file.
1 #include "../utest.h"
2 
3 using namespace std;
4 using namespace PointMatcherSupport;
5 
6 //---------------------------
7 // Tests for IO
8 //---------------------------
9 
10 TEST(IOTest, loadYaml)
11 {
12 
13  // Test loading configuration files for data filters
14  std::ifstream ifs0((dataPath + "default-convert.yaml").c_str());
15  EXPECT_NO_THROW(PM::DataPointsFilters filters(ifs0));
16 
17  // Test loading configuration files for ICP
18  PM::ICP icp;
19 
20  std::ifstream ifs1((dataPath + "default.yaml").c_str());
21  EXPECT_NO_THROW(icp.loadFromYaml(ifs1));
22 
23  std::ifstream ifs2((dataPath + "unit_tests/badIcpConfig_InvalidParameter.yaml").c_str());
25 
26  std::ifstream ifs3((dataPath + "unit_tests/badIcpConfig_InvalidModuleType.yaml").c_str());
28 }
29 
30 TEST(IOTest, loadCSV)
31 {
32  typedef PointMatcherIO<float> IO;
33  std::istringstream is;
34  std::ostringstream os;
35  DP pts;
36 
37  // too many elements on a line
38  os.clear();
39  os.str("");
40  os <<
41  "x, y\n"
42  "1, 2\n"
43  "1, 2, 3\n"
44  "1, 2\n"
45  ;
46 
47  is.clear();
48  is.str(os.str());
49  EXPECT_THROW(IO::loadCSV(is), runtime_error);
50 
51  // not enough elements on a line
52  os.clear();
53  os.str("");
54  os <<
55  "x, y\n"
56  "1, 2\n"
57  "1, \n"
58  "1, 2\n"
59  ;
60 
61  is.clear();
62  is.str(os.str());
63  EXPECT_THROW(IO::loadCSV(is), runtime_error);
64 
65  // 2D data
66  os.clear();
67  os.str("");
68  os <<
69  "x, y\n"
70  "1, 2\n"
71  "1, 2\n"
72  "8, 2\n"
73  "1, 2\n"
74  ;
75 
76  is.clear();
77  is.str(os.str());
78  pts = IO::loadCSV(is);
79  EXPECT_EQ(4u, pts.getNbPoints());
80  EXPECT_EQ(2u, pts.getEuclideanDim());
81  EXPECT_EQ(0u, pts.getDescriptorDim());
82  EXPECT_EQ(0u, pts.getTimeDim());
83  EXPECT_EQ(8.0, pts.features(0,2));
84 
85  // 3D data
86  os.clear();
87  os.str("");
88  os <<
89  "x, y, z\n"
90  "1, 2, 3\n"
91  "1, 2, 3\n"
92  "8, 2, 3\n"
93  "1, 2, 3\n"
94  ;
95 
96  is.clear();
97  is.str(os.str());
98  pts = IO::loadCSV(is);
99  EXPECT_EQ(4u, pts.getNbPoints());
100  EXPECT_EQ(3u, pts.getEuclideanDim());
101  EXPECT_EQ(0u, pts.getDescriptorDim());
102  EXPECT_EQ(0u, pts.getTimeDim());
103  EXPECT_EQ(8.0, pts.features(0,2));
104 
105  // 3D data with unknown descriptor
106  os.clear();
107  os.str("");
108  os <<
109  "x, y, z, dummy\n"
110  "1, 2, 3, 4\n"
111  "1, 2, 3, 4\n"
112  "8, 2, 3, 4\n"
113  "1, 2, 3, 4\n"
114  ;
115 
116  is.clear();
117  is.str(os.str());
118  pts = IO::loadCSV(is);
119  EXPECT_EQ(4u, pts.getNbPoints());
120  EXPECT_EQ(3u, pts.getEuclideanDim());
121  EXPECT_EQ(1u, pts.getDescriptorDim());
122  EXPECT_EQ(0u, pts.getTimeDim());
123  EXPECT_TRUE(pts.descriptorExists("dummy"));
124 
125  // 3D data with known descriptor
126  os.clear();
127  os.str("");
128  os <<
129  "x, y, z, nx, ny, nz\n"
130  "1, 2, 3, 4, 5, 6\n"
131  "1, 2, 3, 4, 5, 6\n"
132  "8, 2, 3, 4, 5, 6\n"
133  "1, 2, 3, 4, 5, 6\n"
134  ;
135 
136  is.clear();
137  is.str(os.str());
138  pts = IO::loadCSV(is);
139  EXPECT_EQ(4u, pts.getNbPoints());
140  EXPECT_EQ(3u, pts.getEuclideanDim());
141  EXPECT_EQ(3u, pts.getDescriptorDim());
143  EXPECT_EQ(0u, pts.getTimeDim());
144  EXPECT_TRUE(pts.descriptorExists("normals"));
145 
146  // csv with time
147  int64_t time0 = 1410264593275569438;
148  int64_t time1 = 1410264593325569391;
149  int64_t time2 = 1410264593425569295;
150  int64_t time3 = 1410264593522569417;
151 
152  os.clear();
153  os.str("");
154  os <<
155  "x, y, z, time\n"
156  "1, 1, 1, " << time0 << "\n"
157  "2, 1, 1, " << time1 << "\n"
158  "3, 1, 1, " << time2 << "\n"
159  "4, 1, 1, " << time3 << "\n"
160  ;
161 
162  is.clear();
163  is.str(os.str());
164 
165  pts = IO::loadCSV(is);
166  EXPECT_EQ(4u, pts.getNbPoints());
167  EXPECT_EQ(3u, pts.getEuclideanDim());
168  EXPECT_EQ(0u, pts.getDescriptorDim());
169  EXPECT_EQ(1u, pts.getTimeDim());
170  EXPECT_EQ(time3, pts.times(0,3));
171 
172  //cout << "dim: " << pts.getEuclideanDim() << endl;
173  //cout << "nb pts: " << pts.getNbPoints() << endl;
174  //cout << "desc dim: " << pts.getDescriptorDim() << endl;
175  //cout << "time dim: " << pts.getTimeDim() << endl;
176 
177 
178 
179 }
180 
181 TEST(IOTest, loadPLY)
182 {
183  typedef PointMatcherIO<float> IO;
184  std::istringstream is;
185 
186  is.str(
187  ""
188  );
189 
190  EXPECT_THROW(IO::loadPLY(is), runtime_error);
191 
192  is.clear();
193  is.str(
194  "ply\n"
195  "format binary_big_endian 1.0\n"
196  );
197 
198  EXPECT_THROW(IO::loadPLY(is), runtime_error);
199 
200  is.clear();
201  is.str(
202  "ply\n"
203  "format ascii 2.0\n"
204  );
205 
206  EXPECT_THROW(IO::loadPLY(is), runtime_error);
207 
208  is.clear();
209  is.str(
210  "ply\n"
211  "format ascii 1.0\n"
212  );
213 
214  EXPECT_THROW(IO::loadPLY(is), runtime_error);
215 
216  is.clear();
217  is.str(
218  "ply\n"
219  "format ascii 1.0\n"
220  "element vertex 5\n"
221  "\n" //empty line
222  "property float z\n" // wrong order
223  "property float y\n"
224  "property float x\n"
225  "property float grrrr\n" //unknown property
226  "property float nz\n" // wrong order
227  "property float ny\n"
228  "property float nx\n"
229  "end_header\n"
230  "3 2 1 99 33 22 11\n"
231  "3 2 1 99 33 22 11\n"
232  "\n" //empty line
233  "3 2 1 99 33 22 11 3 2 1 99 33 22 11\n" // no line break
234  "3 2 1 99 33 22 11\n"
235 
236  );
237 
238  DP pointCloud = IO::loadPLY(is);
239 
240  // Confirm sizes and dimensions
241  EXPECT_TRUE(pointCloud.features.cols() == 5);
242  EXPECT_TRUE(pointCloud.features.rows() == 4); //x, y, z, pad
243  EXPECT_TRUE(pointCloud.descriptors.cols() == 5);
244  EXPECT_TRUE(pointCloud.descriptors.rows() == 4);//nx, ny, nz, grrrr
245 
246  // Random value check
247  EXPECT_TRUE(pointCloud.features(0, 0) == 1);
248  EXPECT_TRUE(pointCloud.features(2, 2) == 3);
249  EXPECT_TRUE(pointCloud.descriptors(1, 1) == 22);
250  EXPECT_TRUE(pointCloud.descriptors(2, 4) == 33);
251 
252 }
253 
254 
255 TEST(IOTest, loadPCD)
256 {
257  typedef PointMatcherIO<float> IO;
258  std::istringstream is;
259 
260  // Empty file
261  is.str(
262  ""
263  );
264 
265  EXPECT_THROW(IO::loadPCD(is), runtime_error);
266 
267  // Partial header
268  is.clear();
269  is.str(
270  "# .PCD v.7 - Point Cloud Data file format\n"
271  "VERSION .7\n"
272  );
273 
274  EXPECT_THROW(IO::loadPCD(is), runtime_error);
275 
276  // Missing data
277  is.clear();
278  is.str(
279  "# .PCD v.7 - Point Cloud Data file format\n"
280  "VERSION .7\n"
281  "FIELDS x y z\n"
282  "SIZE 4 4 4\n"
283  "TYPE F F F\n"
284  "COUNT 1 1 1\n"
285  "WIDTH 18\n"
286  "HEIGHT 1\n"
287  "VIEWPOINT 0 0 0 1 0 0 0\n"
288  "POINTS 18\n"
289  "DATA ascii\n"
290  );
291 
292  EXPECT_THROW(IO::loadPCD(is), runtime_error);
293 
294 
295  is.clear();
296  is.str(
297  "# .PCD v.7 - Point Cloud Data file format\n"
298  "VERSION .7\n"
299  "FIELDS x y z grrr\n"
300  "SIZE 4 4 4 4\n"
301  "TYPE F F F F\n"
302  "COUNT 1 1 1 1\n"
303  "WIDTH 18\n"
304  "HEIGHT 1\n"
305  "VIEWPOINT 0 0 0 1 0 0 0\n"
306  "POINTS 18\n"
307  "DATA ascii\n"
308  "0.44912094 0.49084857 1.153 22\n"
309  "0.34907714 0.48914573 1.149 22\n"
310  "0.33813429 0.48914573 1.149 22\n"
311  "0.32833049 0.49084857 1.153 22\n"
312  "0.24395333 0.42856666 0.98900002 22\n"
313  "0.20816095 0.42856666 0.98900002 22\n"
314  "0.1987419 0.42291525 0.98900002 22\n"
315  "0.18178761 0.42291525 0.98900002 22\n"
316  "0.17990381 0.42291525 0.98900002 22\n"
317  "-0.035590474 0.42997143 1.01 22\n"
318  "-0.035907622 0.43962574 1.0190001 22\n"
319  "-0.043542858 0.43639618 1.016 22\n"
320  "-0.15246001 0.36058003 0.84700006 22\n"
321  "0.21956001 0.44007048 0.99800003 22\n"
322  "-0.16635144 0.3699457 0.86900002 22\n"
323  "-0.33879143 0.36143145 0.84900004 22\n"
324  "-0.35055432 0.36853144 0.85800004 22\n"
325  "-0.39932001 0.38058859 0.89400005 22\n"
326  );
327 
328  DP pointCloud = IO::loadPCD(is);
329 
330  // Confirm sizes and dimensions
331  EXPECT_TRUE(pointCloud.features.cols() == 18);
332  EXPECT_TRUE(pointCloud.features.rows() == 4);
333  EXPECT_TRUE(pointCloud.descriptors.cols() == 18);
334  EXPECT_TRUE(pointCloud.descriptors.rows() == 1);
335 
336  // Random value check
337  EXPECT_NEAR(pointCloud.features(0, 0), 0.449121, 0.0000001);
338  EXPECT_NEAR(pointCloud.features(2, 2), 1.149, 0.0000001);
339  EXPECT_NEAR(pointCloud.descriptors(0, 10), 22, 0.0000001);
340 
341 }
342 
344 {
345 
346 public:
347  virtual void SetUp()
348  {
349  nbPts = 10;
350  addRandomFeature("x", 1);
351  addRandomFeature("y", 1);
352  addRandomFeature("z", 1);
353  ptCloud.addFeature("pad", PM::Matrix::Ones(1, nbPts));
354 
355  addRandomDescriptor("normals",3);
356  addRandomDescriptor("eigValues",3);
357  addRandomDescriptor("eigVectors",9);
358  addRandomDescriptor("color",4);
359  }
360 
361  void addRandomFeature(const string& featureName, const int rows)
362  {
363  ptCloud.addFeature(featureName,PM::Matrix::Random(rows, nbPts));
364  }
365 
366  void addRandomDescriptor(const string& descriptorName, const int rows)
367  {
368  ptCloud.addDescriptor(descriptorName, PM::Matrix::Random(rows, nbPts));
369  }
370 
371  virtual void loadSaveTest(const string& testFileName, bool plyFormat = false, const int nbPts = 10, bool binary = false)
372  {
373  this->testFileName = testFileName;
374 
375  if (plyFormat || binary) {
376  // make sure random values generated for colors are within ply format range
377  int pointCount(ptCloud.features.cols());
378  int descRows(ptCloud.descriptors.rows());
379  bool datawithColor = ptCloud.descriptorExists("color");
380  int colorStartingRow = ptCloud.getDescriptorStartingRow("color");
381  int colorEndRow = colorStartingRow + ptCloud.getDescriptorDimension("color");
382  for (int p = 0; p < pointCount; ++p)
383  {
384  for (int d = 0; d < descRows; ++d)
385  {
386  if (datawithColor && d >= colorStartingRow && d < colorEndRow) {
387  if (ptCloud.descriptors(d, p) < 0) { ptCloud.descriptors.coeffRef(d, p) = -(ptCloud.descriptors(d, p)); }
388  ptCloud.descriptors.coeffRef(d, p) = (static_cast<unsigned>(ptCloud.descriptors(d, p) * 255.0)) / 255.0;
389  }
390  }
391  }
392  }
393 
394  ptCloud.save(testFileName, binary);
395 
396  ptCloudFromFile = DP::load(testFileName);
397 
398  EXPECT_TRUE(ptCloudFromFile.features.cols() == ptCloud.features.cols());
399  EXPECT_TRUE(ptCloudFromFile.descriptorExists("normals",3));
400  EXPECT_TRUE(ptCloudFromFile.getDescriptorViewByName("normals").isApprox(ptCloud.getDescriptorViewByName("normals")));
401  EXPECT_TRUE(ptCloudFromFile.descriptorExists("eigValues",3));
402  EXPECT_TRUE(ptCloudFromFile.getDescriptorViewByName("eigValues").isApprox(ptCloud.getDescriptorViewByName("eigValues")));
403  EXPECT_TRUE(ptCloudFromFile.descriptorExists("eigVectors",9));
404  EXPECT_TRUE(ptCloudFromFile.getDescriptorViewByName("eigVectors").isApprox(ptCloud.getDescriptorViewByName("eigVectors")));
405  EXPECT_TRUE(ptCloudFromFile.descriptorExists("color",4));
406  if (plyFormat || binary) {
407  EXPECT_TRUE(((ptCloudFromFile.getDescriptorViewByName("color") * 255.0)).isApprox((ptCloud.getDescriptorViewByName("color") * 255.0), 1.0));
408  } else {
409  EXPECT_TRUE(ptCloudFromFile.getDescriptorViewByName("color").isApprox(ptCloud.getDescriptorViewByName("color")));
410  }
411 
412  EXPECT_TRUE(ptCloudFromFile.features.isApprox(ptCloud.features));
413 
414  }
415 
416  virtual void TearDown()
417  {
418  EXPECT_TRUE(boost::filesystem::remove(boost::filesystem::path(testFileName)));
419  }
420 
421 
422 protected:
423  int nbPts;
427  string testFileName;
428 
429 };
430 
432 {
433  ptCloud.addDescriptor("genericScalar", PM::Matrix::Random(1, nbPts));
434  ptCloud.addDescriptor("genericVector", PM::Matrix::Random(3, nbPts));
435  ptCloud.addTime("genericTime", PM::Int64Matrix::Random(1, nbPts));
436 
437  loadSaveTest(dataPath + "unit_test.vtk");
438 
439  EXPECT_TRUE(ptCloudFromFile.descriptorExists("genericScalar",1));
440  EXPECT_TRUE(ptCloudFromFile.descriptorExists("genericVector",3));
441  EXPECT_TRUE(ptCloudFromFile.timeExists("genericTime",1));
442 
443 }
444 
446 {
447  ptCloud.addDescriptor("genericScalar", PM::Matrix::Random(1, nbPts));
448  ptCloud.addDescriptor("genericVector", PM::Matrix::Random(3, nbPts));
449  ptCloud.addTime("genericTime", PM::Int64Matrix::Random(1, nbPts));
450 
451  loadSaveTest(dataPath + "unit_test.bin.vtk", false, 10, true);
452 
453  EXPECT_TRUE(ptCloudFromFile.descriptorExists("genericScalar",1));
454  EXPECT_TRUE(ptCloudFromFile.descriptorExists("genericVector",3));
455  EXPECT_TRUE(ptCloudFromFile.timeExists("genericTime",1));
456 }
457 
459 {
460  loadSaveTest(dataPath + "unit_test.ply", true);
461 }
462 
464 {
465  loadSaveTest(dataPath + "unit_test.pcd");
466 }
467 
469 {
470  loadSaveTest(dataPath + "unit_test.csv");
471 }
PointMatcherIO
IO Functions and classes that are dependant on scalar type are defined in this templatized class.
Definition: IO.h:43
PointMatcher::DataPoints::getNbGroupedDescriptors
unsigned getNbGroupedDescriptors() const
Return the number of grouped descriptors (e.g., normals can have 3 components but would count as only...
Definition: pointmatcher/DataPoints.cpp:179
IOLoadSaveTest::loadSaveTest
virtual void loadSaveTest(const string &testFileName, bool plyFormat=false, const int nbPts=10, bool binary=false)
Definition: utest/ui/IO.cpp:371
IOLoadSaveTest::featureLabels
DP::Labels featureLabels
Definition: utest/ui/IO.cpp:424
IOLoadSaveTest::addRandomDescriptor
void addRandomDescriptor(const string &descriptorName, const int rows)
Definition: utest/ui/IO.cpp:366
PointMatcher::DataPoints::getEuclideanDim
unsigned getEuclideanDim() const
Return the dimension of the point cloud.
Definition: pointmatcher/DataPoints.cpp:165
PointMatcher::DataPoints::Labels
A vector of Label.
Definition: PointMatcher.h:229
EXPECT_NEAR
#define EXPECT_NEAR(val1, val2, abs_error)
Definition: gtest.h:19868
PointMatcher::DataPoints::descriptorExists
bool descriptorExists(const std::string &name) const
Look if a descriptor with a given name exist.
Definition: pointmatcher/DataPoints.cpp:582
testing::Test
Definition: gtest.h:17760
TEST_F
TEST_F(IOLoadSaveTest, VTK)
Definition: utest/ui/IO.cpp:431
PointMatcher::DataPoints::getTimeDim
unsigned getTimeDim() const
Return the total number of times.
Definition: pointmatcher/DataPoints.cpp:193
PointMatcher::DataPoints
A point cloud.
Definition: PointMatcher.h:207
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition: gtest.h:19327
PointMatcherSupport::InvalidModuleType
An exception thrown when one tries to use a module type that does not exist.
Definition: PointMatcher.h:83
TEST
TEST(IOTest, loadYaml)
Definition: utest/ui/IO.cpp:10
EXPECT_EQ
#define EXPECT_EQ(expected, actual)
Definition: gtest.h:19747
EXPECT_NO_THROW
#define EXPECT_NO_THROW(statement)
Definition: gtest.h:19313
IOLoadSaveTest::addRandomFeature
void addRandomFeature(const string &featureName, const int rows)
Definition: utest/ui/IO.cpp:361
IOLoadSaveTest::ptCloud
DP ptCloud
Definition: utest/ui/IO.cpp:425
d
d
PointMatcher::DataPoints::descriptors
Matrix descriptors
descriptors of points in the cloud, might be empty
Definition: PointMatcher.h:333
PointMatcherSupport::Parametrizable::InvalidParameter
An exception thrown when one tries to fetch the value of an unexisting parameter.
Definition: Parametrizable.h:101
PointMatcher::DataPoints::getNbPoints
unsigned getNbPoints() const
Return the number of points contained in the point cloud.
Definition: pointmatcher/DataPoints.cpp:158
dataPath
std::string dataPath
Definition: utest.cpp:43
PointMatcher::DataPoints::features
Matrix features
features of points in the cloud
Definition: PointMatcher.h:331
IOLoadSaveTest::nbPts
int nbPts
Definition: utest/ui/IO.cpp:423
PointMatcher::DataPoints::times
Int64Matrix times
time associated to each points, might be empty
Definition: PointMatcher.h:335
IOLoadSaveTest::TearDown
virtual void TearDown()
Definition: utest/ui/IO.cpp:416
std
PointMatcher::DataPoints::getDescriptorDim
unsigned getDescriptorDim() const
Return the total number of descriptors.
Definition: pointmatcher/DataPoints.cpp:186
EXPECT_THROW
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:19311
IOLoadSaveTest::SetUp
virtual void SetUp()
Definition: utest/ui/IO.cpp:347
IOLoadSaveTest
Definition: utest/ui/IO.cpp:343
IOLoadSaveTest::ptCloudFromFile
DP ptCloudFromFile
Definition: utest/ui/IO.cpp:426
PointMatcherSupport
Functions and classes that are not dependant on scalar type are defined in this namespace.
Definition: Bibliography.cpp:45
PointMatcher::DataPoints::load
static DataPoints load(const std::string &fileName)
Load a point cloud from a file, determine format from extension.
Definition: pointmatcher/IO.cpp:375
IOLoadSaveTest::testFileName
string testFileName
Definition: utest/ui/IO.cpp:427


mrpt_local_obstacles
Author(s): Jose-Luis Blanco-Claraco
autogenerated on Mon Aug 14 2023 02:09:03