3

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: enter image description here

Current result: enter image description here

4

4 回答 4

2

我正在努力解决类似的问题,并通过使用Open3D 库为我找到了一种非常方便的方法。

pip install open3d只需使用 pip或 conda安装库conda install -c open3d-admin open3d并运行以下三行:

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

它工作正常并保持颜色(使用 CloudCompare 检查)。

于 2020-06-20T16:55:26.570 回答
0

你可以从这里得到 r,g,b 和 rgb 之间的关系

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;

好的,你可以改变

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

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)))
于 2019-04-13T13:01:55.680 回答
0

当我使用您的方法时,出现以下错误:

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

我也尝试安装 pcl 库,显然我无法让它运行它的错误,我的 python 解释器甚至在pip install python-pcl not evetimport pcl正常工作后都看不到它我得到一个 ModuleNotFoundError

任何其他转换方法我仍然坚持使用 .ply 文件?

于 2020-05-13T11:59:46.133 回答
-1

我知道我参加聚会已经很晚了,但是为什么不给python-pcl 库一个机会呢?具体来说,您可以通过这种方式使用pcl.save()方法:

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

请注意 pcl.save 方法根据您在文件路径中或作为方法参数提供的文件扩展名保存云。也许您打算编写自己的函数,但我仍将这个答案留在这里,希望对您或其他人有用。

于 2018-12-01T16:37:48.897 回答