我有一个根据一些图像计算的点云,我试图从该点生成一个网格(3D 表面)。我可以成功创建点云,但我无法从该云创建网格并保存我创建的网格。我在下面分享了我的完整代码。
我使用的图书馆:
开放3D 数值模拟 Matplotlib 操作系统 追溯
import open3d as o3d
import numpy as np
import cv2
import matplotlib.pyplot as plt
import os
import traceback
def read_point_cloud(file_path):
try:
if not os.path.exists(file_path):
raise FileNotFoundError(f"Dosya bulunamadı: {file_path}")
if not os.access(file_path, os.R_OK):
raise PermissionError(f"Dosya erişim izni yok: {file_path}")
ply = o3d.io.read_point_cloud(file_path)
if ply.is_empty():
raise ValueError("Nokta bulutu boş veya geçersiz.")
return ply
except Exception as e:
print(f"Error in read_point_cloud: {e}")
traceback.print_exc()
raise
def generate_depth_map(points, width, height):
try:
depth_map = np.zeros((height, width), dtype=np.float32)
for point in points:
x, y, z = point
u = int(np.clip(x, 0, width - 1)) # Ölçekleme ve sınır kontrolü
v = int(np.clip(y, 0, height - 1)) # Ölçekleme ve sınır kontrolü
depth_map[v, u] = z
return depth_map
except Exception as e:
print(f"Error in generate_depth_map: {e}")
traceback.print_exc()
raise
def refine_depth_map(depth_map):
try:
min_val = np.min(depth_map)
max_val = np.max(depth_map)
print(f"Min depth value: {min_val}, Max depth value: {max_val}")
if max_val > min_val:
depth_map_normalized = (depth_map - min_val) / (max_val - min_val) * 255
else:
depth_map_normalized = np.zeros_like(depth_map)
depth_map_uint8 = np.clip(depth_map_normalized, 0, 255).astype(np.uint8)
return depth_map_uint8
except Exception as e:
print(f"Error in refine_depth_map: {e}")
traceback.print_exc()
raise
def plot_depth_map(depth_map):
try:
plt.imshow(depth_map, cmap='viridis')
plt.colorbar()
plt.title('Depth Map')
plt.show()
except Exception as e:
print(f"Error in plot_depth_map: {e}")
traceback.print_exc()
raise
def depth_map_to_point_cloud(depth_map):
try:
height, width = depth_map.shape
points = []
for v in range(height):
for u in range(width):
z = depth_map[v, u]
if z > 0: # Depth value should be positive
x = u
y = v
points.append([x, y, z])
points = np.array(points)
print(f"Number of valid points: {len(points)}")
if len(points) == 0:
raise ValueError("No valid points found to create point cloud.")
point_cloud = o3d.geometry.PointCloud()
point_cloud.points = o3d.utility.Vector3dVector(points)
return point_cloud
except Exception as e:
print(f"Error in depth_map_to_point_cloud: {e}")
traceback.print_exc()
raise
def point_cloud_to_mesh(point_cloud):
alpha = 0.1
mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_alpha_shape(point_cloud, alpha)
return mesh
def save_mesh(mesh, file_path):
print(f"Saving mesh to {file_path}")
try:
dir_name = os.path.dirname(file_path)
if not os.path.exists(dir_name):
os.makedirs(dir_name)
o3d.io.write_triangle_mesh(file_path, mesh)
print("Mesh saved successfully")
except Exception as e:
print(f"Error in save_mesh: {e}")
traceback.print_exc()
raise
def main():
file_path = './dataset/mini6.ply'
output_file_dir = './output/'
width, height = 640, 480
try:
ply = read_point_cloud(file_path)
points = np.asarray(ply.points)
depth_map = generate_depth_map(points, width, height)
refined_depth_map = refine_depth_map(depth_map)
depth_point_cloud = depth_map_to_point_cloud(refined_depth_map)
mesh = point_cloud_to_mesh(depth_point_cloud)
if not os.path.exists(output_file_dir):
os.makedirs(output_file_dir)
output_file = os.path.join(output_file_dir, "output_mesh.ply")
save_mesh(mesh, output_file)
except Exception as e:
print(f"Bir hata oluştu: {e}")
traceback.print_exc()
if __name__ == "__main__":
main()
我遇到的问题:
我可以成功创建点云,但即使 point_cloud_to_mesh 函数指示它已创建网格,但当我尝试保存创建的网格时遇到问题。在应该保存网格的地方,没有保存任何内容,或者看起来网格没有创建。
错误信息:
在网格创建过程中我没有收到任何错误消息,但是当我调用 save_mesh 函数时,网格文件不会保存。 问题:
我在网格创建或保存部分代码时犯了错误吗?您对此有何建议? 我不确定我是否正确使用了 create_from_point_cloud_alpha_shape 函数。在这种情况下 Alpha 值合适吗? 任何帮助将不胜感激!谢谢。 ❤️
在不知道你的点云是什么样子的情况下很难知道发生了什么,但我的猜测是你的 alpha 值太小而无法生成包络,所以你试图保存一个空网格。
这个有什么作用?
saved = o3d.io.write_triangle_mesh(file_path, mesh, print_progress=True)
if saved:
print("Mesh saved successfully")
else:
print("Something went wrong")