不同格式点云存储结构(txt、pcd、las、ply)整理以及基本的读写、可视化方法 您所在的位置:网站首页 后缀为bin的文件有哪些 不同格式点云存储结构(txt、pcd、las、ply)整理以及基本的读写、可视化方法

不同格式点云存储结构(txt、pcd、las、ply)整理以及基本的读写、可视化方法

2024-06-14 03:13| 来源: 网络整理| 查看: 265

不同格式点云存储结构整理以及基本的读写、可视化方法 一、文本(txt)1.1、存储结构1.2、读取 二、PCD格式1.1、存储结构1.2、读写1.2.1、open3d读写(python)1.2.2、PCL读写(C++) 三、LAS格式3.1、存储结构3.2、读写3.2.1、使用laspy 读写(Python)3.2.2、使用laslib读写(C++) 四、PLY格式4.1、存储结构文件头(header)数据区域 4.2、读写4.2.1、使用plyfile读写(Python)4.2.2、使用pcl读写(C++)

一、文本(txt) 1.1、存储结构

使用文本格式存储的点云数据文件结构比较简单,每个点是一行记录,点的信息存储格式为 x y z或者 x y z r g b。

1.2、读取

读取文本格式的点云数据时,可以按照一般的文本读取方法,这里记录一下如何使用open3d读取txt格式的点云数据

import open3d as o3d txt_file=r"D:\test_data\bildstein_station1_xyz_intensity_rgb.txt" pcd=o3d.io.read_point_cloud(txt_file,format='xyz') o3d.visualization.draw([pcd]) 二、PCD格式

一个PCD文件是文件头部分和数据部分组成

1.1、存储结构 字段名字段解释VERSION指定PCD文件版本FIELDS指定一个点可以有的每一个维度和字段的名字SIZE用字节数指定每一个维度的大小TYPE用一个字符指定每一个维度的类型COUNT指定每一个维度包含的元素数据WIDTH无序点的数量或者有序点一行中点的数目HEIGHT无序点云中设置为1,有序点云中表示行数POINTS点云中点的总数DATA数据类型,二进制或者ASCII 1.2、读写 1.2.1、open3d读写(python)

读取pcd点云文件

import open3d as o3d import numpy as np #读取pcd数据并可视化 pcd_file=r"" pcd=o3d.io.read_point_cloud(pcd_file,format='pcd') #将点云的坐标和颜色转换为numpy格式 points=np.array(pcd.points) colors=np.array(pcd.colors) #可视化 o3d.visualization.draw([pcd])

保存pcd点云文件

#写入pcd格式 save_file="test2.pcd" #手动定义点云 points=np.array([[8,5,3], [9,0,1], [2,5,3], [0,4,2], [7,2,9], [8,8,4], [9,5,8], [2,5,9], [0,7,5], [11,2,8], [10,9,0] ]) colors=np.array([[255,0,0], [255,0,0], [0,255,0], [0,255,0], [0,0,255], [0,0,255], [255,0,255], [255,0,255], [255,255,0], [255,255,0], [255,255,0] ]) colors=colors/255 pcd=o3d.geometry.PointCloud() pcd.points=o3d.utility.Vector3dVector(points) pcd.colors=o3d.utility.Vector3dVector(colors) #可视化 o3d.visualization.draw_geometries([pcd]) #使用draw方法可视化需要将颜色归一化到0-1之间 # o3d.visualization.draw([pcd]) #保存 #o3d.io.write_point_cloud(save_file,pcd,write_ascii=True) #以ascii格式存储点数据集部分 o3d.io.write_point_cloud(save_file,pcd)#以二进制格式存储点数据集部分 pcd点数据集部分保存为ASCII格式

pcd点数据集部分保存为二进制格式,其中rgb是用位存储的方式写入的。

1.2.2、PCL读写(C++)

我们用上面生成的pcd文件做测试

#include #include #include using namespace std; int main() { string pcd_file = "D:\\project\\Python\\PointCloud\\test2.pcd"; //pcl::PointCloud::Ptr cloud(new pcl::PointCloud); pcl::PointCloud::Ptr cloud(new pcl::PointCloud); if (pcl::io::loadPCDFile(pcd_file,*cloud)==-1) { PCL_ERROR("couldn't read file\n"); return(-1); } for (size_t i=0;ipoints.size();++i) { cout {8,5,3,255,0,0}, {9,0,1,255,0,0}, {2,5,3,0,255,0}, {0,4,2,0,255,0}, {7,2,9,0,0,255}, {8,8,4,0,0,255}, {9,5,8,255,0,255}, {2,5,9,255,0,255}, {0,7,5,255,255,0}, {11,2,8,255,255,0}, {10,9,0,255,255,0}}; cloud.width = 11; cloud.height = 1; cloud.is_dense = false; cloud.points.resize(cloud.width*cloud.height); for (size_t i = 0; i const string las_file=""; LASreadOpener lasreadopener; lasreadopener.set_file_name(las_file.data()); LASreader* lasreader=lasreadopener.open(); LASheader header=lasreader->header; lasreader->header.unlink(); int nbPoints = header.number_of_point_records; float x,y,z; int r,g,b; while(lasreader->read_point()) { LASpoint& pointReader= lasreader->point; x=pointReader.get_x(); y=pointReader.get_y(); z=pointReader.get_z(); r=pointReader.get_R(); g=pointReader.get_G(); b=pointReader.get_B(); } delete lasreader; }

写入las文件

#include #include "lasreader.hpp" #include "laswriter.hpp" using namespace std; int main() { const string las_file="test.las"; int data[11][6] = { {8,5,3,255,0,0}, {9,0,1,255,0,0}, {2,5,3,0,255,0}, {0,4,2,0,255,0}, {7,2,9,0,0,255}, {8,8,4,0,0,255}, {9,5,8,255,0,255}, {2,5,9,255,0,255}, {0,7,5,255,255,0}, {11,2,8,255,255,0}, {10,9,0,255,255,0} }; LASwriteOpener laswriteropener; laswriteropener.set_file_name(las_file.data()); LASheader header; header.point_data_format=3; header.point_data_record_length=34; header.number_of_point_records=11; LASWriter* laswriter = laswriteropener.open(&header); LASpoint point; point.init(&header,header.point_data_format,header.point_data_record_length,&header); double minx=DBL_MAX,miny=DBL_MAX,minz=DBL_MAX; double maxx=-DBL_MAX,maxy=-DBL_MAX,maxz=-DBL_MAX; for(size_t i=0;i minx=data[i][0]; } if(data[i][1] minx=data[i][2]; } if(data[i][0]>maxx) { maxx=data[i][0]; } if(data[i][1]>maxy) { maxy=data[i][1]; } if(data[i][2]>maxz) { maxx=data[i][2]; } laswriter->write_point(&point); laswriter->update_inventory(&point); } header.set_bounding_box(minx,miny,minz,maxx.maxy.maxz); laswriter->update_header(&header); I64 total_bytes=laswriter->close(); delete laswriter; } 四、PLY格式 4.1、存储结构

PLY(Polygon File Format)是一种常见的点云存储格式,由斯坦福大学开发,其最早主要用于存储三维扫描仪器的点云数据。

PLY文件是由文件头和数据区两部分组成。

文件头(header)

其中文件头记录的是点云文件中的注释、元素类别和属性,以ply开头,以end header结尾。

ply ... ... end header

文件头的第二行是文件的存储方式和版本,以format开头,依次是编码方式、版本。编码方式有三种分别是ascii、binary_little_endian 、binary_big_endian。目前PLY只有1.0版本。

ply format ascii 1.0 ... ... end header

format之后跟注释信息,以comment开头,制作者可以添加一些作者信息,点云基本信息。

ply format ascii 1.0 comment made by anonymous comment this file is a cube ... end header

注释信息comment之后是element元素信息+该种元素的property属性信息,element元素信息包括种类、个数,property属性信息包括属性字段的存储类型和属性名。PLY文件中的元素一般包括顶点(vertex)、面(face)、边(edge)等。元素信息和属性信息应该组合出现,格式如下

element property property property

我们定义一个包含6个顶点和8个面元素的ply文件,文件头如下,

ply format ascii 1.0 comment made by anonymous comment this file is a cube element vertex 6 property float32 x property float32 y property float32 z property uchar red property uchar green property uchar blue element face 8 property list uint8 int32 vertex_index end_header 数据区域

在文件头后直接开始存储数据,存储形式分为ASCII和二进制。以ASCII为例,先按行记录每个点,全部点记录完成后再按行记录每个面。

0 0 0 0 0 0 (开始记录点,按照x,y,z,r,g,b方式排列) 0 100 0 0 0 0 100 100 0 0 0 0 100 0 0 0 0 0 50 50 75 255 255 255 50 50 -75 255 255 255 3 0 1 4 (开始记录面,按照点个数,点的序号排列,3表示这个面由3个点组成,0,1,4代表该面由第0,1,4个点组成) 3 1 2 4 3 2 3 4 3 0 3 4 3 0 1 5 3 1 2 5 3 2 3 5 3 0 3 5

所以完整的一个ply文件如下

ply format ascii 1.0 comment made by anonymous comment this file is a cube element vertex 6 property float32 x property float32 y property float32 z property uchar red property uchar green property uchar blue element face 8 property list uint8 int32 vertex_index end_header 0 0 0 0 0 0 0 100 0 0 0 0 100 100 0 0 0 0 100 0 0 0 0 0 50 50 75 255 255 255 50 50 -75 255 255 255 3 0 1 4 3 1 2 4 3 2 3 4 3 0 3 4 3 0 1 5 3 1 2 5 3 2 3 5 3 0 3 5 4.2、读写 4.2.1、使用plyfile读写(Python)

使用plyfile读取ply文件

from plyfile import PlyData,PlyElement file=r"C:\Users\123\Desktop\test2.ply" plydata=PlyData.read(file) print(plydata) print("*************************************************") #第一种读取方法 elements=plydata.elements for element in elements: for data in element.data: print(data) print("*************************************************") #第二种读取方法 vertex_data=elements[0].data face_data =elements[1].data print(vertex_data) print(face_data)

打印结果

ply format ascii 1.0 comment made by anonymous comment this file is a cube element vertex 6 property float x property float y property float z property uchar red property uchar green property uchar blue element face 8 property list uchar int vertex_index end_header ************************************************* (0., 0., 0., 0, 0, 0) (0., 100., 0., 0, 0, 0) (100., 100., 0., 0, 0, 0) (100., 0., 0., 0, 0, 0) (50., 50., 75., 255, 255, 255) (50., 50., -75., 255, 255, 255) (array([0, 1, 4]),) (array([1, 2, 4]),) (array([2, 3, 4]),) (array([0, 3, 4]),) (array([0, 1, 5]),) (array([1, 2, 5]),) (array([2, 3, 5]),) (array([0, 3, 5]),) ************************************************* [( 0., 0., 0., 0, 0, 0) ( 0., 100., 0., 0, 0, 0) (100., 100., 0., 0, 0, 0) (100., 0., 0., 0, 0, 0) ( 50., 50., 75., 255, 255, 255) ( 50., 50., -75., 255, 255, 255)] [(array([0, 1, 4]),) (array([1, 2, 4]),) (array([2, 3, 4]),) (array([0, 3, 4]),) (array([0, 1, 5]),) (array([1, 2, 5]),) (array([2, 3, 5]),) (array([0, 3, 5]),)]

使用plyfile写入ply文件

def write_ply(output_file,text=True): points=[ (0,0,0), (0,100,0), (100,100,0), (100,0,0), (50,50,75) ] face=np.array([ ((0,1,2),255,0,0), ((0,2,3),255,0,0), ((0, 1, 4),0,255,0), ((1,2,4),0,0,255), ((2,3,4),255,255,0), ((0,3,4),0,0,0)], dtype=[('vertex_index','i4',(3,)), ('red','u1'),('green','u1'), ('blue','u1')] ) print(face) vertex = np.array(points, dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')]) el = PlyElement.describe(vertex, 'vertex') face = PlyElement.describe(face, 'face') PlyData([el,face], text=text).write(out_file)

在meshlab中打开

4.2.2、使用pcl读写(C++)

读取ply点云文件

#include #include #include #include #include using namespace std; int main() { string ply_file = "C:\\Users\\123\\Desktop\\test7.ply"; pcl::PointCloud::Ptr cloud(new pcl::PointCloud); if (pcl::io::loadPLYFile(ply_file,*cloud)==-1) { return (-1); } cout string ply_file = "test2.ply"; pcl::PointCloud cloud; int data[11][6] = { {8,5,3,255,0,0}, {9,0,1,255,0,0}, {2,5,3,0,255,0}, {0,4,2,0,255,0}, {7,2,9,0,0,255}, {8,8,4,0,0,255}, {9,5,8,255,0,255}, {2,5,9,255,0,255}, {0,7,5,255,255,0}, {11,2,8,255,255,0}, {10,9,0,255,255,0}}; cloud.width = 11; cloud.height = 1; cloud.is_dense = false; cloud.points.resize(cloud.width*cloud.height); for (size_t i = 0; i


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有