Files
orisys-sdk/example2_async_pipeline.py
T
2025-12-30 17:17:57 +08:00

116 lines
4.5 KiB
Python

"""
示例 5: 异步流水线处理(单传感器高吞吐模式)
本示例演示传感器的异步三阶段流水线:
- 图像采集、光流计算、HHD分解并行执行
- 通过队列在线程间传递数据
- 实现更高的帧率和吞吐量
流水线架构:
[采集线程] → 队列 → [光流线程] → 队列 → [HHD线程] → 队列 → [主线程显示]
时间线示例(每格代表一帧的处理时间):
采集: |帧1|帧2|帧3|帧4|帧5|...
光流: |帧1|帧2|帧3|帧4|...
HHD: |帧1|帧2|帧3|...
优势:三个阶段重叠执行,总吞吐量约为最慢阶段的速度
适用场景:
- 单传感器需要最大帧率
- CPU/GPU 利用率需要最大化
- 可以接受 2-3 帧的处理延迟
对比同步模式:
- 同步模式:采集→光流→HHD 串行执行,FPS 受限于总时间
- 异步模式:三阶段并行,FPS 约为同步模式的 2-3 倍
"""
import os
os.environ["OPENCV_VIDEOIO_MSMF_ENABLE_HW_TRANSFORMS"] = "0" # Windows 兼容性设置
import cv2
import orisys
import numpy as np
def main():
# =========================================================================
# 1. 初始化传感器
# =========================================================================
sensor = orisys.Sensor(0, cuda=True, verbose=True, config_name="prototype")
# =========================================================================
# 2. 启用异步流水线
# =========================================================================
# queue_size: 每个阶段间队列的大小
# - 较小的值(1-2):延迟低,但可能丢帧
# - 较大的值(3-5):吞吐稳定,但延迟增加
sensor.enable_async(queue_size=2, compute_contact=True)
print("\n异步模式已启用")
print("按 'q' 退出,按 'r' 重置光流追踪器")
# =========================================================================
# 3. 主循环:非阻塞获取数据
# =========================================================================
try:
while True:
# 非阻塞获取最新结果
# timeout: 等待超时时间(秒)
# - 返回 None 表示暂无新数据
# - 返回 dict 包含所有传感器数据
data = sensor.get_async(timeout=0.05)
if data is None:
# 暂无新数据,继续等待
continue
# 打印力的数值
print(f"FPS: {data['fps']:5.1f}, "
f"法向力: {data['fnormal']:8.2f}, "
f"切向力X: {data['fshearx']:8.2f}, "
f"切向力Y: {data['fsheary']:8.2f}")
# 显示形变箭头图
if data['img'] is not None and data['flow'] is not None:
arrows = orisys.util.draw_arrows(
data['img'].copy(),
data['flow'],
threshold=5
)
cv2.imshow("异步模式 - 形变", arrows)
if data['centroid'] is not None:
# print(f"触碰点: {data['centroid']}")
image_with_foe = orisys.util.draw_contact(data['img'].copy(), data['contour'], data['centroid'])
cv2.imshow("Contact Centroid", image_with_foe)
if data['depth_map'] is not None:
# 归一化散度值到0-255范围(使用绝对值,然后归一化)
div_abs = data['depth_map']
if div_abs.max() > div_abs.min():
div_normalized = ((div_abs - div_abs.min()) / (div_abs.max() - div_abs.min()) * 255).astype(np.uint8)
else:
div_normalized = np.zeros_like(div_abs, dtype=np.uint8)
cv2.imshow("Depth Map", cv2.applyColorMap(div_normalized, cv2.COLORMAP_JET))
# 键盘控制
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
break
elif key == ord('r'):
sensor.reset()
print("光流追踪器已重置")
finally:
# =====================================================================
# 4. 清理资源
# =====================================================================
# disconnect() 会自动调用 disable_async() 停止所有线程
sensor.disconnect()
cv2.destroyAllWindows()
if __name__ == '__main__':
main()