深度图转换为点云文件脚本
步骤
1. 读取深度图像
-
使用OpenCV读取16位深度图(假设输入是单通道的深度图,单位为毫米)。
-
cv2.IMREAD_UNCHANGED
确保保留原始数据精度(如16位)。
2. 相机内参设置
-
内参被除以4,因为深度图的分辨率被缩小了4倍(如从高分辨率下采样到当前尺寸)。
-
注意:如果图像未缩放,此操作会导致坐标计算错误。
3. 遍历像素生成点云
-
坐标转换公式:将像素坐标
(u, v)
转换为相机坐标系下的3D点(x, y, z)
。 -
公式依据:根据相机模型,三维点 P
(x, y, z)
到像素坐标的转换,如图所示:
转换公式为焦距放缩加上坐标系中心主点偏移:
则反推为:
4. 坐标轴变换与单位转换
-
坐标轴重排:将相机坐标系的
(z, x, y)
转换为点云的(x, y, z)
,可能意图调整坐标系朝向。 -
单位转换:假设深度图单位为毫米,除以1000转换为米(常见于Kinect等设备)。
5. 生成并保存点云
代码实现
import cv2
import numpy as np
import open3d as o3ddepth_image = cv2.imread('C:/pyprojects/images/1112_0-rgb.png', cv2.IMREAD_UNCHANGED)if depth_image is None:print("fail")exit()# 相机内参(根据你的相机设置进行调整)
fx = 1085.76 # 焦距 x
fy = 1085.93 # 焦距 y
cx = 600.785 # 主点 x
cy = 496.776 # 主点 yheight, width = depth_image.shape
print("depth_image.shape ", depth_image.shape)
points = []
for v in range(height):for u in range(width):z = depth_image[v, u] # 获取深度值if z > 0: # 过滤无效点x = (u - (cx/4)) * z / (fx/4) y = (v - (cy/4)) * z / (fy/4)point_x = z / 1000.0point_y = x / 1000.0point_z = y / 1000.0# point_x = z # point_y = x # point_z = y points.append([point_x, point_y, point_z])points = np.array(points)
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(points)
print("点云数量:", len(pcd.points))# o3d.visualization.draw_geometries([pcd])o3d.io.write_point_cloud("C:/pyprojects/depth_init.pcd", pcd)
初始深度图(已可视化):
点云展示(使用CloudCompare v2.13打开):