点云数据之间的格式转换是将点云数据从一种文件格式转换为另一种文件格式的过程。点云数据通常用于表示物体表面的三维点的集合,这些数据在计算机图形学、计算机视觉、3D建模等领域有广泛应用。常见的点云文件格式包括PLY、PCD、BIN、TXT、OBJ等。接下来将介绍不同点云格式之间的转换方法。
PLY转其他格式
PLY转PCD
我们以斯坦福三维扫描数据库中的bunny.ply
为例进行介绍,首先是在网上获取该数据并将其保存到同级目录中。
import os
import urllib.request
import tarfile
import open3d as o3d
import shutil
# 下载并解压Stanford Bunny数据集
url = "http://graphics.stanford.edu/pub/3Dscanrep/bunny.tar.gz"
download_path = "bunny.tar.gz"
extract_folder = "bunny"
target_ply_file = "bunny.ply"
# 下载数据集
if not os.path.exists(download_path):
print("Downloading Stanford Bunny dataset...")
urllib.request.urlretrieve(url, download_path)
print("Download complete.")
# 解压数据集
if not os.path.exists(extract_folder):
print("Extracting Stanford Bunny dataset...")
with tarfile.open(download_path, "r:gz") as tar:
tar.extractall(path=extract_folder)
print("Extraction complete.")
# 查找点云文件
point_cloud_file = None
for root, dirs, files in os.walk(extract_folder):
for file in files:
if file.endswith(".ply"):
point_cloud_file = os.path.join(root, file)
break
if point_cloud_file:
print(f"Point cloud file found: {point_cloud_file}")
# 复制PLY文件到同级目录
shutil.copy(point_cloud_file, target_ply_file)
print(f"PLY file copied to: {target_ply_file}")
# 使用Open3D加载点云文件
pcd = o3d.io.read_point_cloud(target_ply_file)
print(pcd)
# 可视化点云
o3d.visualization.draw_geometries([pcd])
else:
print("Point cloud file not found.")
使用python对ply格式的点云转换成pcd:
import open3d as o3d
# 读取PLY文件
ply_point_cloud = o3d.io.read_point_cloud("bunny.ply")
# 检查点云是否正确加载
if ply_point_cloud.is_empty():
print("Failed to load the point cloud from bunny.ply")
else:
# 保存为PCD文件
o3d.io.write_point_cloud("bunny.pcd", ply_point_cloud)
print("Successfully converted bunny.ply to bunny.pcd")
PLY转TXT
import open3d as o3d
import numpy as np
import os
# 读取PLY文件
ply_file = "bunny.ply"
txt_file = "bunny.txt"
# 检查PLY文件是否存在
if not os.path.exists(ply_file):
print(f"File {ply_file} not found.")
else:
# 读取PLY文件
ply_point_cloud = o3d.io.read_point_cloud(ply_file)
# 检查点云数据是否正确加载
if ply_point_cloud.is_empty():
print("Failed to load the point cloud from bunny.ply")
else:
# 获取点云数据
points = np.asarray(ply_point_cloud.points)
# 保存为TXT文件
try:
np.savetxt(txt_file, points)
print(f"Successfully saved point cloud to {txt_file}")
except Exception as e:
print(f"Error saving point cloud to {txt_file}: {e}")
PLY转BIN
import open3d as o3d
import numpy as np
import struct
# 读取PLY文件
ply_point_cloud = o3d.io.read_point_cloud("bunny.ply")
# 获取点云数据
points = np.asarray(ply_point_cloud.points)
# 保存为BIN文件
with open("bunny.bin", "wb") as bin_file:
for point in points:
bin_file.write(struct.pack('fff', *point))
PLY转OBJ
import open3d as o3d
import numpy as np
# 读取PLY文件
ply_point_cloud = o3d.io.read_point_cloud("bunny.ply")
# 计算点云法线
ply_point_cloud.estimate_normals(
search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.1, max_nn=30)
)
# 将点云转换为三角网格
distances = ply_point_cloud.compute_nearest_neighbor_distance()
avg_dist = np.mean(distances)
radius = 3 * avg_dist
# 使用Ball Pivoting算法创建三角网格
bpa_mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_ball_pivoting(
ply_point_cloud,
o3d.utility.DoubleVector([radius, radius * 2]))
# 计算法线
bpa_mesh.compute_vertex_normals()
# 保存为OBJ文件(顶点法线信息存储在注释中)
with open("bunny.obj", "w") as f:
f.write("# OBJ file created by Open3D\n")
for v in bpa_mesh.vertices:
f.write("v {} {} {}\n".format(v[0], v[1], v[2]))
for vn in bpa_mesh.vertex_normals:
f.write("vn {} {} {}\n".format(vn[0], vn[1], vn[2]))
for face in bpa_mesh.triangles:
f.write("f {}/{} {}/{} {}/{}\n".format(
face[0] + 1, face[0] + 1, face[1] + 1, face[1] + 1, face[2] + 1, face[2] + 1))
print("OBJ file created successfully: bunny.obj")
# 可视化点云和三角网格
o3d.visualization.draw_geometries([ply_point_cloud], window_name="Original Point Cloud")
o3d.visualization.draw_geometries([bpa_mesh], window_name="Triangle Mesh")
其他格式转PLY
可以使用trimesh
库对PLY文件转换成PCD、TXT、BIN、OBJ等格式时,通常需要先进行表面重建。这是因为PLY文件通常包含的不仅仅是点云数据,还可能包含面和法线等信息,而这些信息在转换为其他格式时需要处理和保存。而表面重建可以将点云数据转换为有组织的三角网格,这样可以更好地保留几何结构和表面细节,从而在转换为其他格式时保持数据的完整性和准确性。
实际上得到的ply点云缺失数据较多,因此此处先不详细介绍如何优化,后面会通过点云处理库进一步优化数据转换质量。
PCD转PLY
import open3d as o3d
# 读取PCD文件
pcd = o3d.io.read_point_cloud("bunny.pcd")
# 保存为PLY文件
o3d.io.write_point_cloud("bunny_from_pcd.ply", pcd)
print("bunny_from_pcd.ply created successfully.")
TXT转PLY
import open3d as o3d
import numpy as np
# 读取TXT文件
points = np.loadtxt("bunny.txt")
# 创建Open3D点云对象
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(points)
# 保存为PLY文件
o3d.io.write_point_cloud("bunny_from_txt.ply", pcd)
print("bunny_from_txt.ply created successfully.")
BIN转PLY
import open3d as o3d
import numpy as np
import struct
# 读取BIN文件
points = []
with open("bunny.bin", "rb") as f:
while True:
bytes = f.read(12)
if not bytes:
break
points.append(struct.unpack('fff', bytes))
points = np.array(points)
# 创建Open3D点云对象
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(points)
# 保存为PLY文件
o3d.io.write_point_cloud("bunny_from_bin.ply", pcd)
print("bunny_from_bin.ply created successfully.")
OBJ转PLY
import open3d as o3d
# 读取OBJ文件
mesh = o3d.io.read_triangle_mesh("bunny.obj")
pcd = mesh.sample_points_uniformly(number_of_points=100000)
# 保存为PLY文件
o3d.io.write_point_cloud("bunny_from_obj.ply", pcd)
print("bunny_from_obj.ply created successfully.")
以上内容总结自网络,如有帮助欢迎关注与转发,我们下次再见!