如何解决为两个参数的函数点数据云构建一个网格,然后使用Python将其另存为.ply文件
我正在尝试为两个参数的函数(点数据云)构建网格,并使用Python将其另存为.ply文件。
输入:3D空间中的数百万个数据点(x,y,z) 其中 z 可被视为数学函数的值 z = f(x,y)
- 如何构建表示该点云的3D绘图表面的网格?
- 并将其导出为3D模型?
对于步骤2,我具有以下功能:
def savepoly(filename,arrayOfXYZ):
xyz = np.array(arrayOfXYZ)
x_points = xyz[:,0]
y_points = xyz[:,1]
z_points = xyz[:,2]
# Write header of .ply file
fid = open(filename,'wb')
fid.write(bytes('ply\n','utf-8'))
fid.write(bytes('format binary_little_endian 1.0\n','utf-8'))
fid.write(bytes('element vertex %d\n' % x_points.shape[0],'utf-8'))
fid.write(bytes('property float x\n','utf-8'))
fid.write(bytes('property float y\n','utf-8'))
fid.write(bytes('property float z\n','utf-8'))
fid.write(bytes('property uchar red\n','utf-8'))
fid.write(bytes('property uchar green\n','utf-8'))
fid.write(bytes('property uchar blue\n','utf-8'))
fid.write(bytes('end_header\n','utf-8'))
rgb_points = np.ones(x_points.shape).astype(np.uint8) * 255
# Write 3D points to .ply file
for i in range(x_points.shape[0]):
fid.write(bytearray(struct.pack("fffccc",x_points[i],y_points[i],z_points[i],rgb_points[i].tobytes(),rgb_points[i].tobytes()
)))
fid.close()
print(fid)
但是那个只保存顶点,没有曲面。
以下代码将三角形保存为.ply,但我不确定 tris 是什么首先如何构建三角形:
"""
plyfun
@author:wronk
Write surface to a .ply (Stanford 3D mesh file) in a way that preserves
vertex order in the MNE sense. Extendable for colors or other vertex/face properties.
.ply format: https://en.wikipedia.org/wiki/PLY_(file_format)
"""
import mne
import numpy as np
from os import path as op
import os
from os import environ
def write_surf2ply(rr,tris,save_path):
out_file = open(save_path,'w')
head_strs = ['ply\n','format ascii 1.0\n']
ele_1 = ['element vertex ' + str(len(rr)) + '\n','property float x\n','property float y\n','property float z\n']
ele_2 = ['element face ' + str(len(tris)) + '\n','property list uchar int vertex_index\n']
tail_strs = ['end_header\n']
# Write Header
out_file.writelines(head_strs)
out_file.writelines(ele_1)
out_file.writelines(ele_2)
out_file.writelines(tail_strs)
##############
# Write output
##############
# First,write vertex positions
for vert in rr:
out_file.write(str(vert[0]) + ' ')
out_file.write(str(vert[1]) + ' ')
out_file.write(str(vert[2]) + '\n')
# Second,write faces using vertex indices
for face in tris:
out_file.write(str(3) + ' ')
out_file.write(str(face[0]) + ' ')
out_file.write(str(face[1]) + ' ')
out_file.write(str(face[2]) + '\n')
out_file.close()
if __name__ == '__main__':
struct_dir = op.join(environ['SUBJECTS_DIR'])
subject = 'AKCLEE_139'
surf_fname = op.join(struct_dir,subject,'surf','lh.pial')
save_path = op.join('/media/Toshiba/Blender/Brains','lh.pial_reindex.ply')
rr,tris = mne.read_surface(surf_fname)
write_surf2ply(rr,save_path)
对于步骤1:
以下文章生成了网格,但(a)它是通用点数据云,而z = f(x,y)此处就足够了,(b)假设输入中包含法线数组: https://towardsdatascience.com/5-step-guide-to-generate-3d-meshes-from-point-clouds-with-python-36bad397d8ba,仍然需要构建。
总而言之:
是否有一种简单的方法可以使用Python为庞大的点云数据构建网格,其中z坐标是(x,y)的函数,然后将此网格导出到.ply文件?
解决方法
解决方案:
- 进口
import numpy as np
import scipy.spatial
import pandas as pd
- 使用点云数据加载csv文件:
df = pd.read_csv("data.csv")
print(df.columns)
x = df['column 0']
y = df['column 1']
z = df['column z values']
- 如有必要,对数据进行归一化以确保网格正确位于轴原点中:
x0 = x[0]
y0 = y[0]
z0 = z[0]
pointslist = []
for i in range(len(x)):
xi = (x[i] - x0) / 100
yi = (y[i] - y0) / 4
zi = (z[i] - z0) / 8
pointslist.append([xi,yi,zi]) # array of triplets
xyz = np.array(pointslist)
- 由于 z = f(x,y),因此我们无需使用通用三角剖分,并且可以将Delaunay算法用于2D数据点集。
# xyz = np.random.random((12,3)) # arbitrary 3D data set
# xyz = np.array([[0,1],[0,1,[1,0.5,0],0]]) # smaller data set for testing
# print(data)
mesh = scipy.spatial.Delaunay(xyz[:,:2]) # take the first two dimensions
# print(mesh.points)
# print(mesh.convex_hull)
# print(mesh.vertex_to_simplex)
#
# x = xyz[:,0]
# y = xyz[:,1]
# z = xyz[:,2]
- 网格已准备好,三角形作为顶点索引存储在 mesh.simplices 中。使用以下功能将所有内容保存到 .PLY 文件中:
writeSurface2PLY(xyz,mesh.simplices,"output.ply")
def writeSurface2PLY(vertices,meshanglesAsVertexIndices,save_path):
out_file = open(save_path,'w')
head_strs = ['ply\n','format ascii 1.0\n']
ele_1 = ['element vertex ' + str(len(vertices)) + '\n','property float x\n','property float y\n','property float z\n']
ele_2 = ['element face ' + str(len(meshanglesAsVertexIndices)) + '\n','property list uchar int vertex_index\n']
tail_strs = ['end_header\n']
# Write Header
out_file.writelines(head_strs)
out_file.writelines(ele_1)
out_file.writelines(ele_2)
out_file.writelines(tail_strs)
##############
# Write output
##############
# First,write vertex positions
for vert in vertices:
out_file.write(str(vert[0]) + ' ')
out_file.write(str(vert[1]) + ' ')
out_file.write(str(vert[2]) + '\n')
# Second,write faces using vertex indices
for face in meshanglesAsVertexIndices:
out_file.write(str(3) + ' ')
out_file.write(str(face[0]) + ' ')
out_file.write(str(face[1]) + ' ')
out_file.write(str(face[2]) + '\n')
out_file.close()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。