b_pcd2rgbd.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import os
  2. import cv2
  3. import numpy as np
  4. import open3d as o3d
  5. from glob import glob
  6. from tifffile import imwrite as tif_write
  7. # 相机内参矩阵
  8. K = np.array([
  9. [1.30449e3, 0, 5.2602e2],
  10. [0, 1.30449e3, 1.07432e3],
  11. [0, 0, 1]
  12. ])
  13. fx, fy = K[0, 0], K[1, 1]
  14. cx, cy = K[0, 2], K[1, 2]
  15. # 图像尺寸
  16. height, width = 2000, 2000
  17. def pointscloud2colorimg(points):
  18. color_image = np.zeros((height, width, 3), dtype=np.float32)
  19. for point in points:
  20. X, Y, Z, r, g, b = point
  21. if Z > 0:
  22. u = int((X * fx) / Z + cx)
  23. v = int((Y * fy) / Z + cy)
  24. if 0 <= u < width and 0 <= v < height:
  25. color_image[v, u] = [r * 255, g * 255, b * 255]
  26. return color_image
  27. def pointscloud2depthmap(points):
  28. depth_map = np.zeros((height, width), dtype=np.float32)
  29. for point in points:
  30. X, Y, Z, *_ = point
  31. if Z > 0:
  32. u = int((X * fx) / Z + cx)
  33. v = int((Y * fy) / Z + cy)
  34. if 0 <= u < width and 0 <= v < height:
  35. depth_map[v, u] = Z
  36. return depth_map
  37. def process_pcd_file(pcd_path, rgbd_dir):
  38. filename = os.path.splitext(os.path.basename(pcd_path))[0]
  39. print(f"Processing: {filename}")
  40. pcd = o3d.io.read_point_cloud(pcd_path)
  41. points = np.asarray(pcd.points)
  42. colors = np.asarray(pcd.colors)
  43. if points.shape[0] == 0 or colors.shape[0] == 0:
  44. print(f"Skipping empty or invalid PCD: {filename}")
  45. return
  46. points_colored = np.hstack((points, colors))
  47. color_img = pointscloud2colorimg(points_colored)
  48. depth_map = pointscloud2depthmap(points_colored)
  49. # RGB 转 uint8,Depth 保持 float32
  50. color_img_u8 = np.clip(color_img, 0, 255).astype(np.uint8)
  51. depth_map_mm = depth_map.astype(np.float32)
  52. # 合并为 4 通道 RGBD 图像(float32)
  53. rgbd = np.concatenate((color_img_u8, depth_map_mm[..., np.newaxis]), axis=2)
  54. tif_write(os.path.join(rgbd_dir, f"{filename}_rgbd.tiff"), rgbd, photometric='rgb')
  55. print(f"Saved RGBD TIFF for {filename}")
  56. input_dir = r"G:\python_ws_g\data\pcd"
  57. output_base = os.path.dirname(input_dir)
  58. rgbd_dir = os.path.join(output_base, "rgbd_tiff")
  59. os.makedirs(rgbd_dir, exist_ok=True)
  60. # 获取 PCD 文件
  61. pcd_files = glob(os.path.join(input_dir, "*.pcd"))
  62. print(f"Found {len(pcd_files)} PCD files.")
  63. # 批量处理
  64. for pcd_path in pcd_files:
  65. process_pcd_file(pcd_path, rgbd_dir)