目录

从深度图到 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 数据,并进行各种应用,如环境建模、机器人导航、增强现实等。

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

本文是转载文章,点击查看原文
如有侵权,请联系 xyy@jishuzhan.net 删除
相关推荐
weixin_457885825 分钟前
DeepSeek与搜索引擎:AI生成内容如何突破“语义天花板”
人工智能·搜索引擎·ai·deepseek
拓端研究室TRL21 分钟前
Python贝叶斯回归、强化学习分析医疗健康数据拟合截断删失数据与参数估计3实例
开发语言·人工智能·python·数据挖掘·回归
知来者逆32 分钟前
YOLO目标检测应用——基于 YOLOv8目标检测和 SAM 零样本分割实现指定目标分割
yolo·目标检测·计算机视觉·图像分割·sam·yolov8
国科安芯35 分钟前
高安全等级车规芯片在星载控制终端上的应用
人工智能·嵌入式硬件·物联网·架构·汽车
Direct_Yang38 分钟前
如何使用 DeepSeek 帮助自己的工作?
人工智能
汪子熙1 小时前
使用 Trae 开发一个演示勾股定理的动画演示
前端·人工智能·trae
小白学C++.2 小时前
大模型论文:CRAMMING TRAINING A LANGUAGE MODEL ON ASINGLE GPU IN ONE DAY(效率提升)-final
人工智能·语言模型·自然语言处理
Encarta19932 小时前
【语音识别】vLLM 部署 Whisper 语音识别模型指南
人工智能·whisper·语音识别
AWS官方合作商2 小时前
AWS Bedrock:开启企业级生成式AI的钥匙【深度解析】
大数据·人工智能·aws
神经星星2 小时前
【vLLM 学习】API 客户端
数据库·人工智能·机器学习