前言
读取点云ply文件,生成对应的rgb图像、深度图像和灰度图像,从RGB图像和深度图像重建点云
一、ply点云对象生成rgb图像、深度图像和灰度图像
代码如下:
import open3d as o3d
import numpy as np
import cv2
from PIL import Image
point_cloud = o3d.io.read_point_cloud('./data/soldier_vox10_0536.ply')
# 提取点云数据
points = np.asarray(point_cloud.points)
colors = np.asarray(point_cloud.colors)
# 设置RGB图像的分辨率
width = 1024
height = 1024
# 将点云坐标映射到图像坐标
# 点云数据的最大值恰好是1023,如果不是,就需要缩放一下
# scaled_points = (points - min_coord) / (max_coord - min_coord) * 1023
scaled_points = points.astype(int)
# 创建空白RGBD图像
rgbd_image = np.zeros((1024, 1024, 3), dtype=np.uint8)
# 将点云颜色赋值给RGBD图像
rgbd_image[1023 - scaled_points[:, 1], scaled_points[:, 0]] = colors[:, :3] * 255
# 将点云归一化到0-255的范围
normalized_points = (points - min_coord) / (max_coord - min_coord) * 255
normalized_depth = normalized_points[:, 2]
# 创建深度图像
depth_image = np.zeros((1024, 1024), dtype=np.uint8)
depth_image[1023 - scaled_points[:, 1], scaled_points[:, 0]] = normalized_depth
# 将RGBD图像转换为灰度图像
gray_image = cv2.cvtColor(rgbd_image, cv2.COLOR_RGB2GRAY)
# 显示RGBD图像和灰度图像
cv2.imwrite("./figures/soldier_gray_image_0536.png", gray_image)
cv2.imwrite("./figures/soldier_rgb_image_0536.png", rgbd_image)
cv2.imwrite("./figures/soldier_depth_image_0536.png", depth_image)
二、从RGB图像和深度图像重建点云
代码如下:
import numpy as np
import open3d as o3d
import cv2
import time
# 从RGB图像和深度图像重建点云
def reconstruct_point_cloud(rgb_image, depth_image):
# 获取图像尺寸
height, width = depth_image.shape
# 创建点云坐标
y_coords, x_coords = np.indices((height, width))
x_coords = x_coords.reshape(-1)
y_coords = y_coords.reshape(-1)
z_coords = depth_image.reshape(-1)
points_x = []
points_y = []
points_z = []
colors = []
for x, y in zip(x_coords, y_coords):
[r, g, b] = rgb_image[y][x]
if r == 0 and g == 0 and b == 0:
continue
points_x.append(x)
points_y.append(1023 - y)
points_z.append(depth_image[y][x])
color = [r / 255.0, g / 255.0, b / 255.0]
colors.append(color)
# 创建点云
points = np.column_stack((points_x, points_y, points_z))
# colors = rgb_image.reshape(-1, 3) / 255.0
# print(colors)
point_cloud = o3d.geometry.PointCloud()
point_cloud.points = o3d.utility.Vector3dVector(points)
point_cloud.colors = o3d.utility.Vector3dVector(colors)
return point_cloud
# 主程序
def main():
rgb_image_path = './figures/longdress_rgb_image_1051.png'
depth_image_path = './figures/longdress_depth_image_1051.png'
# 读取RGB图像和深度图像
rgb_image = cv2.imread(rgb_image_path)
depth_image = cv2.imread(depth_image_path, cv2.IMREAD_GRAYSCALE)
start_time = time.time()
# 将RGB图像和深度图像重建为点云
point_cloud = reconstruct_point_cloud(rgb_image, depth_image)
end_time = time.time()
print('cost %f second' % (end_time - start_time))
# 原始点云点数
point_size = np.array(point_cloud.points).shape[0]
print(point_size)
# 保存重建的点云
# o3d.io.write_point_cloud("./Pointdata/soldier_RGBDtoPCD.pcd", point_cloud)
# 可视化点云
# o3d.visualization.draw_geometries([point_cloud])
总结
点云和二维图像的简单转换。