为何无法从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
相关产品推荐
相关产品推荐

