随便写点
Jan/15/2023
最近在学PCL,关于网上很多使用PCL将PCD转PLY格式的内容,不能说有错,因为文件的header确实被正确的修改,也能被读取。但是存在一个问题:PLY的header中,element face 的数量依然是0。这是因为那些转换方式不是一个表面重建的过程,PCD(点云)并没有被转换成PLY(网格)。因此如果想通过PCL完全的将PCD转为PLY,需要搜索的内容是“表面重建”,而不是“PCD转PLY”。
July/1/2022
标题中“点云表面重建”为后来添加,因为这通操作最开始的需求是 PCD 转 PLY 这个直观浅显的需求。起初我并没有意识到这实质上一个表面重建的过程。
正文
我也不清楚为什么会有这么奇怪的需求。
直到我发现 pcd 格式的数据不能被 MATLAB 的 toolbox_wavelet_meshes 处理,也不能被 MeshLab 处理。因为两者文件结构的差别,不能直接通过修改文件后缀实现格式转换。
于是上网搜,剔除掉智能聚合得到的垃圾,基本只剩下3种解决方案:
- 通过C++的PCL(Point Cloud Library)来实现格式转换。见 PCL中将PCD文件转换成PLY文件。当然在一切皆有可能的CSDN,这篇文章已经变成了VIP可见。
因为重新配置环境太麻烦,不想因为这个文件转换浪费太多时间。况且我的程序都在MATLAB上运行,不想换成C++(其实是不会)。 - 某些工具箱 或者 Github上的脚本。见 PcdPlyConverter 还是C++...
- 文章中使用的这种,来自一个日文网站,方法简单无脑暴力,需要先安装MeshLAB,下方链接自行安装。MeshLab
PCD 和 PLY 的区别
首先说说 pcd 和 ply 文件的区别。虽然二者整体结构很相似,都是header + x y z 坐标。但是还是有细微的差别。
PCD Header:
# .PCD v.7 - Point Cloud Data file format
VERSION .7
FIELDS x y z nx ny nz
SIZE 4 4 4 4 4 4
TYPE F F F F F F
COUNT 1 1 1 1 1 1
WIDTH 299266
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 299266
DATA ascii
PLY Header:
ply
format binary_little_endian 1.0
comment VCGLIB generated
element vertex 151546
property float x
property float y
property float z
element face 303088
property list uchar int vertex_indices
end_header
从上述代码的header可以发现,ply文件在 x y z 坐标外,还提供了 vertex 和 face 这两个元素。
vertex 和 pcd 中的 point 类似,但是 face 这个参数不能通过观察得出。
转换方法
- 首先用记事本打开pcd文件。删除header部分的内容。之后将文件原本的pcd后缀改为asc。
- 之后,这个文件便可用 MeshLAB 打开
- 计算点云表面法线。在菜单 Filters ->Point Sets -> Compute normals for points sets 。进行完这步后,reconstruction效果会更好。
- 计算法线完毕后,另存项目为一个新的project。这步很重要,因为后续重建步骤必须在现存的一个project上进行,否则会报错。
- 在菜单 Filters -> Remeshing simpleification and Reconstruction -> Surface Reconstruction : Screened Poisson 中,将对象网格化。可以看到Reconstruction有三种方式,你会发现第一种“Ball pivoting”这种方法不需要另存为新的project便可进行,但是这种方法并不会生成新的vertex,如果原数据点云密度太小,会产生很多closed hole。
- 导出文件,格式保存为 ply 。这个PLY文件就可以使用于之后的各种场景了。由此可见 pcd 格式转为 ply 的核心就是表面重建这个步骤。
参考文章
[1] Pcd2PlyConvert