add multisensor
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
"""
|
||||
示例 4: 多传感器并行处理(多进程模式)
|
||||
|
||||
本示例演示如何同时运行多个传感器:
|
||||
- 每个传感器运行在独立的进程中
|
||||
- 每个进程拥有独立的 CUDA 上下文
|
||||
- 使用 MultiSensor 类简化多传感器管理
|
||||
|
||||
架构说明:
|
||||
进程 1 (传感器 0): 采集 → 光流 → HHD → 队列
|
||||
进程 2 (传感器 1): 采集 → 光流 → HHD → 队列
|
||||
↓
|
||||
主进程: 显示 ← ───────────────┘
|
||||
|
||||
适用场景:多指触觉传感器、多视角采集、需要 GPU 加速的多路处理
|
||||
|
||||
注意事项:
|
||||
- Windows 下必须在 if __name__ == '__main__' 中调用 mp.freeze_support()
|
||||
- 每个传感器进程会占用独立的 GPU 显存
|
||||
"""
|
||||
|
||||
import os
|
||||
os.environ["OPENCV_VIDEOIO_MSMF_ENABLE_HW_TRANSFORMS"] = "0" # Windows 兼容性设置
|
||||
|
||||
import cv2
|
||||
import orisys
|
||||
import multiprocessing as mp
|
||||
import numpy as np
|
||||
|
||||
|
||||
def main():
|
||||
# =========================================================================
|
||||
# 1. 配置多个传感器
|
||||
# =========================================================================
|
||||
# 每个传感器的配置是一个字典,包含:
|
||||
# vid_src: 视频源(文件路径或摄像头索引)
|
||||
# isstitch: 是否启用拼接模式
|
||||
# cuda: 是否使用 GPU 加速
|
||||
# cal_path: 标定文件路径
|
||||
configs = [
|
||||
{
|
||||
'vid_src': './s1.mp4',
|
||||
'isstitch': True,
|
||||
'cuda': True,
|
||||
'cal_path': './config/cal.npy',
|
||||
'config_name': "prototype"
|
||||
},
|
||||
{
|
||||
'vid_src': './s1.mp4',
|
||||
'isstitch': True,
|
||||
'cuda': True,
|
||||
'cal_path': './config/cal.npy',
|
||||
'config_name': "prototype"
|
||||
},
|
||||
]
|
||||
|
||||
# =========================================================================
|
||||
# 2. 使用上下文管理器启动多传感器
|
||||
# =========================================================================
|
||||
# MultiSensor 会自动:
|
||||
# - 为每个配置创建独立的子进程
|
||||
# - 在子进程中初始化 Sensor 实例
|
||||
# - 持续采集和处理数据
|
||||
# - 通过队列将结果传回主进程
|
||||
# compute_contact=True 启用接触点检测(深度图、质心、轮廓)
|
||||
with orisys.MultiSensor(configs, compute_contact=True) as multi:
|
||||
print("\n多传感器已启动,按 'q' 退出")
|
||||
|
||||
# =====================================================================
|
||||
# 3. 迭代获取所有传感器的数据
|
||||
# =====================================================================
|
||||
# multi 是可迭代的,每次迭代返回所有传感器的最新数据列表
|
||||
# all_data = [data_sensor_0, data_sensor_1, ...]
|
||||
for all_data in multi:
|
||||
# 过滤掉 None(某些传感器可能暂时没有新数据)
|
||||
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"Deformation {sid}", 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(f"Contact Centroid {sid}", image_with_foe)
|
||||
|
||||
if data['depth_map'] is not None and data['depth_map'].size > 0:
|
||||
# 归一化散度值到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(f"Depth Map {sid}", cv2.applyColorMap(div_normalized, cv2.COLORMAP_JET))
|
||||
|
||||
|
||||
# 检查退出键
|
||||
if cv2.waitKey(1) & 0xFF == ord('q'):
|
||||
break
|
||||
|
||||
# 上下文管理器退出时自动停止所有子进程
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Windows 下多进程必需的初始化
|
||||
mp.freeze_support()
|
||||
main()
|
||||
Reference in New Issue
Block a user