使用 Open3D 从点云生成网格并保存问题

问题描述 投票:0回答:1

我有一个根据一些图像计算的点云,我试图从该点生成一个网格(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 值合适吗? 任何帮助将不胜感激!谢谢。 ❤️

python 3d point-clouds open3d 3d-reconstruction
1个回答
0
投票

在不知道你的点云是什么样子的情况下很难知道发生了什么,但我的猜测是你的 alpha 值太小而无法生成包络,所以你试图保存一个空网格。

这个有什么作用?

saved = o3d.io.write_triangle_mesh(file_path, mesh, print_progress=True)
if saved:
    print("Mesh saved successfully")
else:
    print("Something went wrong")

© www.soinside.com 2019 - 2024. All rights reserved.