1fastrgbd.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import os
  2. import numpy as np
  3. import open3d as o3d
  4. from glob import glob
  5. from tifffile import imwrite as tif_write
  6. # 相机内参矩阵
  7. K = np.array([
  8. [1.30449e3, 0, 5.2602e2],
  9. [0, 1.30449e3, 1.07432e3],
  10. [0, 0, 1]
  11. ])
  12. fx, fy = K[0, 0], K[1, 1]
  13. cx, cy = K[0, 2], K[1, 2]
  14. # 图像尺寸
  15. height, width = 2000, 2000
  16. def compute_uv_mask(points):
  17. """
  18. 计算 u, v 像素坐标和有效 mask
  19. """
  20. X, Y, Z = points[:, 0], points[:, 1], points[:, 2]
  21. valid = Z > 0
  22. X, Y, Z = X[valid], Y[valid], Z[valid]
  23. u = ((X * fx) / Z + cx).astype(np.int32)
  24. v = ((Y * fy) / Z + cy).astype(np.int32)
  25. mask = (u >= 0) & (u < width) & (v >= 0) & (v < height)
  26. return u[mask], v[mask], Z[mask], valid, mask
  27. def build_rgb_image(points, u, v, valid_mask):
  28. r, g, b = points[:, 3], points[:, 4], points[:, 5]
  29. r, g, b = r[valid_mask], g[valid_mask], b[valid_mask]
  30. color_image = np.zeros((height, width, 3), dtype=np.uint8)
  31. color_image[v, u, 0] = (r * 255).astype(np.uint8)
  32. color_image[v, u, 1] = (g * 255).astype(np.uint8)
  33. color_image[v, u, 2] = (b * 255).astype(np.uint8)
  34. return color_image
  35. def build_depth_map(u, v, Z):
  36. depth_map = np.zeros((height, width), dtype=np.float32)
  37. depth_map[v, u] = Z
  38. return depth_map
  39. def process_pcd_file(pcd_path, rgbd_dir):
  40. filename = os.path.splitext(os.path.basename(pcd_path))[0]
  41. print(f"Processing: {filename}")
  42. pcd = o3d.io.read_point_cloud(pcd_path)
  43. points = np.asarray(pcd.points)
  44. colors = np.asarray(pcd.colors)
  45. if points.shape[0] == 0 or colors.shape[0] == 0:
  46. print(f"Skipping empty or invalid PCD: {filename}")
  47. return
  48. points_colored = np.hstack((points, colors)) # Nx6
  49. # 一次性计算 u, v 和 mask
  50. u, v, Z, valid_z_mask, final_mask = compute_uv_mask(points_colored)
  51. # 生成 RGB 和 depth 图像
  52. color_img = build_rgb_image(points_colored[valid_z_mask], u, v, final_mask)
  53. depth_map = build_depth_map(u, v, Z)
  54. # 合并为 RGBD
  55. rgbd = np.zeros((height, width, 4), dtype=np.float32)
  56. rgbd[:, :, 0:3] = color_img.astype(np.float32)
  57. rgbd[:, :, 3] = depth_map
  58. # 保存 tiff
  59. tif_write(os.path.join(rgbd_dir, f"{filename}_rgbd.tiff"), rgbd, photometric='rgb')
  60. print(f"Saved RGBD TIFF for {filename}")
  61. if __name__ == "__main__":
  62. input_dir = r"\\192.168.50.222\share2\zyh\data\rgbd_line\dianyun0731"
  63. output_base = os.path.dirname(input_dir)
  64. rgbd_dir = os.path.join(output_base, "rgbd_tiff")
  65. os.makedirs(rgbd_dir, exist_ok=True)
  66. pcd_files = glob(os.path.join(input_dir, "*.pcd"))
  67. print(f"Found {len(pcd_files)} PCD files.")
  68. for pcd_path in pcd_files:
  69. process_pcd_file(pcd_path, rgbd_dir)