如何从.ply文件中读取初始三维图形数据

pavel_loyal 2007-11-19 09:37:03
在很多书上介绍的三维图形数据都是.obj,3ds格式,.dxf等格式的,真正讲解如何读取的就只有.obj格式文件的。但是我现在所做的内容,要求从.ply文件中读取初始塞维图形数据,这我就不会了,虽然对.ply文件格式有了了解:

Ply文件格式是Stanford大学开发的一套三维mesh模型数据格式,图形学领域内很多著名的模型数据,比如Stanford的三维扫描数据库(其中包括很多文章中会见到的Happy Buddha、Dragon、Bunny兔子),Geogia Tech的大型几何模型库,北卡(UNC)的电厂模型等,最初的模型都是基于这个格式的。

PLY多边形文件格式的开发目标是建立一套针对多边形模型的,结构简单但是能够满足大多数图形应用需要的模型格式,而且它允许以ASCII码格式或二进制形式存储文件。PLY的开发者希望,这样一套既简单又灵活的文件格式,能够帮助开发人员避免重复开发文件格式的问题。然而由于各种各样的原因,在工业领域内,新的文件格式仍然在不断的出现,但是在图形学的研究领域中,PLY还是种常用且重要的文件格式。

PLY作为一种多边形模型数据格式,不同于三维引擎中常用的场景图文件格式和脚本文件,每个PLY文件只用于描述一个多边形模型对象(Object),该模型对象可以通过诸如顶点、面等数据进行描述,每一类这样的数据被称作一种元素(Element)。相比于现代的三维引擎中所用到的各种复杂格式,PLY实在是种简单的不能再简单的文件格式,但是如果仔细研究就会发现,就像设计者所说的,这对于绝大多数的图形应用来说已经是足够用了。

PLY的文件结构同样很简单:文件头加上元素数据列表。其中文件头中以行为单位描述文件类型、格式与版本、元素类型、元素的属性等,然后就根据在文件头中所列出元素类型的顺序及其属性,依次记录各个元素的属性数据。

请教高人如何读取啊!!谢谢
...全文
2467 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
wooutsider 2012-03-28
  • 打赏
  • 举报
回复
很受用,明白了ply数据的格式,很感谢
kingoftime3 2009-03-05
  • 打赏
  • 举报
回复
典型的 PLY 文件结构:

头部
顶点列表
面片列表
(其他元素列表)

头部是一系列以回车结尾的文本行,用来描述文件的剩余部分。头部包含一个对每个元素类型的描述,包括元素名(如“边”),这个元素在工程里有多少,以及一 个与这个元素关联的不同属性的列表。头部还说明这个文件是二进制的或者是ASCII的。头部后面的是一个每个元素类型的元素列表,按照在头部中描述的顺序 出现。

下面是一个立方体的完整ASCII描述。相同工程的二进制版本头部的唯一不同是用词“binary_little_endian”或者 “binary_big_endian”替换词“ascii”。大括号中的注释不是文件的一部分,它们是这个例子的注解。文件中的注释一般在 “comment”开始的关键词定义行里。

ply
format ascii 1.0 { ascii/二进制,格式版本数 }
comment made by anonymous { 注释关键词说明,像其他行一样 }
comment this file is a cube
element vertex 8 { 定义“vertex”(顶点)元素,在文件中有8个 }
property float32 x { 顶点包含浮点坐标“x”}
property float32 y { y 坐标同样是一个顶点属性 }
property float32 z { z 也是坐标 }
element face 6 { 在文件里有6个“face”(面片) }
property list uint8 int32 vertex_index { “vertex_indices”(顶点素引)是一列整数 }
end_header { 划定头部结尾 }
0 0 0 { 顶点列表的开始 }
0 0 1
0 1 1
0 1 0
1 0 0
1 0 1
1 1 1
1 1 0
4 0 1 2 3 { 面片列表开始 }
4 7 6 5 4
4 0 4 5 1
4 1 5 6 2
4 2 6 7 3
4 3 7 4 0

这个例子说明头部的基本组成。头部的每个部分都是以一个关键词开头以回车结尾的ASCII串。即使是头部的开始和结尾(“ply”和 “end_header”)也是以这种形式。因为字符“ply”是文件的魔法数字,必须是文件的头四个字符。跟在文件头部开头之后的是关键词 “format”和一个特定的ASCII或者二进制的格式,接下来是一个版本号。再下面是多边形文件中每个元素的描述,在每个元素里还有多属性的说明。一 般元素以下面的格式描述:

element <元素名> <在文件中的个数>
property <数据类型> <属性名-1>
property <数据类型> <属性名-2>
property <数据类型> <属性名-3>
...

属性罗列在“element”(元素)行后面定义,既包含属性的数据类型也包含属性在每个元素中出现的次序。一个属性可以有三种数据类型:标量,字符串和列表。属性可能具有的标量数据类型列表如下:

名称 类型 字节数
-------------------------------
int8 字符 1
uint8 非负字符 1
int16 短整型 2
uint16 非负短整型 2
int32 整型 4
uint32 非负整型 4
float32 单精度浮点数 4
float64 双精度浮点数 8

这些字节计数很重要,而且在实现过程中不能修改以使这些文件可移植。使用列表数据类型的属性定义有一种特殊的格式:

property list <数值类型> <数值类型> <属性名>

这种格式的一类例子是上面的立方体文件中的:

property list uint8 int32 vertex_index

这表示属性“vertex_index”首先包含一个非负字符报苏在属性里包含多少索引,接下来是一个列表包含许多整数。在这个边长列表里的每个整数都是一个顶点的索引。

另外一个例子
------------

另外一个立方体定义:

ply
format ascii 1.0
comment author: anonymous
comment object: another cube
element vertex 8
property float32 x
property float32 y
property float32 z
property red uint8 { 顶点颜色开始 }
property green uint8
property blue uint8
element face 7
property list uint8 int32 vertex_index { 每个面片的顶点个数 }
element edge 5 { 物体里有5条边 }
property int32 vertex1 { 边的第一个顶点的索引 }
property int32 vertex2 { 第二个顶点的索引 }
property uint8 red { 边颜色开始 }
property uint8 green
property uint8 blue
end_header
0 0 0 255 0 0 { 顶点列表开始 }
0 0 1 255 0 0
0 1 1 255 0 0
0 1 0 255 0 0
1 0 0 0 0 255
1 0 1 0 0 255
1 1 1 0 0 255
1 1 0 0 0 255
3 0 1 2 { 面片列表开始,从一个三角形开始 }
3 0 2 3 { 另一个三角形 }
4 7 6 5 4 { 现在是一些四边形 }
4 0 4 5 1
4 1 5 6 2
4 2 6 7 3
4 3 7 4 0
0 1 255 255 255 { 边列表开始,从白边开始 }
1 2 255 255 255
2 3 255 255 255
3 0 255 255 255
2 0 0 0 0 { 以一个黑线结束 }

这个文件为每个顶点指定一个红、绿、蓝值。为了说明变长vertex_index(顶点索引)的能力,物体的头两个面片是两个三角形而不是一个四边形。这 意味着物体的面片数是7。这个物体还包括一个边列表。每条边包括两个指向说明边的顶点的指针。每条边也有一种颜色。上面定义的五条边指定了颜色,使文件里 的两个三角形高亮。前四条边白色,它们包围两个三角形。最后一条边是黑的,他是分割三角形的边。

用户定义元素
------------

上面的例子显示了顶点、面片和边三种元素的用法。PLY 格式同样允许用户定义它们自己的元素。定义新元素的格式于顶点、面片和边相同。这是头部定义材料属性的部分:

element material 6
property ambient_red uint8 { 环绕颜色 }
property ambient_green uint8
property ambient_blue uint8
property ambient_coeff float32
property diffuse_red uint8 { 扩散(diffuse)颜色 }
property diffuse_green uint8
property diffuse_blue uint8
property diffuse_coeff float32
property specular_red uint8 { 镜面(specular)颜色 }
property specular_green uint8
property specular_blue uint8
property specular_coeff float32
property specular_power float32 { Phong 指数 }

这些行应该在头部顶点、面片和边的说明后直接出现。如果我们希望每个顶点有一个材质说明,我们可以将这行加在顶点属性末尾:

property material_index int32

这个整数现在是一个到文件内包含的材质列表的索引。这可能诱使一个新应用的作者编制一些信的元素保存在 PLY 文件中。这个练习应该保持在最小。试着将普通元素(顶点、面片、边、材质)改编用于新用途更好,使得其他能够读懂这些元素的程序在操作这些改编过的元素时 更有用。比如,一个将分子描述成球体和圆柱体集合的应用。这将需要在包含分子的 PLY 文件里定义球体和圆柱体元素。然而,如果我们为了这个目的使用顶点和边元素(为每个添加半径属性),我们可以利用操作和显示顶点和边的程序。无疑不应该为 三角形和四边形创建特殊元素,而应该使用面片元素。
pavel_loyal 2007-11-20
  • 打赏
  • 举报
回复
怎么没人回答啊!!真的很急啊!!
【资源说明】 基于C和C++实现的单目多视图立体重建系统源码+项目说明.zip * 数据读取 * 特征点提取和匹配 * 稀疏重建,生成稀疏点云以及估计视图位姿 * 稠密重建,生成每张视图对应的深度图(这里可以进一步生成稠密点云,通过深度图) 数据读取 主要读取输入视图数据,对于无内参的图,并估计内参(采用张正友相机标定法)。 特征点提取和匹配 * 特征点提取,本项目采用两种特征提取方法,STIF算法和ORB,你可以根据自己的数据和时间要求进行选择,同时你也可以采用一些神经网络的方法来代替此方法。 * 特征点匹配,对于不同的数据量,实则有三种匹配方法,这里只提供第一种: * 对于输入图片属于非连续稀疏图片,采用两两匹配的方式,注意这里不用全部两两匹配,例如A-B匹配完,不用再执行B-A匹配。匹配示意图类似于上三角矩阵。只用匹配对角线以上或者以下的图像对,降低匹配时间。 * 对于连续时间帧图片,采用和相邻时间帧图片进行匹配。例如匹配 [t-50,t+50]区间之间的。 * 对于大数据量图片进行匹配,需要采用词汇树进行匹配。降低匹配复杂度。 以上匹配均采用多线程实现 稀疏重建 本项目给的示例代码是全局增量重建代码,主要分为以下步骤: 1.计算每个图像特征点的Track,也就是图像每个特征点和几个其他图像特征点对应。为了让重建结果更加鲁棒,对于Track小于阈值的特征点进行滤除。 2.建立图像之间的Edge,滤出图像间Track对大于一定阈值的建立Edge 3.选取重建初始图像对,这里选取的思想是,sum=0.6*AB+0.2*A+0.2*B;这里AB是A图像和B图像对应特征点的个数,A是A图像与所有其他图像特征点的个数和,B是B图像与所有其他图像特征点的个数和。取sum最大的图像对。同时该图像对应该满足夹角在一定阈值范围里,保证三角化计算不会有太大误差。 4.三角化求取三维点云信息,这里对于步骤三选取的图像对,选取其与其他图像特征点数最大的图像的相机位置作为世界坐标系,然后通过分解本质矩阵求解另一个图像的位姿信息进行三角化。 5.选取一下一张待重建图像,这个选取的标准是,下一张待重建图像对应该满足特征点数和已重建的三维点交集最大。可以保证通过PNP方法求取初始值相对正确的相机位姿。 6.进行bundle_adjuestment。这里需要对三维点云进行预处理,淘汰那些重投影误差大于一定阈值的三维点,淘汰相机参数不合理的图像。防止在bundle_adjuestment过程拉偏优化方向。主要借助Ceres库实现,Ceres库主要是一些优化算法例如牛顿高斯法,LM算法等等,借助最小二乘法和泰勒展开去计算让代价函数值最小的变量移动方向和步长。 7.继续重复第5-6步,直到没有合适的图像 8.保存将相机位姿和三维点云 9.对重建结果进行评价,通过.ply文件直接肉眼查看重建状是否正确,也可以通过统计重投影误差的平均值、最大值、最小值、方差来进行评价。 稠密重建 稠密重建阶段,本项目采用的是patchMatchStereo的方法,为了提高速度通过CUDA实现并行处理。 在稀疏重建阶段已经实现了图像位姿的求解,因此本项目没有采用传统PatchMatchStereo极线对齐的方法,而且是通过单应矩阵来计算对应同名点,并且支持多视图PatchMatchStereo。其一些实现方法参考了《Massively Parallel Multiview Stereopsis by Surface Normal Diffusion》这篇论文。核心算法主要有四个部分: * 多视图代价计算:在此部分,代价计算的方式和原始的PatchMatchStereo一致。对于多视图代价计算,通过计算参考视图和每个其他视图之间的代价,淘汰不满足阈值的代价,并求其平均值,作为最终代价。 * 空间传播:考虑到原始的PatchMatchStereo算法需要通过左上和右下来传播,但是对于并行计算无法实现,因此应该红黑块的方法。 * RefinePlane:和原始的PatchMatch 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!
【资源说明】 基于C++实现的单目多视图立体重建系统源码+项目说明.zip 1、该资源内项目代码都是经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能。 单目多视图立体重建系统,此项目是针对单目多视图立体重建的方法。本项目从分为四个部分:** * 数据读取 * 特征点提取和匹配 * 稀疏重建,生成稀疏点云以及估计视图位姿 * 稠密重建,生成每张视图对应的深度图(这里可以进一步生成稠密点云,通过深度图) ### 数据读取 主要读取输入视图数据,对于无内参的图,并估计内参(采用张正友相机标定法)。 ### 特征点提取和匹配 * 特征点提取,本项目采用两种特征提取方法,STIF算法和ORB,你可以根据自己的数据和时间要求进行选择,同时你也可以采用一些神经网络的方法来代替此方法。 * 特征点匹配,对于不同的数据量,实则有三种匹配方法,这里只提供第一种: * 对于输入图片属于非连续稀疏图片,采用两两匹配的方式,注意这里不用全部两两匹配,例如A-B匹配完,不用再执行B-A匹配。匹配示意图类似于上三角矩阵。只用匹配对角线以上或者以下的图像对,降低匹配时间。 * 对于连续时间帧图片,采用和相邻时间帧图片进行匹配。例如匹配 [t-50,t+50]区间之间的。 * 对于大数据量图片进行匹配,需要采用词汇树进行匹配。降低匹配复杂度。 以上匹配均采用多线程实现 ### 稀疏重建 本项目给的示例代码是全局增量重建代码,主要分为以下步骤: 1.计算每个图像特征点的Track,也就是图像每个特征点和几个其他图像特征点对应。为了让重建结果更加鲁棒,对于Track小于阈值的特征点进行滤除。 2.建立图像之间的Edge,滤出图像间Track对大于一定阈值的建立Edge 3.选取重建初始图像对,这里选取的思想是,sum=0.6*AB+0.2*A+0.2*B;这里AB是A图像和B图像对应特征点的个数,A是A图像与所有其他图像特征点的个数和,B是B图像与所有其他图像特征点的个数和。取sum最大的图像对。同时该图像对应该满足夹角在一定阈值范围里,保证三角化计算不会有太大误差。 4.三角化求取三维点云信息,这里对于步骤三选取的图像对,选取其与其他图像特征点数最大的图像的相机位置作为世界坐标系,然后通过分解本质矩阵求解另一个图像的位姿信息进行三角化。 5.选取一下一张待重建图像,这个选取的标准是,下一张待重建图像对应该满足特征点数和已重建的三维点交集最大。可以保证通过PNP方法求取初始值相对正确的相机位姿。 6.进行bundle_adjuestment。这里需要对三维点云进行预处理,淘汰那些重投影误差大于一定阈值的三维点,淘汰相机参数不合理的图像。防止在bundle_adjuestment过程拉偏优化方向。主要借助Ceres库实现,Ceres库主要是一些优化算法例如牛顿高斯法,LM算法等等,借助最小二乘法和泰勒展开去计算让代价函数值最小的变量移动方向和步长。 7.继续重复第5-6步,直到没有合适的图像 8.保存将相机位姿和三维点云 9.对重建结果进行评价,通过.ply文件直接肉眼查看重建状是否正确,也可以通过统计重投影误差的平均值、最大值、最小值、方差来进行评价。 ### 稠密重建 稠密重建阶段,本项目采用的是patchMatchStereo的方法,为了提高速度通过CUDA实现并行处理。 在稀疏重建阶段已经实现了图像位姿的求解,因此本项目没有采用传统PatchMatchStereo极线对齐的方法,而且是通过单应矩阵来计算对应同名点,并且支持多视图PatchMatchStereo。其一些实现方法参考了《Massively Parallel Multiview Stereopsis by Surface Normal Diffusion》这篇论文。核心算法主要有四个部分: * 多视图代价计算:在此部分,代价计算的方式和原始的PatchMatchStereo一致。对于多视图代价计算,通过计算参考视图和每个其他视图之间的代价,淘汰不满足阈值的代价,并求其平均值,作为最终代价。 * 空间传播:考虑到原始的PatchMatchStereo算法需要通过左上和右下来传播,但是对于并行计算无法实现,因此应该红黑块的方法。
dll函数接口: ////******** 初始化默认参数 ********// //extern "C" int __stdcall ZSY3DViewerInit(); //******** 读取历史数据到cloud ********// extern "C" int __stdcall ZSY3DReadHistoryData(char *file_dir); //******** 读取txt数据到cloud ********// extern "C" int __stdcall ZSY3DReadTxtData(char *file_dir); //******** 读取单个点数据到cloud ********// extern "C" int __stdcall ZSY3DReadSingleData(float x, float y, float z); //******** 读取所有点数据到cloud ********// extern "C" int __stdcall ZSY3DReadNowData(float *x, float *y, float *z, int count); //******** vtk读取txt文件并显示 ********// extern "C" int __stdcall ZSY3DReadFile_TXT(char *file_dir); //******** vtk读取obj文件并显示 ********// extern "C" int __stdcall ZSY3DReadFile_OBJ(char *file_dir); //******** vtk读取vtk文件并显示 ********// extern "C" int __stdcall ZSY3DReadFile_VTK(char *file_dir); //******** vtk读取ply文件并显示 ********// extern "C" int __stdcall ZSY3DReadFile_PLY(char *file_dir); //******** cloud下采样处理 ********// extern "C" int __stdcall ZSY3DDownSampling(float leaf_size); //******** cloud均匀采样处理 ********// extern "C" int __stdcall ZSY3DBalanceSampling(float radiusSearch = 0.01f); //******** cloud增采样处理 ********// extern "C" int __stdcall ZSY3DIncreaseSampling(float radius = 0.03f, float StepSize = 0.02f); //******** cloud直通滤波采样处理 ********// extern "C" int __stdcall ZSY3DStraightSampling(char *fieldName = "z", float limits_min = 0.0f, float limits_max = 0.1f, bool limitsNegative = true); //******** cloud统计滤波采样处理 ********// extern "C" int __stdcall ZSY3DStatisticsSampling(float meanK = 50.0f,float stddevMulThresh = 1.0f); //******** cloud半径滤波采样处理 ********// extern "C" int __stdcall ZSY3DRadiusSampling(float radiusSearch = 0.8f, float minNeighborsInRadius = 2.0f); //******** cloud数据进行渲染,并显示 ********// extern "C" int __stdcall ZSY3DShowPointCloud(); //******** cloud数据进行VTK三维重建(三角面绘制),并显示 ********// extern "C" int __stdcall ZSY3DDelaunayBuild(bool depth_color); //******** cloud数据进行VTK三维重建(曲面体绘制),并显示 ********// extern "C" int __stdcall ZSY3DSurfaceBu

19,469

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧