Skip to content

Open3D saved PointCloud file (.ply) cannot be read by the PCL library

AlexZakIntel edited this page Jan 27, 2022 · 2 revisions

Q: Open3D-saved PointCloud file (.ply) cannot be read by the PCL library:

I am using these APIs:

o3d.io.write_point_cloud(...)
pcl::io::readPLYFile(...)

Then pcl would get empty cloud.

This occurs in the following environment:

  • OS: Ubuntu 16.04
  • Python version: 3.6
  • Open3D version: 0.9.0.0
  • Is this a remote workstation?: no
  • How did you install Open3D?: through conda

A:

Here is what we found:

  • Open3D IO (Legacy/Eigen-based) only supports double data types. Therefore while reading, the data is converted to double, and while saving x, y, z, nx, ny, nz are saved as double, while colors r, g, b are converted to uchar.
  • PCL PLY format does not seem to support double.
    Therefore, PLY files saved by Open3D Legacy/Eigen IO are incompatible with PCL PLY, as they lack support for double value attributes.

However,

  • The NEW Open3D Tensor IO supports saving files in the original attribute (float -> float, double -> double). So, one may use that to save point clouds in Float, which is compatible with PCL.

Conclusion:

  • PCL does not support Double attribute in PLY format;
  • Please use the NEW Open3D Tensor IO, as is it supports various data types and custom attributes.

C++ PCL Test Code for PLY IO:

#include <pcl/io/ply_io.h>
#include <pcl/point_types.h>

#include <iostream>

int main(int argc, char* argv[])
{
  if (argc < 2) {
    std::cout << "Please pass the path to PLY file, as argument.";
    return 1;
  }

  const std::string path = argv[1];

  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);

  if (pcl::io::loadPLYFile<pcl::PointXYZ>(path, *cloud) == -1) //* load the file
  {
    PCL_ERROR("Couldn't read file o3d_io_ply_ascii.ply \n");
    return (-1);
  }

  std::cout << "Loaded " << cloud->width * cloud->height
            << " data points from test_ply.ply with the following fields: "
            << std::endl;
  for (const auto& point : *cloud)
    std::cout << "    " << point.x << " " << point.y << " " << point.z << std::endl;

  return (0);
}

original.ply is a ply generated by PCL, with Float Points, Normals, Curvature, and UChar Colors.

Python Example 1: Open3D Legacy/Eigen-based IO: files generated by the following code are NOT supported by PCL:

import open3d as o3d
pcd = o3d.io.read_point_cloud("/home/rey/original.ply")
o3d.io.write_point_cloud("/home/rey/o3d_io_ply_ascii.ply", pcd, write_ascii=True, compressed=False)
o3d.io.write_point_cloud("/home/rey/o3d_io_ply_ascii_compressed.ply", pcd, write_ascii=True, compressed=False)
o3d.io.write_point_cloud("/home/rey/o3d_io_ply_bin.ply", pcd, write_ascii=False, compressed=False)
o3d.io.write_point_cloud("/home/rey/o3d_io_ply_bin_compressed.ply", pcd, write_ascii=False, compressed=True)

Python Example 2: Open3D New Tensor IO: files generated by the following code are supported by PCL:

tpcd = o3d.t.io.read_point_cloud("/home/rey/original.ply")
o3d.t.io.write_point_cloud("/home/rey/o3d_tio_ply_ascii.ply", tpcd, write_ascii=True, compressed=False)
o3d.t.io.write_point_cloud("/home/rey/o3d_tio_ply_ascii_compressed.ply", tpcd, write_ascii=True, compressed=False)
o3d.t.io.write_point_cloud("/home/rey/o3d_tio_ply_bin.ply", tpcd, write_ascii=False, compressed=False)
o3d.t.io.write_point_cloud("/home/rey/o3d_tio_ply_bin_compressed.ply", tpcd, write_ascii=False, compressed=True)

Python Example 3: Converted to Float64/Double by Open3D and then saved by Tensor IO: files generated by the following code are NOT supported by PCL.

tpcd_f64 = o3d.t.io.read_point_cloud("/home/rey/original.ply")

for attr in tpcd_f64.point:
    tpcd_f64.point[attr] = tpcd_f64.point[attr].to(o3d.core.float64)
    
o3d.t.io.write_point_cloud("/home/rey/o3d_tio_ply_ascii64.ply", tpcd_f64, write_ascii=True, compressed=False)
o3d.t.io.write_point_cloud("/home/rey/o3d_tio_ply_ascii_compressed64.ply", tpcd_f64, write_ascii=True, compressed=False)
o3d.t.io.write_point_cloud("/home/rey/o3d_tio_ply_bin64.ply", tpcd_f64, write_ascii=False, compressed=False)
o3d.t.io.write_point_cloud("/home/rey/o3d_tio_ply_bin_compressed64.ply", tpcd_f64, write_ascii=False, compressed=True)

For more detailed information, please see our Issues page at: https://github.com/isl-org/Open3D/issues/1633#issuecomment-1014225858