save_image_to_disk.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. """保存图像示例。
  2. 从相机采集少量彩色帧和深度帧并落盘,便于离线分析。
  3. """
  4. import os
  5. import cv2
  6. import numpy as np
  7. from pyorbbecsdk import *
  8. from utils import frame_to_bgr_image
  9. def save_depth_frame(frame: DepthFrame, index):
  10. """保存单帧深度数据为原始 .raw 文件。"""
  11. if frame is None:
  12. return
  13. width = frame.get_width()
  14. height = frame.get_height()
  15. timestamp = frame.get_timestamp()
  16. scale = frame.get_depth_scale()
  17. depth_format = frame.get_format()
  18. if depth_format != OBFormat.Y16:
  19. print("depth format is not Y16")
  20. return
  21. # 深度数据转毫米后按 uint16 存储。
  22. data = np.frombuffer(frame.get_data(), dtype=np.uint16)
  23. data = data.reshape((height, width))
  24. data = data.astype(np.float32) * scale
  25. data = data.astype(np.uint16)
  26. save_image_dir = os.path.join(os.getcwd(), "depth_images")
  27. if not os.path.exists(save_image_dir):
  28. os.mkdir(save_image_dir)
  29. raw_filename = save_image_dir + "/depth_{}x{}_{}_{}.raw".format(width, height, index, timestamp)
  30. data.tofile(raw_filename)
  31. def save_color_frame(frame: ColorFrame, index):
  32. """保存单帧彩色图为 PNG 文件。"""
  33. if frame is None:
  34. return
  35. width = frame.get_width()
  36. height = frame.get_height()
  37. timestamp = frame.get_timestamp()
  38. save_image_dir = os.path.join(os.getcwd(), "color_images")
  39. if not os.path.exists(save_image_dir):
  40. os.mkdir(save_image_dir)
  41. filename = save_image_dir + "/color_{}x{}_{}_{}.png".format(width, height, index, timestamp)
  42. image = frame_to_bgr_image(frame)
  43. if image is None:
  44. print("failed to convert frame to image")
  45. return
  46. cv2.imwrite(filename, image)
  47. def main():
  48. """采集并保存若干帧样例图片。"""
  49. pipeline = Pipeline()
  50. config = Config()
  51. saved_color_cnt: int = 0
  52. saved_depth_cnt: int = 0
  53. has_color_sensor = False
  54. try:
  55. # 优先尝试启用彩色流。
  56. profile_list = pipeline.get_stream_profile_list(OBSensorType.COLOR_SENSOR)
  57. if profile_list is not None:
  58. color_profile: VideoStreamProfile = profile_list.get_default_video_stream_profile()
  59. config.enable_stream(color_profile)
  60. has_color_sensor = True
  61. except OBError as e:
  62. print(e)
  63. # 启用深度流。
  64. depth_profile_list = pipeline.get_stream_profile_list(OBSensorType.DEPTH_SENSOR)
  65. if depth_profile_list is not None:
  66. depth_profile = depth_profile_list.get_default_video_stream_profile()
  67. config.enable_stream(depth_profile)
  68. pipeline.start(config)
  69. while True:
  70. try:
  71. frames = pipeline.wait_for_frames(100)
  72. if frames is None:
  73. continue
  74. # 已达到目标帧数则结束采集。
  75. if has_color_sensor:
  76. if saved_color_cnt >= 5 and saved_depth_cnt >= 5:
  77. break
  78. elif saved_depth_cnt >= 5:
  79. break
  80. color_frame = frames.get_color_frame()
  81. if color_frame is not None and saved_color_cnt < 5:
  82. save_color_frame(color_frame, saved_color_cnt)
  83. saved_color_cnt += 1
  84. depth_frame = frames.get_depth_frame()
  85. if depth_frame is not None and saved_depth_cnt < 5:
  86. save_depth_frame(depth_frame, saved_depth_cnt)
  87. saved_depth_cnt += 1
  88. except KeyboardInterrupt:
  89. break
  90. if __name__ == "__main__":
  91. main()