Marlowe
Marlowe

Reputation: 41

PCL: X and Y values are changed when pcd file is loaded by PCL library

I want to load point cloud data using PCL. I could load sample data on tutorial correctly, but when I try with my data, the value of pcd file was changed to very small value.

Terminal output image

The actual value is like 3603538.71629 but when PCL reads this file it becomes very small values. This is my pcd file.

# .PCD v.7 - Point Cloud Data file format
VERSION .7
FIELDS x y z cluster
SIZE 4 4 4 4
TYPE F F F F
COUNT 1 1 1 1
WIDTH 14937
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 14937
DATA binary
# POINT_X;POINT_Y;Count;Cluster
3603538.71629;5794698.05946;1;4
3605159.73611;5792213.47052;1;20
3605158.44424;5792230.86339;1;20
3605158.97718;5792221.85844;1;20
3605152.30217;5792232.17992;1;20
3604558.82308;5793345.02318;1;55
3604944.90684;5794341.30959;1;56

This is my pcd_read.cpp

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>

int
main (int argc, char** argv)
{
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);

  if (pcl::io::loadPCDFile<pcl::PointXYZ> ("xyzc-Cloud.pcd", *cloud) == -1) //* load the file
  {
    PCL_ERROR ("Couldn't read file xyzc-Cloud.pcd \n");
    return (-1);
  }
  std::cout << "Loaded "
            << cloud->width * cloud->height
            << " data points from xyzc-Cloud.pcd with the following fields: "
            << std::endl;

  for (size_t i = 0; i < 10; ++i)  
    std::cout << "    " << cloud->points[i].x
              << " "    << cloud->points[i].y
              << " "    << cloud->points[i].z << std::endl;

  return (0);
}
'''

Environment: macOS ver 10.14.16

Upvotes: 1

Views: 583

Answers (1)

acraig5075
acraig5075

Reputation: 10756

I think you are seeing corruption because of your coordinate data being improperly formatted. The fields are supposed to be space or tab delimited, whereas you have a character ;.

Quote from the docs:

Storing point cloud data in both a simple ascii form with each point on a line, space or tab separated, without any other characters on it, as well as in a binary dump format, allows us to have the best of both worlds: simplicity and speed, depending on the underlying application.

This is confirmed by looking at the reader source where the lines are split using the following. Your semi-colon will lead to invalid splitting and subsequent float extraction. The function does not return an error for improper formatting, which is why your code still works, albeit incorrectly.

boost::split (st, line, boost::is_any_of ("\t\r "), boost::token_compress_on);

Therefore, answer is to format your .pcd body data with space delimiters.


Also as @UlrichtEckhardt comments you're mixing and matching intended output formats:

Replace

DATA binary

with

DATA ascii

Upvotes: 1

Related Questions