Convertion of .ply format to .pcd format

邮差的信 提交于 2020-07-09 08:17:14

问题


I've a .ply format model and trying to create a .pcd file one. After checking how .pcd format should look like and writing some code to convert it to .pcd format, my results are that the model is black colored only, instead of multi-colored like the .ply format model.

In the .ply format there are 7 parameters in every point line (x,y,z,r,g,b,a) and on .pcd one it should be (x y z rgb). I'm not sure how to evaluate the rgb from the .ply file.

Here's some of my .ply file data:

ply
format ascii 1.0
comment VCGLIB generated
element vertex 130474
property float x
property float y
property float z
property uchar red
property uchar green
property uchar blue
property uchar alpha
element face 0
property list uchar int vertex_indices
end_header
169.345 0.00190678 -356.222 128 138 80 255 
170.668 0.00202459 -355.459 58 36 16 255 
170.6 0.00285877 -355.877 59 46 45 255 
170.307 0.00326565 -354.98 149 107 81 255 
170.581 0.00329066 -355.646 61 38 28 255 

And some of the .pcd file data after using the code:

# .PCD v.7 - Point Cloud Data file format
VERSION .7
FIELDS x y z rgb
SIZE 4 4 4 1
TYPE F F F F
COUNT 1 1 1 1
WIDTH 130474
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 130474
DATA ascii
169.345 0.00190678 -356.222 128
170.668 0.00202459 -355.459 58
170.6 0.00285877 -355.877 59

Here's how the .pcd should look like (found in point cloud website)

# .PCD v.7 - Point Cloud Data file format
VERSION .7
FIELDS x y z rgb
SIZE 4 4 4 4
TYPE F F F F
COUNT 1 1 1 1
WIDTH 213
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 213
DATA ascii
0.93773 0.33763 0 4.2108e+06
0.90805 0.35641 0 4.2108e+06
0.81915 0.32 0 4.2108e+06

Question: What are these values: 4.2108e+06 as the 4th parameter and how can I generate it through the .ply format?

Here's the code I'm currently using on PyCharm:

#!/usr/bin/env python
import sys
import os

header = "# .PCD v.7 - Point Cloud Data file format\n\
VERSION .7\n\
FIELDS x y z rgb\n\
SIZE 4 4 4 1\n\
TYPE F F F F\n\
COUNT 1 1 1 1\n\
WIDTH XXXX\n\
HEIGHT 1\n\
VIEWPOINT 0 0 0 1 0 0 0\n\
POINTS XXXX\n\
DATA ascii"

def convertionOfPlyToPcd(ply_file, pcd_file):
    input_file = open(ply_file)
    out = pcd_file
    output = open(out, 'w')
    write_points = False
    points_counter = 0
    nr_points = 0
    for s in input_file.readlines():
        if s.find("element vertex") != -1:
            nr_points = int(s.split(" ")[2].rstrip().lstrip())
            new_header = header.replace("XXXX", str(nr_points))
            output.write(new_header)
            output.write("\n")
        if s.find("end_header") != -1:
            write_points = True
            continue
        if write_points and points_counter < nr_points:
            points_counter = points_counter + 1
            output.write(" ".join(s.split(" ", 4)[:4]))
            output.write("\n")
    input_file.close()
    output.close()

if __name__ == "__main__":
    # We request the path to the script, if it's not found - exit
    if sys.argv[0] == "":
        sys.exit(1)
    # PLY file - We convert this format to PCD format
    ply_file = sys.argv[1]
    # PCD file - generated from PLY file
    pcd_file = sys.argv[2]

    # Function which converts .ply format files to .pcd files
    convertionOfPlyToPcd(ply_file, pcd_file)

With these changes to the code the results are white cloud points instead of black:

header = "# .PCD v.7 - Point Cloud Data file format\n\
VERSION .7\n\
FIELDS x y z\n\
SIZE 4 4 4\n\
TYPE F F F \n\
COUNT 1 1 1\n\
WIDTH XXXX\n\
HEIGHT 1\n\
VIEWPOINT 0 0 0 1 0 0 0\n\
POINTS XXXX\n\
DATA ascii"

Software used for comparison: CloudCompare

Desired result:

Current result:


回答1:


I was struggling with a similar problem and found a quite convenient method for me by using the Open3D library.

Simply install the library using pip pip install open3d or conda conda install -c open3d-admin open3d and run these three lines:

import open3d as o3d
pcd = o3d.io.read_point_cloud("source_pointcloud.ply")
o3d.io.write_point_cloud("sink_pointcloud.pcd", pcd)

It worked fine and kept the colors (checked by using CloudCompare).




回答2:


You can get the relationship between r,g,b and rgb from here

PointXYZRGB p;
// unpack rgb into r/g/b
uint32_t rgb = *reinterpret_cast<int*>(&p.rgb);
uint8_t r = (rgb >> 16) & 0x0000ff;
uint8_t g = (rgb >> 8)  & 0x0000ff;
uint8_t b = (rgb)       & 0x0000ff;

OK, you can change

output.write(" ".join(s.split(" ", 4)[:4]))

to

x,y,z,r,g,b = s.split(" ", 6)[:6]
rgb = str((int(r)<<16)  + (int(g)<<8) + (int(b)))
output.write(" ".join((x,y,z,rgb)))



回答3:


When I use your method I get the following error:

Traceback (most recent call last):
  File "/home/me/shared/test.py", line 49, in <module>
    convertionOfPlyToPcd(ply_file, pcd_file)
  File "/home/me/shared/test.py", line 23, in convertionOfPlyToPcd
    for s in input_file.readlines():
  File "/usr/lib/python3.6/codecs.py", line 321, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbf in position 252: invalid start byte

I have also tried to install the pcl library, apparently I cant get it working its buggy and my python interpreter doesn't even see it after pip install python-pcl not evet just import pcl works I get a ModuleNotFoundError

Any other method for the conversion I'm still stuck with the .ply file ??




回答4:


I know that I'm pretty late to the party but, why not giving a chance to python-pcl library? Specifically, you can use method pcl.save() in this way:

cloud_in = pcl.load("path-to-ply-cloud.ply")
pcl.save(cloud_in, "path-to-ply-cloud.pcd")

notice that pcl.save method saves the cloud according to the file extension you provide either in your file path or as method parameter. Maybe you intended to write your own function but I'm still leaving this answer here hoping that will be useful to you or to someone else.



来源:https://stackoverflow.com/questions/51350493/convertion-of-ply-format-to-pcd-format

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!