cargo_height_measure.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. """本地可视化测量脚本。
  2. 用于直接打开深度相机窗口,实时查看 ROI、最近点与距离标注,
  3. 便于调试参数与现场观测效果。
  4. """
  5. import time
  6. import cv2
  7. from depth_common import (
  8. Settings,
  9. TemporalFilter,
  10. compute_roi_bounds,
  11. extract_depth_data,
  12. find_nearest_point,
  13. init_depth_pipeline,
  14. nearest_distance_in_roi,
  15. )
  16. # 键盘退出键。
  17. ESC_KEY = 27
  18. # 控制终端打印频率(秒)。
  19. PRINT_INTERVAL = 1
  20. # 从环境变量加载深度处理参数。
  21. SETTINGS = Settings.from_env()
  22. def main():
  23. """启动实时深度查看窗口。"""
  24. # 启用时间滤波以降低深度抖动。
  25. temporal_filter = TemporalFilter(alpha=0.5)
  26. try:
  27. # 初始化深度相机并获取深度内参。
  28. pipeline, depth_intrinsics, depth_profile = init_depth_pipeline()
  29. print("depth profile: ", depth_profile)
  30. except Exception as e:
  31. print(e)
  32. return
  33. last_print_time = time.time()
  34. while True:
  35. try:
  36. # 等待一帧数据,超时时间 100ms。
  37. frames = pipeline.wait_for_frames(100)
  38. if frames is None:
  39. continue
  40. depth_frame = frames.get_depth_frame()
  41. depth_data = extract_depth_data(depth_frame, SETTINGS, temporal_filter)
  42. if depth_data is None:
  43. continue
  44. # 计算中心 ROI 范围。
  45. bounds = compute_roi_bounds(depth_data, depth_intrinsics, SETTINGS)
  46. if bounds is None:
  47. continue
  48. x_start, x_end, y_start, y_end, center_distance = bounds
  49. roi = depth_data[y_start:y_end, x_start:x_end]
  50. # 计算 ROI 最近距离。
  51. nearest_distance = nearest_distance_in_roi(roi, SETTINGS) or 0
  52. # 找到最近点坐标用于绘制圆点标记。
  53. nearest_point = find_nearest_point(
  54. roi,
  55. x_start,
  56. y_start,
  57. SETTINGS,
  58. nearest_distance,
  59. )
  60. # 限频打印测量值,避免刷屏。
  61. current_time = time.time()
  62. if current_time - last_print_time >= PRINT_INTERVAL:
  63. print(
  64. "nearest distance in "
  65. f"{SETTINGS.roi_width_cm}cm x {SETTINGS.roi_height_cm}cm area: ",
  66. nearest_distance,
  67. )
  68. last_print_time = current_time
  69. # 生成深度伪彩图并叠加标注信息。
  70. depth_image = cv2.normalize(depth_data, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U)
  71. depth_image = cv2.applyColorMap(depth_image, cv2.COLORMAP_JET)
  72. cv2.rectangle(
  73. depth_image,
  74. (x_start, y_start),
  75. (x_end - 1, y_end - 1),
  76. (0, 255, 0),
  77. 2,
  78. )
  79. if nearest_point is not None:
  80. cv2.circle(depth_image, nearest_point, 4, (0, 0, 0), -1)
  81. cv2.circle(depth_image, nearest_point, 6, (0, 255, 255), 2)
  82. cv2.putText(
  83. depth_image,
  84. f"nearest: {nearest_distance} mm",
  85. (10, 30),
  86. cv2.FONT_HERSHEY_SIMPLEX,
  87. 0.8,
  88. (255, 255, 255),
  89. 2,
  90. cv2.LINE_AA,
  91. )
  92. cv2.putText(
  93. depth_image,
  94. f"center: {int(center_distance)} mm",
  95. (10, 60),
  96. cv2.FONT_HERSHEY_SIMPLEX,
  97. 0.8,
  98. (255, 255, 255),
  99. 2,
  100. cv2.LINE_AA,
  101. )
  102. cv2.imshow("Depth Viewer", depth_image)
  103. key = cv2.waitKey(1)
  104. if key == ord("q") or key == ESC_KEY:
  105. break
  106. except KeyboardInterrupt:
  107. break
  108. # 退出前释放窗口和相机资源。
  109. cv2.destroyAllWindows()
  110. pipeline.stop()
  111. if __name__ == "__main__":
  112. main()