深度图生成三维点云

mac2026-03-03  6

如何用Python快速通过深度图片生成点云图像并预览

原理代码

原理

在机器人及其他应用中,除了传统的RGB三通道相机以外,常常还会配置有深度传感器。比较常用的有Kinect,Lidar等等。博主前段时间被研究所导师布置了一个用深度图(depth image)和RGB图片来生成点云的任务。一开始谷歌百度了很久发现居然没有python的解法。实际上这是一个非常简单的问题,只要计算一下二维到三维的映射就可以了。 我自己写了一个转换函数可以直接生成点云了,原始repo在:Github代码库

代码

from PIL import Image import pandas as pd import numpy as np from open3d import read_point_cloud, draw_geometries import time class point_cloud_generator(): def __init__(self, rgb_file, depth_file, pc_file, focal_length, scalingfactor): self.rgb_file = rgb_file self.depth_file = depth_file self.pc_file = pc_file self.focal_length = focal_length self.scalingfactor = scalingfactor self.rgb = Image.open(rgb_file) self.depth = Image.open(depth_file).convert('I') self.width = self.rgb.size[0] self.height = self.rgb.size[1] def calculate(self): t1=time.time() depth = np.asarray(self.depth).T self.Z = depth / self.scalingfactor X = np.zeros((self.width, self.height)) Y = np.zeros((self.width, self.height)) for i in range(self.width): X[i, :] = np.full(X.shape[1], i) self.X = ((X - self.width / 2) * self.Z) / self.focal_length for i in range(self.height): Y[:, i] = np.full(Y.shape[0], i) self.Y = ((Y - self.height / 2) * self.Z) / self.focal_length df=np.zeros((6,self.width*self.height)) df[0] = self.X.T.reshape(-1) df[1] = -self.Y.T.reshape(-1) df[2] = -self.Z.T.reshape(-1) img = np.array(self.rgb) df[3] = img[:, :, 0:1].reshape(-1) df[4] = img[:, :, 1:2].reshape(-1) df[5] = img[:, :, 2:3].reshape(-1) self.df=df t2=time.time() print('calcualte 3d point cloud Done.',t2-t1) def write_ply(self): t1=time.time() float_formatter = lambda x: "%.4f" % x points =[] for i in self.df.T: points.append("{} {} {} {} {} {} 0\n".format (float_formatter(i[0]), float_formatter(i[1]), float_formatter(i[2]), int(i[3]), int(i[4]), int(i[5]))) file = open(self.pc_file, "w") file.write('''ply format ascii 1.0 element vertex %d property float x property float y property float z property uchar red property uchar green property uchar blue property uchar alpha end_header %s ''' % (len(points), "".join(points))) file.close() t2=time.time() print("Write into .ply file Done.",t2-t1) def show_point_cloud(self): pcd = read_point_cloud(self.pc_file) draw_geometries([pcd]) a = point_cloud_generator('p.png', 'd.png', 'pc1.ply', focal_length=50, scalingfactor=1000) a.calculate() a.write_ply() a.show_point_cloud() df = a.df np.save('pc.npy',df)

在原代码文件夹里放入RGB图片 ‘p.png’,深度图’d.png’直接运行就可以预览点云啦。 具体的坐标转换原理网上已经有很多解释了,比如坐标转换原理,大家觉得有帮助帮忙在github上点个星吧谢谢!

最新回复(0)