You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何无法从Blender生成的深度图得到正确点云?

深度图转点云畸变问题解决

问题背景

用Blender生成深度图后,通过代码转换为点云时出现严重畸变,实际场景应为平面。相关信息如下:

Blender设置

Blender渲染设置

场景与深度图

  • 主场景:
    主场景{: width="500"}
  • 生成的深度图:
    深度图{: width="500"}

相机参数

传感器设置为Vertical 36x36,图像分辨率800x800,代码内参:f_x=f_y=1111.11,c_x=c_y=400

原始转换代码

import cv2
import numpy as np
import open3d as o3d

f_x = 1111.11
f_y = 1111.11
c_x = 400
c_y = 400

depth_map = cv2.imread("./images/depth.png", cv2.IMREAD_ANYDEPTH)
height, width = depth_map.shape

z_min = 4.0
z_max = 16.0

point_cloud = []

for v in range(height):
    for u in range(width):
        d_norm = depth_map[v, u] / 65535.0

        z = d_norm * (z_max - z_min) + z_min
        if z > 0:
            X = (u - c_x) * z / f_x
            Y = (v - c_y) * z / f_y

            point_cloud.append(np.array([X, Y, z]))

point_cloud = np.array(point_cloud)

pcd = o3d.geometry.PointCloud()

pcd.points = o3d.utility.Vector3dVector(point_cloud)

o3d.visualization.draw_geometries([pcd])

畸变原因与修正方案

1. 坐标系方向不匹配

Blender与OpenCV/Open3D的坐标系存在核心差异:Blender图像行索引(v)从上到下递增,而OpenCV中从下到上递增,直接计算会导致Y轴方向反转,引发畸变。

修正:反转Y轴计算
将代码中Y的计算改为:

Y = -(v - c_y) * z / f_y

2. 深度值过滤优化

原始代码判断z>0,但实际近平面外的深度值无效,应改为判断z > near_plane(即4.0),避免引入错误点。

修正后的完整代码

import cv2
import numpy as np
import open3d as o3d

f_x = 1111.11
f_y = 1111.11
c_x = 400
c_y = 400

# 读取深度图,校验路径有效性
depth_map = cv2.imread("./images/depth.png", cv2.IMREAD_ANYDEPTH)
if not depth_map.any():
    raise ValueError("无法读取深度图文件,请检查路径")
height, width = depth_map.shape

# 与Blender渲染设置一致的近/远平面
near_plane = 4.0
far_plane = 16.0

point_cloud = []

for v in range(height):
    for u in range(width):
        d_norm = depth_map[v, u] / 65535.0
        z = d_norm * (far_plane - near_plane) + near_plane
        
        # 只保留有效深度值
        if z > near_plane:
            X = (u - c_x) * z / f_x
            Y = -(v - c_y) * z / f_y  # 修正Y轴方向
            point_cloud.append(np.array([X, Y, z]))

point_cloud = np.array(point_cloud)

pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(point_cloud)

o3d.visualization.draw_geometries([pcd])

内容的提问来源于stack exchange,提问作者Clyde Tony

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 04:37:36