130 lines
4.5 KiB
Python
130 lines
4.5 KiB
Python
"""
|
|
示例 6: 多传感器 + 异步流水线(最高性能模式)
|
|
|
|
本示例结合了多进程和异步流水线的优势:
|
|
- 多进程:每个传感器运行在独立进程,拥有独立 CUDA 上下文
|
|
- 异步流水线:每个进程内部使用三阶段流水线
|
|
|
|
这是性能最高的配置,适用于:
|
|
- 多个高分辨率传感器
|
|
- 需要最大化总吞吐量
|
|
- 有充足的 CPU 核心和 GPU 显存
|
|
|
|
架构说明:
|
|
进程 1 (传感器 0):
|
|
[采集] → [光流] → [HHD] → 队列 ──┐
|
|
进程 2 (传感器 1): │
|
|
[采集] → [光流] → [HHD] → 队列 ──┼──→ 主进程显示
|
|
... │
|
|
进程 N (传感器 N-1): │
|
|
[采集] → [光流] → [HHD] → 队列 ──┘
|
|
|
|
资源占用估算(每个传感器):
|
|
- CPU: 约 2-3 个核心(采集、光流、HHD 各一个线程)
|
|
- GPU 显存: 约 500MB-1GB(取决于分辨率和 CUDA 算法)
|
|
"""
|
|
|
|
import os
|
|
os.environ["OPENCV_VIDEOIO_MSMF_ENABLE_HW_TRANSFORMS"] = "0" # Windows 兼容性设置
|
|
|
|
import cv2
|
|
import orisys
|
|
import multiprocessing as mp
|
|
|
|
|
|
def main():
|
|
# =========================================================================
|
|
# 1. 配置多个传感器
|
|
# =========================================================================
|
|
configs = [
|
|
{
|
|
'vid_src': './s1.mp4', # 视频源
|
|
'isstitch': True, # 启用拼接
|
|
'cuda': True, # 启用 GPU 加速
|
|
'cal_path': './config/cal.npy' # 标定文件
|
|
},
|
|
{
|
|
'vid_src': './s1_copy.mp4',
|
|
'isstitch': True,
|
|
'cuda': True,
|
|
'cal_path': './config/cal.npy'
|
|
},
|
|
]
|
|
|
|
# =========================================================================
|
|
# 2. 使用 async_context 启动(推荐方式)
|
|
# =========================================================================
|
|
# async_context 是一个便捷的上下文管理器:
|
|
# - 自动启用每个传感器进程内的异步流水线
|
|
# - 退出时自动清理所有资源
|
|
with orisys.MultiSensor.async_context(configs) as multi:
|
|
print("\n多传感器异步模式已启动,按 'q' 退出")
|
|
|
|
# =====================================================================
|
|
# 3. 迭代获取所有传感器数据
|
|
# =====================================================================
|
|
for all_data in multi:
|
|
# 过滤有效数据
|
|
for data in [d for d in all_data if d]:
|
|
sid = data['sensor_id']
|
|
|
|
# 打印状态
|
|
print(f"传感器 {sid}: FPS={data['fps']:5.1f}, 法向力={data['fnormal']: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(f"传感器 {sid} - 形变", arrows)
|
|
|
|
# 检查退出键
|
|
if cv2.waitKey(1) & 0xFF == ord('q'):
|
|
break
|
|
|
|
cv2.destroyAllWindows()
|
|
|
|
|
|
def main_manual():
|
|
"""
|
|
备选方式:手动控制启动和停止
|
|
|
|
适用于需要更精细控制的场景,例如:
|
|
- 动态添加/移除传感器
|
|
- 在运行时切换同步/异步模式
|
|
- 自定义错误处理
|
|
"""
|
|
configs = [
|
|
{'vid_src': './s1.mp4', 'isstitch': True, 'cuda': True, 'cal_path': './config/cal.npy'},
|
|
{'vid_src': './s1_copy.mp4', 'isstitch': True, 'cuda': True, 'cal_path': './config/cal.npy'},
|
|
]
|
|
|
|
# 创建 MultiSensor 实例
|
|
multi = orisys.MultiSensor(configs)
|
|
|
|
# 手动启动,use_async=True 启用异步模式
|
|
multi.start(use_async=True)
|
|
|
|
try:
|
|
while True:
|
|
# 获取所有传感器的最新数据
|
|
all_data = multi.get_all()
|
|
|
|
for data in [d for d in all_data if d]:
|
|
cv2.imshow(f"传感器 {data['sensor_id']}", data['img'])
|
|
|
|
if cv2.waitKey(1) & 0xFF == ord('q'):
|
|
break
|
|
finally:
|
|
# 手动停止所有进程
|
|
multi.stop()
|
|
cv2.destroyAllWindows()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
# Windows 下多进程必需的初始化
|
|
mp.freeze_support()
|
|
main()
|