我正在尝试为两个参数函数(点数据云)构建网格,并使用 Python 将其保存为 .ply 文件。
输入:3D 空间(x,y,z)中的数百万个数据点, 其中z可以视为数学函数z=f(x,y)的值
- 如何构建表示该点云的 3D 绘图表面的网格?
- 并将其导出为 3D 模型?
所需输出:包含网格的.PLY文件。
对于第 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(),
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', subject,
'lh.pial_reindex.ply')
rr, tris = mne.read_surface(surf_fname)
write_surf2ply(rr, tris, 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 文件?