update multiproecssing for max. speed to 130fps
This commit is contained in:
@@ -94,9 +94,6 @@ def sensor_worker(sensor_id, vid_src, config_name, cal_path, result_queue, stop_
|
|||||||
# 如果队列已满,跳过这一帧
|
# 如果队列已满,跳过这一帧
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# 短暂休眠,避免过度占用CPU
|
|
||||||
time.sleep(0.001)
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"传感器 {sensor_id} 处理错误: {e}")
|
print(f"传感器 {sensor_id} 处理错误: {e}")
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
@@ -118,22 +115,24 @@ def main():
|
|||||||
sensor_configs = [
|
sensor_configs = [
|
||||||
{
|
{
|
||||||
'sensor_id': 0,
|
'sensor_id': 0,
|
||||||
'vid_src': './s1.mp4',
|
'vid_src': './s1_720p.mp4',
|
||||||
'config_name': 'prototype',
|
'config_name': './config/prototype_of3_720p.json',
|
||||||
'cal_path': './config/cal.npy'
|
'cal_path': './config/dd01a_0_720p.npy'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'sensor_id': 1,
|
'sensor_id': 1,
|
||||||
'vid_src': './s1.mp4', # 可以改为不同的视频源或摄像头索引
|
'vid_src': './s1_720p.mp4', # 可以改为不同的视频源或摄像头索引
|
||||||
'config_name': 'prototype',
|
'config_name': './config/prototype_of3_720p.json',
|
||||||
'cal_path': './config/cal2.npy'
|
'cal_path': './config/dd01a_0_720p.npy'
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
# 2. 创建进程间通信对象
|
# 2. 创建进程间通信对象
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
result_queues = [Queue(maxsize=num_sensors) for _ in sensor_configs] # 每个传感器一个队列
|
# 增大队列大小以缓冲更多帧,避免因主进程处理延迟导致的丢帧
|
||||||
|
# 使用更大的缓冲区以平滑FPS波动
|
||||||
|
result_queues = [Queue(maxsize=30) for _ in sensor_configs] # 每个传感器一个队列,缓冲30帧
|
||||||
stop_events = [mp.Event() for _ in sensor_configs] # 停止事件
|
stop_events = [mp.Event() for _ in sensor_configs] # 停止事件
|
||||||
|
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
@@ -154,21 +153,32 @@ def main():
|
|||||||
# 用于存储每个传感器的最新数据
|
# 用于存储每个传感器的最新数据
|
||||||
latest_data = [None] * len(sensor_configs)
|
latest_data = [None] * len(sensor_configs)
|
||||||
|
|
||||||
|
# 用于控制打印频率,减少I/O开销
|
||||||
|
print_counter = 0
|
||||||
|
print_interval = 30 # 每30帧打印一次,进一步减少I/O
|
||||||
|
|
||||||
|
# 用于控制按键检查频率
|
||||||
|
key_check_counter = 0
|
||||||
|
key_check_interval = 5 # 每5帧检查一次按键
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# =====================================================================
|
# =====================================================================
|
||||||
# 4. 主循环:从队列获取数据并显示
|
# 4. 主循环:从队列获取数据并显示
|
||||||
# =====================================================================
|
# =====================================================================
|
||||||
while True:
|
while True:
|
||||||
# 从所有队列中获取最新数据
|
# 从所有队列中快速获取最新数据(高效清空队列,只保留最新帧)
|
||||||
for i, queue in enumerate(result_queues):
|
for i, queue in enumerate(result_queues):
|
||||||
try:
|
# 快速清空队列,只保留最后一帧
|
||||||
# 非阻塞获取,获取队列中最新的数据
|
data = None
|
||||||
while True:
|
# 一次性获取所有可用数据,只保留最后一个
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
data = queue.get_nowait()
|
data = queue.get_nowait()
|
||||||
latest_data[i] = data
|
except:
|
||||||
except:
|
break
|
||||||
# 队列为空,使用之前的数据
|
|
||||||
pass
|
if data is not None:
|
||||||
|
latest_data[i] = data
|
||||||
|
|
||||||
# 显示所有传感器的数据
|
# 显示所有传感器的数据
|
||||||
for data in latest_data:
|
for data in latest_data:
|
||||||
@@ -207,15 +217,24 @@ def main():
|
|||||||
div_normalized = np.zeros_like(div_abs, dtype=np.uint8)
|
div_normalized = np.zeros_like(div_abs, dtype=np.uint8)
|
||||||
cv2.imshow(f"Depth Map {sid}",
|
cv2.imshow(f"Depth Map {sid}",
|
||||||
cv2.applyColorMap(div_normalized, cv2.COLORMAP_JET))
|
cv2.applyColorMap(div_normalized, cv2.COLORMAP_JET))
|
||||||
|
|
||||||
# 打印FPS
|
|
||||||
print(f"传感器 {sid}: FPS={data['fps']:5.1f}")
|
|
||||||
|
|
||||||
# 检查退出键
|
# 降低打印频率以减少I/O开销(在主循环级别控制)
|
||||||
key = cv2.waitKey(1) & 0xFF
|
print_counter += 1
|
||||||
if key == ord('q'):
|
if print_counter >= print_interval:
|
||||||
print("\n退出程序...")
|
for data in latest_data:
|
||||||
break
|
if data is not None and 'error' not in data:
|
||||||
|
sid = data['sensor_id']
|
||||||
|
print(f"传感器 {sid}: FPS={data['fps']:5.1f}")
|
||||||
|
print_counter = 0
|
||||||
|
|
||||||
|
# 降低按键检查频率以减少开销
|
||||||
|
key_check_counter += 1
|
||||||
|
if key_check_counter >= key_check_interval:
|
||||||
|
key = cv2.waitKey(1) & 0xFF
|
||||||
|
if key == ord('q'):
|
||||||
|
print("\n退出程序...")
|
||||||
|
break
|
||||||
|
key_check_counter = 0
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
# =====================================================================
|
# =====================================================================
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ class Sensor:
|
|||||||
diff = cv2.absdiff(self.img, self.initial_img)
|
diff = cv2.absdiff(self.img, self.initial_img)
|
||||||
return diff.mean() > threshold
|
return diff.mean() > threshold
|
||||||
|
|
||||||
def compute_deformation(self):
|
def compute_deformation(self, decompose=True):
|
||||||
"""
|
"""
|
||||||
Compute optical flow and decompose into force components.
|
Compute optical flow and decompose into force components.
|
||||||
|
|
||||||
@@ -220,7 +220,8 @@ class Sensor:
|
|||||||
raise Exception("Warning: Get image first")
|
raise Exception("Warning: Get image first")
|
||||||
|
|
||||||
self.__compute_flow()
|
self.__compute_flow()
|
||||||
self.__compute_hhd()
|
if decompose:
|
||||||
|
self.__compute_hhd()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user