如何基于RGB图像为Open3D生成的深度点云着色?
给Open3D点云赋予RGB色彩的实现方法
方法一:基于已有深度点云手动映射RGB
如果你已经通过深度图创建了点云,可以通过相机内参将点云坐标反向映射到RGB图像的像素,为点云赋予颜色:
import open3d as o3d import numpy as np # 加载深度图与RGB图 depth_img = o3d.io.read_image("depth.png") rgb_img = o3d.io.read_image("rgb.png") # 相机内参(替换为你的实际标定参数) intrinsics = o3d.camera.PinholeCameraIntrinsic( o3d.camera.PinholeCameraIntrinsicParameters.PrimeSenseDefault ) # 创建深度点云 pcd = o3d.geometry.PointCloud.create_from_depth_image(depth_img, intrinsics) # 将RGB图像转为numpy数组,方便索引 rgb_np = np.asarray(rgb_img) # 获取点云所有点的坐标 points = np.asarray(pcd.points) # 将点云坐标投影到RGB图像的像素坐标系 u, v = intrinsics.project_points_to_pixels(points) # 转为整数像素索引 u = np.round(u).astype(int) v = np.round(v).astype(int) # 过滤超出图像范围的无效点 valid_mask = (u >= 0) & (u < rgb_np.shape[1]) & (v >= 0) & (v < rgb_np.shape[0]) u_valid = u[valid_mask] v_valid = v[valid_mask] valid_points = points[valid_mask] # 提取对应像素的颜色,Open3D要求颜色值为0-1的浮点数,因此除以255 colors = rgb_np[v_valid, u_valid] / 255.0 # 更新点云的有效点与颜色 pcd.points = o3d.utility.Vector3dVector(valid_points) pcd.colors = o3d.utility.Vector3dVector(colors) # 可视化带颜色的点云 o3d.visualization.draw_geometries([pcd])
方法二:直接通过RGBD图像创建带颜色的点云
这是更简洁的方式,直接将RGB图与深度图打包为RGBD图像,再创建点云:
import open3d as o3d # 加载深度图与RGB图 depth_img = o3d.io.read_image("depth.png") rgb_img = o3d.io.read_image("rgb.png") # 相机内参(替换为你的实际标定参数) intrinsics = o3d.camera.PinholeCameraIntrinsic( o3d.camera.PinholeCameraIntrinsicParameters.PrimeSenseDefault ) # 将RGB与深度图转为RGBD图像 # depth_scale:深度值缩放因子(比如深度图单位为毫米时设为1000,米则设为1) # depth_trunc:截断距离,超出该距离的深度点会被丢弃 rgbd_img = o3d.geometry.RGBDImage.create_from_color_and_depth( rgb_img, depth_img, depth_scale=1000.0, depth_trunc=3.0, convert_rgb_to_intensity=False ) # 直接创建带颜色的点云 pcd = o3d.geometry.PointCloud.create_from_rgbd_image(rgbd_img, intrinsics) # 可视化 o3d.visualization.draw_geometries([pcd])
关键注意事项
- 必须保证RGB图像与深度图像尺寸完全一致,且为同一视角下同步采集的帧,否则颜色映射会出现错位。
- 相机内参需与采集图像时的实际参数匹配,否则投影坐标会不准确。
depth_scale和depth_trunc参数需根据你的深度图实际情况调整,避免无效深度值干扰。
内容的提问来源于stack exchange,提问作者Ars ML




