pcd2color.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import os
  2. import cv2
  3. import numpy as np
  4. import open3d as o3d
  5. from glob import glob
  6. from collections import defaultdict
  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. point_count = np.zeros((height, width), dtype=np.int32) # 统计每个像素覆盖的点数
  20. for point in points:
  21. X, Y, Z, r, g, b = point
  22. if Z > 0:
  23. u = int((X * fx) / Z + cx)
  24. v = int((Y * fy) / Z + cy)
  25. if 0 <= u < width and 0 <= v < height:
  26. color_image[v, u] = [r * 255, g * 255, b * 255]
  27. point_count[v, u] += 1 # 该像素多了一个点
  28. return color_image, point_count
  29. def process_pcd_file(pcd_path, color_dir):
  30. filename = os.path.splitext(os.path.basename(pcd_path))[0]
  31. print(f"Processing: {filename}")
  32. pcd = o3d.io.read_point_cloud(pcd_path)
  33. points = np.asarray(pcd.points) # xyz
  34. colors = np.asarray(pcd.colors) # rgb
  35. if points.shape[0] == 0 or colors.shape[0] == 0:
  36. print(f"Skipping empty or invalid PCD: {filename}")
  37. return
  38. points_colored = np.hstack((points, colors))
  39. color_img, point_count = pointscloud2colorimg(points_colored)
  40. # 保存图像
  41. color_img_u8 = np.clip(color_img, 0, 255).astype(np.uint8)
  42. cv2.imwrite(os.path.join(color_dir, f"{filename}_color.jpg"), color_img_u8)
  43. # 统计覆盖情况
  44. num_multi_cover = np.sum(point_count > 1) # 有多少像素点被多个点覆盖
  45. total_points = np.sum(point_count) # 总点数
  46. max_cover = np.max(point_count) # 单个像素最多的点数
  47. print(f"{filename}: 总点数={total_points}, 被多个点覆盖的像素数={num_multi_cover}, 单像素最多点数={max_cover}")
  48. # 设置输入输出路径
  49. input_dir = r"\\192.168.50.222\share\zqy\dianyun0731"
  50. output_base = r"G:\python_ws_g\data\color"
  51. color_dir = os.path.join(output_base, "color_jpg")
  52. os.makedirs(color_dir, exist_ok=True)
  53. # 获取所有 PCD 文件
  54. pcd_files = glob(os.path.join(input_dir, "*.pcd"))
  55. print(f"Found {len(pcd_files)} PCD files.")
  56. # 批量处理
  57. for pcd_path in pcd_files:
  58. process_pcd_file(pcd_path, color_dir)