1

I'm trying to read .bin point cloud files. I found this link suggesting a python code that I can convert to C++. I came up with the following code, but the precision of the floating point numbers are different compared to the results that I got from running the python code in the above link. I noticed that some coordinate values in the middle are totally missing, or in other words, the count of the floating point values that resulted from python is more than that of the C++ code:

std::ifstream file("C:/Users/hedey/OneDrive/Documents/Research_papers/STDF/data_object_velodyne/training/velodyne/001984.bin", ios::in | std::ios::binary);

char header[4];
float item;
if (file.is_open())
{
    file.read((char*)&header, 4);
    cout << char(header) << endl;
    while (!file.eof())
    {
        file.read((char*)&item, 4);
        cout << float(item) << endl;
    }
    file.close();

}

Here is a link to the bin file I was trying to read: https://www.dropbox.com/s/m6gney49lmr5vg9/001984.zip?dl=0

Also, the header string is not showing up using the above C++ code. What might be wrong with my code? How can it be improved?

Mohamed Hedeya
  • 153
  • 5
  • 22
  • The first four bytes of your file are `F0 A7 92 41`, three of them are not printable; are you sure you can `cout` them? Your excessive type casting is suspicious. Could you please try to read your floats directly: `file >> item;`? – Vlad Feinstein Jan 04 '21 at 23:01
  • The first 4 bytes are not printable. Every time I cout them, I get a different character, sometimes 'C' , or 'p', .... When I tried file >> item, I got a series of zeros instead of the decimal point values I was getting before. – Mohamed Hedeya Jan 04 '21 at 23:19
  • The link says "Essentially we took a .pcd file, removed the headers and saved the data in binary format." so I'm not sure why you think there's a header. There are a lot of zeroes in that file. The link says they are in groups of 5 with the last an unused index but the zeroes do not match up to that 5th value. *shrug* – Retired Ninja Jan 04 '21 at 23:21
  • You are printing an address of the `header` array, type-casted to `char`. Garbage in - garbage out... – Vlad Feinstein Jan 04 '21 at 23:23

1 Answers1

1

Here's a code that produces exactly the same output as the Python version:

#include <iostream>
#include <fstream>
#include <cmath>

int main()
{
  std::ifstream file("1.pcd.bin", std::ios::in | std::ios::binary);
  if (!file) return EXIT_FAILURE;

  float item;
  while (file.read((char*)&item, 4))
  {
    std::cout << "[" << item;
    if (std::round(item) == item) std::cout << ".";
    std::cout  << "]\n";
  }
}

Now, where did you go wrong?

  • you did not search the internet or did not mention here what actually .pcd.bin format is. I found the definition of the true binary pcd format here: https://pointclouds.org/documentation/tutorials/pcd_file_format.html , but this is NOT the format you deal with
  • well, so you did not understand the format, hence your problem :-)
  • the guys who "invented" pcd.bin evidently started from ASCII format, removed the header, and wrote everything else as binary, in groups of five floats.
  • So there's no header in the input.
  • Please note how I organize the while loop. It's far better than your testing for the end-of-file condition, which is usually incorrect.
  • For this reason you printed out the last item twice
zkoza
  • 2,644
  • 3
  • 16
  • 24
  • Thanks a lot @zkoza for the comprehensive answer. Really appreciated. – Mohamed Hedeya Jan 05 '21 at 23:39
  • Dear Professor @zkoza, Could you pls help me with another question about .las files? I'm totally stuck with this question for weeks, and really need help with it. This is the link to the question: [link](https://stackoverflow.com/questions/65984689/reading-las-version-1-3-using-c-and-displaying-the-results-using-pcl-library) – Mohamed Hedeya Feb 01 '21 at 20:13