从深度图到 3D 网格与点云:完整实现

从深度图到 3D 网格与点云:完整实现

在计算机视觉与三维重建中,深度图提供了对场景中每个像素与相机之间距离的精确测量。结合深度图,我们可以将场景从 2D 图像转换为 3D 空间表示。通常,有两种常见的 3D 表示方法:点云网格(Mesh)。点云由散布在三维空间中的一组顶点组成,而网格通过连接顶点形成三角形面片,从而表示一个更完整的 3D 对象。

在本文中,我们将介绍如何从深度图生成点云和网格,并展示如何使用深度学习模型(如 MiDaS)进行深度图预测,以及如何处理和可视化生成的 3D 数据。


1. 深度图到 3D 点云

1.1 什么是点云?

点云是由多个点(每个点通常包含 x、y 和 z 坐标)构成的数据集,表示物体表面或场景的三维结构。在计算机视觉中,点云是由深度图或 LiDAR 等传感器生成的。点云提供了物体的几何形状,但通常没有连接点的三角面片信息,因此不像网格那样具有表面。

1.2 生成点云

生成点云的关键步骤是将深度图中的每个像素的深度值转换为对应的三维坐标,然后将这些坐标作为点云数据。假设我们已经获得了深度图及相机的内参,我们可以根据以下公式计算每个像素的 3D 坐标:
( X = ( x − c x ) ⋅ Z f x ) ( X = \frac{(x - c_x) \cdot Z}{f_x} ) (X=fx(x−cx)⋅Z)
( Y = ( y − c y ) ⋅ Z f y ) ( Y = \frac{(y - c_y) \cdot Z}{f_y} ) (Y=fy(y−cy)⋅Z)

其中, ( Z ) 是深度图中每个像素的深度值, f x f_x fx和 f y f_y fy是相机的焦距, c x c_x cx和 c y c_y cy是相机的光心坐标。

1.3 代码实现:深度图到点云

以下代码示例展示了如何将深度图转换为点云,并使用 Open3D 库进行可视化。

python 复制代码
import numpy as np
import open3d as o3d
import cv2

def depth_to_point_cloud(depth_image, intrinsics):
    """
    将深度图转换为点云
    :param depth_image: 深度图 (2D NumPy 数组)
    :param intrinsics: 相机内参 (Camera Intrinsics)
    :return: 点云 (open3d.geometry.PointCloud)
    """
    height, width = depth_image.shape
    
    # 获取相机内参
    fx, fy, cx, cy = intrinsics['fx'], intrinsics['fy'], intrinsics['cx'], intrinsics['cy']
    
    # 生成像素坐标网格
    x_coords, y_coords = np.meshgrid(np.arange(width), np.arange(height))
    
    # 根据深度图计算对应的3D坐标
    z_coords = depth_image / 1000.0  # 假设深度单位是毫米,转换为米
    x_coords = (x_coords - cx) * z_coords / fx
    y_coords = (y_coords - cy) * z_coords / fy
    
    # 将 3D 坐标转化为点 (x, y, z)
    points = np.stack((x_coords, y_coords, z_coords), axis=-1)
    
    # 扁平化点云
    points = points.reshape((-1, 3))
    
    # 创建 Open3D 点云对象
    point_cloud = o3d.geometry.PointCloud()
    point_cloud.points = o3d.utility.Vector3dVector(points)
    
    return point_cloud

# 假设你有深度图数据
depth_image = np.load('depth_image.npy')  # 这里是示例数据,深度图应为 numpy 数组

# 相机内参(假设为已知)
intrinsics = {
    'fx': 525.0,  # x轴焦距
    'fy': 525.0,  # y轴焦距
    'cx': 319.5,  # 光心x坐标
    'cy': 239.5   # 光心y坐标
}

# 将深度图转换为点云
point_cloud = depth_to_point_cloud(depth_image, intrinsics)

# 可视化生成的点云
o3d.visualization.draw_geometries([point_cloud])

在这个示例中,我们将深度图中的每个像素的深度值映射到三维空间中的坐标,然后将这些坐标作为点云对象展示。Open3D 提供了一个简单的接口来显示生成的点云。


2. 深度图到 3D 网格

相比于点云,网格通过将多个相邻的顶点连接成三角形面片,构建了一个完整的 3D 表面。我们将在这里介绍如何从深度图生成网格,而不使用点云。

2.1 生成网格

与生成点云相似,我们仍然需要将深度图的每个像素转换为 3D 坐标。接着,我们需要通过连接这些顶点形成三角形面片,以构建网格。

2.2 代码实现:深度图到网格
python 复制代码
def depth_to_mesh(depth_image, intrinsics):
    """
    将深度图转为网格
    :param depth_image: 深度图 (2D NumPy 数组)
    :param intrinsics: 相机内参 (Camera Intrinsics)
    :return: 网格 (open3d.geometry.TriangleMesh)
    """
    height, width = depth_image.shape
    
    # 获取相机内参
    fx, fy, cx, cy = intrinsics['fx'], intrinsics['fy'], intrinsics['cx'], intrinsics['cy']
    
    # 生成像素坐标网格
    x_coords, y_coords = np.meshgrid(np.arange(width), np.arange(height))
    
    # 根据深度图计算对应的3D坐标
    z_coords = depth_image / 1000.0  # 假设深度单位是毫米,转换为米
    x_coords = (x_coords - cx) * z_coords / fx
    y_coords = (y_coords - cy) * z_coords / fy
    
    # 将 3D 坐标转化为顶点 (x, y, z)
    vertices = np.stack((x_coords, y_coords, z_coords), axis=-1)
    
    # 扁平化顶点
    vertices = vertices.reshape((-1, 3))
    
    # 构建三角形面片
    triangles = []
    for i in range(height - 1):
        for j in range(width - 1):
            idx1 = i * width + j
            idx2 = i * width + (j + 1)
            idx3 = (i + 1) * width + j
            idx4 = (i + 1) * width + (j + 1)
            
            # 两个三角形,构成一个矩形面
            triangles.append([idx1, idx2, idx3])
            triangles.append([idx2, idx4, idx3])
    
    triangles = np.array(triangles)
    
    # 生成 Open3D 网格
    mesh = o3d.geometry.TriangleMesh()
    mesh.vertices = o3d.utility.Vector3dVector(vertices)
    mesh.triangles = o3d.utility.Vector3iVector(triangles)
    
    return mesh

# 将深度图转换为网格
mesh = depth_to_mesh(depth_image, intrinsics)

# 可视化生成的网格
o3d.visualization.draw_geometries([mesh])

该代码通过遍历深度图中的像素,计算每个像素对应的三维坐标,并通过相邻像素之间的连接构建网格。通过 Open3D 可视化,我们可以查看生成的 3D 网格。


3. 总结

本文介绍了如何从深度图生成 点云网格,并展示了如何使用深度学习模型(如 MiDaS)预测深度图。具体步骤如下:

  • 深度图到点云 :将深度图的每个像素映射为 3D 坐标,并通过 Open3D 可视化点云。
  • 深度图到网格 :将每个像素的 3D 坐标连接成三角形面片,构建网格,并通过 Open3D 可视化。

通过这些方法,我们可以从深度图中直接生成 3D 数据,并进行各种应用,如环境建模、机器人导航、增强现实等。

希望本文能为你提供有用的工具与思路!

相关推荐
IT古董18 分钟前
【深度学习】常见模型-Transformer模型
人工智能·深度学习·transformer
沐雪架构师1 小时前
AI大模型开发原理篇-2:语言模型雏形之词袋模型
人工智能·语言模型·自然语言处理
python算法(魔法师版)2 小时前
深度学习深度解析:从基础到前沿
人工智能·深度学习
kakaZhui2 小时前
【llm对话系统】大模型源码分析之 LLaMA 位置编码 RoPE
人工智能·深度学习·chatgpt·aigc·llama
struggle20253 小时前
一个开源 GenBI AI 本地代理(确保本地数据安全),使数据驱动型团队能够与其数据进行互动,生成文本到 SQL、图表、电子表格、报告和 BI
人工智能·深度学习·目标检测·语言模型·自然语言处理·数据挖掘·集成学习
佛州小李哥3 小时前
通过亚马逊云科技Bedrock打造自定义AI智能体Agent(上)
人工智能·科技·ai·语言模型·云计算·aws·亚马逊云科技
云空4 小时前
《DeepSeek 网页/API 性能异常(DeepSeek Web/API Degraded Performance):网络安全日志》
运维·人工智能·web安全·网络安全·开源·网络攻击模型·安全威胁分析
AIGC大时代4 小时前
对比DeepSeek、ChatGPT和Kimi的学术写作关键词提取能力
论文阅读·人工智能·chatgpt·数据分析·prompt
山晨啊86 小时前
2025年美赛B题-结合Logistic阻滞增长模型和SIR传染病模型研究旅游可持续性-成品论文
人工智能·机器学习
一水鉴天6 小时前
为AI聊天工具添加一个知识系统 之77 详细设计之18 正则表达式 之5
人工智能·正则表达式