基于Win系统下PCL库入门到实践:IO模块之PLY文件的读写(附详细代码
PLY(Polygon File Format) 是一种常用的三维数据存储格式,最初由 Stanford 大学提出。可以保存的信息有点云数据(XYZ,RGB,法向量,强度等属性)、网格模型(点 + 面的拓扑关系)。实际应用场景广泛:三维扫描与建模:结构光扫描仪/深度相机输出点云 → 保存为 PLY → 用于 3D 打印或仿真。点云到网格的过渡:PCL/Open3D 重建曲面 → 导出 PLY → 在 Meshlab/Blender 中查看和编辑。自动驾驶与机器人:激光雷达点云 → 转成 PLY → 用第三方工具做可视化和标注。医学影像:CT/MRI 数据重建 3D 模型 → 保存为 PLY → 用于手术导航和医学可视化。
文件的读取
PLY的读取和PCD的类似也是分为两种:
pcl::PLYReader reader;
reader.read("C:\\Users\\admin\\Desktop\\code\\pcl_type.pcd", Cloud);
pcl::io::loadPLYFile("C:\\Users\\admin\\Desktop\\code\\result\\pcl_ASCII.pcd", Cloud);
文件的保存
pcl::PLYWriter writer;
writer.write("C:\\Users\\admin\\Desktop\\code\\pcl_ASCII.pcd",*Cloud2,true);
writer.writeASCII("C:\\Users\\admin\\Desktop\\code\\pcl_ASCII.pcd",Cloud);
writer.writeBinary("C:\\Users\\admin\\Desktop\\code\\pcl_Binary.pcd",Cloud);
pcl::io::savePLYFile("C:\\Users\\admin\\Desktop\\code\\pcl.pcd",*Cloud2);
pcl::io::savePLYFileASCII("C:\\Users\\admin\\Desktop\\code\\pcl.pcd",*Cloud2);
pcl::io::savePLYFileBinary("C:\\Users\\admin\\Desktop\\code\\pcl_Binary.pcd",*Cloud2);
PLY文件的保存可能有区别:不能保存为压缩二进制,原始write中的第四个参数就是是否保存二进制。并且本身write支持接受两种类别的点云变量。
而第一种的方法ASCII和Binary只支持PCLPointCloud2的接收。
至于第二种方法就支持了,可以跳转到其函数定义:
mesh
这里引入mesh的介绍
Mesh(网格)是 3D 表面几何的一种离散表示方法。点云(Point Cloud):只有点,没有拓扑关系。Mesh(网格):不仅有点(顶点),还有面(多边形),可以表示物体的形状和表面。一个 Mesh = 顶点表 + 面索引表。Mesh 通常保存在以下文件中:PLY(Polygon File Format)、OBJ、STL、OFF。
具体代码实现添加mesh:
#include <thread>
#include <pcl/point_cloud.h>
#include <pcl/io/ply_io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/visualization/pcl_visualizer.h>//.h>using namespace std;int main()
{pcl::PolygonMesh mesh;pcl::PCLPointCloud2 Cloud;//这里是不知道要读取得点云到底是什么格式得,所以使用PCLPointCloud2可以读取更多得格式pcl::io::loadPLYFile("C:\\Users\\admin\\Desktop\\code\\3Dfile\\PLY Railgun\\Railgun_Prototype-Polygon File Format.ply", Cloud);pcl::io::loadPLYFile("C:\\Users\\admin\\Desktop\\code\\3Dfile\\PLY Railgun\\Railgun_Prototype-Polygon File Format.ply", mesh);for(auto &f : Cloud.fields)cout <<f.name<<endl;//这一步就是在输出口打印其格式pcl::PointCloud<pcl::PointXYZ>::Ptr Cloud2(new pcl::PointCloud<pcl::PointXYZ>);pcl::fromPCLPointCloud2(Cloud,*Cloud2);// // 创建 CloudViewerpcl::visualization::CloudViewer viewer("Viewer");viewer.showCloud(Cloud2);viewer.runOnVisualizationThread([&](pcl::visualization::PCLVisualizer &vis){vis.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "cloud");vis.setBackgroundColor(0.2,0.3,0.4);if (!vis.contains("mesh")) {vis.addPolygonMesh(mesh,"mesh");}//添加mesh});// 保持显示while (!viewer.wasStopped())std::this_thread::sleep_for(std::chrono::milliseconds(100));// pcl::PLYWriter writer;// writer.write("C:\\Users\\admin\\Desktop\\code\\pcl_ASCII.pcd",*Cloud2,true);// writer.writeASCII("C:\\Users\\admin\\Desktop\\code\\pcl_ASCII.pcd",Cloud);// writer.writeBinary("C:\\Users\\admin\\Desktop\\code\\pcl_Binary.pcd",Cloud);// pcl::io::savePLYFileBinary("C:\\Users\\admin\\Desktop\\code\\pcl_Binary.pcd",*Cloud2);// pcl::io::savePLYFile("C:\\Users\\admin\\Desktop\\code\\pcl.pcd",*Cloud2);// pcl::io::savePLYFileASCII("C:\\Users\\admin\\Desktop\\code\\pcl.pcd",*Cloud2);return 0;
}
添加mesh和点云可视化结果: