深度相机足部压力视频推流提交

This commit is contained in:
jingna 2025-08-14 11:33:34 +08:00 committed by zhaozilong12
parent 7a52183119
commit c48cc3eb63
11 changed files with 958 additions and 317 deletions

1
.gitignore vendored
View File

@ -10020,3 +10020,4 @@ node_modules/date-fns/subQuarters/index.js
node_modules/date-fns/subQuarters/index.js.flow
Log/OrbbecSDK.log.txt
Log/OrbbecSDK.log.txt
backend/Log/OrbbecSDK.log.txt

View File

@ -164,7 +164,10 @@ def init_app():
logger.info('SocketIO已启用')
device_manager.set_socketio(socketio) # 设置WebSocket连接
# 初始化视频流管理器
t_vsm = time.time()
logger.info(f'[TIMING] 准备创建VideoStreamManager - {datetime.now().strftime("%H:%M:%S.%f")[:-3]}')
video_stream_manager = VideoStreamManager(socketio, device_manager)
logger.info(f'[TIMING] VideoStreamManager创建完成耗时: {(time.time()-t_vsm)*1000:.2f}ms')
else:
logger.info('SocketIO未启用跳过WebSocket相关初始化')
video_stream_manager = None
@ -1058,9 +1061,10 @@ if socketio is not None:
# 启动视频流管理器(普通摄像头)
if video_stream_manager:
logger.info('正在启动视频流管理器...')
t_vs = time.time()
logger.info(f'[TIMING] 即将调用start_video_stream - {datetime.now().strftime("%H:%M:%S.%f")[:-3]}')
video_result = video_stream_manager.start_video_stream()
logger.info(f'视频流管理器启动结果: {video_result}')
logger.info(f'[TIMING] start_video_stream返回耗时: {(time.time()-t_vs)*1000:.2f}ms: {video_result}')
results['cameras']['normal'] = video_result
else:
logger.error('视频流管理器未初始化')

View File

@ -16,11 +16,11 @@ backup_interval = 24
max_backups = 7
[DEVICES]
camera_index = 0
camera_index = 3
camera_width = 640
camera_height = 480
camera_fps = 30
imu_port = COM4
imu_port = COM8
imu_baudrate = 9600
pressure_port = COM4

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -30,7 +30,7 @@ class CameraViewer:
if __name__ == "__main__":
# 修改这里的数字可以切换不同摄像头设备
viewer = CameraViewer(device_index=0)
viewer = CameraViewer(device_index=3)
viewer.start_stream()
# import ctypes

Binary file not shown.

View File

@ -1,194 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
SMiTSense足部压力传感器简单演示程序
展示如何使用SMiTSenseUsb-F3.0.dll进行基本的压力数据采集
"""
import sys
import os
import time
from test_smitsense_dll import SMiTSensePressureSensor
def simple_pressure_monitor():
"""
简单的压力监控演示
"""
print("SMiTSense足部压力传感器演示")
print("=" * 40)
# 创建传感器实例
sensor = SMiTSensePressureSensor()
try:
# 初始化
print("正在初始化传感器...")
if not sensor.initialize():
print("❌ 初始化失败")
return
# 查找设备
print("正在查找设备...")
devices = sensor.get_device_list()
if not devices:
print("❌ 未找到SMiTSense设备")
print("请检查:")
print("1. 设备是否正确连接")
print("2. 驱动程序是否已安装")
print("3. 设备是否被其他程序占用")
return
print(f"✅ 找到 {len(devices)} 个设备")
# 连接第一个设备
print("正在连接设备...")
if not sensor.connect(devices[0]):
print("❌ 连接失败")
return
print("✅ 设备连接成功")
# 获取灵敏度
sensitivity = sensor.get_sensitivity()
if sensitivity is not None:
print(f"当前灵敏度: {sensitivity}")
# 开始监控压力数据
print("\n开始压力监控按Ctrl+C停止...")
print("-" * 60)
print("时间\t\t左前\t左后\t右前\t右后\t总压力")
print("-" * 60)
count = 0
while True:
# 读取压力数据
pressure_data = sensor.read_pressure_data()
if pressure_data:
# 转换为足部区域数据
foot_zones = sensor.get_foot_pressure_zones(pressure_data)
if foot_zones:
timestamp = time.strftime("%H:%M:%S")
print(f"{timestamp}\t{foot_zones['left_front']:.1f}\t"
f"{foot_zones['left_rear']:.1f}\t"
f"{foot_zones['right_front']:.1f}\t"
f"{foot_zones['right_rear']:.1f}\t"
f"{foot_zones['total_pressure']:.1f}")
# 简单的平衡分析
if foot_zones['total_pressure'] > 10: # 有压力时才分析
left_ratio = foot_zones['left_total'] / foot_zones['total_pressure']
if left_ratio < 0.4:
balance_status = "右倾"
elif left_ratio > 0.6:
balance_status = "左倾"
else:
balance_status = "平衡"
if count % 10 == 0: # 每10次显示一次平衡状态
print(f"\t\t\t\t\t\t\t平衡状态: {balance_status}")
else:
print(f"{time.strftime('%H:%M:%S')}\t数据处理失败")
else:
print(f"{time.strftime('%H:%M:%S')}\t无数据")
count += 1
time.sleep(0.2) # 5Hz采样率
except KeyboardInterrupt:
print("\n\n用户停止监控")
except Exception as e:
print(f"\n❌ 监控过程中发生错误: {e}")
finally:
# 断开连接
print("正在断开设备连接...")
sensor.disconnect()
print("✅ 设备已断开")
def test_dll_availability():
"""
测试DLL文件是否可用
"""
print("检查DLL文件可用性...")
dll_path = os.path.join(os.path.dirname(__file__), 'SMiTSenseUsb-F3.0.dll')
if not os.path.exists(dll_path):
print(f"❌ DLL文件不存在: {dll_path}")
return False
try:
sensor = SMiTSensePressureSensor(dll_path)
print("✅ DLL文件加载成功")
# 测试基本函数调用
result = sensor.initialize()
print(f"✅ 初始化函数调用成功,返回值: {result}")
return True
except Exception as e:
print(f"❌ DLL测试失败: {e}")
return False
def show_usage():
"""
显示使用说明
"""
print("""
SMiTSense足部压力传感器使用说明
=================================
1. 硬件准备
- 确保SMiTSense足部压力传感器已正确连接到USB端口
- 安装相应的设备驱动程序
- 确保设备未被其他程序占用
2. 软件准备
- 确保SMiTSenseUsb-F3.0.dll文件在当前目录中
- 安装Python 3.6+
- 确保ctypes库可用Python标准库
3. 运行程序
python smitsense_demo.py
4. 功能说明
- 自动检测并连接SMiTSense设备
- 实时显示足部各区域压力数据
- 简单的平衡状态分析
- 支持Ctrl+C安全退出
5. 数据说明
- 左前/左后/右前/右后对应足部四个区域的压力值
- 总压力所有传感器压力值的总和
- 平衡状态基于左右脚压力分布的简单分析
6. 故障排除
- 如果提示"未找到设备"请检查硬件连接和驱动
- 如果提示"DLL加载失败"请检查DLL文件路径
- 如果数据异常请检查传感器校准状态
7. 集成到现有系统
- 可以将SMiTSensePressureSensor类集成到device_manager.py中
- 替换现有的MockPressureDevice模拟设备
- 实现真实的压力传感器数据采集
""")
if __name__ == "__main__":
if len(sys.argv) > 1 and sys.argv[1] == "--help":
show_usage()
sys.exit(0)
print("SMiTSense足部压力传感器演示程序")
print("使用 --help 参数查看详细使用说明")
print()
# 首先测试DLL可用性
if not test_dll_availability():
print("\n请检查DLL文件和依赖项后重试")
sys.exit(1)
print()
# 运行压力监控演示
simple_pressure_monitor()

85
backend/tests/testsmit.py Normal file
View File

@ -0,0 +1,85 @@
import ctypes
import time
import numpy as np
import cv2
# === DLL 加载 ===
dll = ctypes.WinDLL(r"D:\BodyBalanceEvaluation\backend\tests\SMiTSenseUsbWrapper.dll")
dll.SMiTSenseUsb_Init.argtypes = [ctypes.c_int]
dll.SMiTSenseUsb_Init.restype = ctypes.c_int
dll.SMiTSenseUsb_ScanDevices.argtypes = [ctypes.POINTER(ctypes.c_int)]
dll.SMiTSenseUsb_ScanDevices.restype = ctypes.c_int
dll.SMiTSenseUsb_OpenAndStart.argtypes = [
ctypes.c_int,
ctypes.POINTER(ctypes.c_uint16),
ctypes.POINTER(ctypes.c_uint16)
]
dll.SMiTSenseUsb_OpenAndStart.restype = ctypes.c_int
dll.SMiTSenseUsb_GetLatestFrame.argtypes = [
ctypes.POINTER(ctypes.c_uint16),
ctypes.c_int
]
dll.SMiTSenseUsb_GetLatestFrame.restype = ctypes.c_int
dll.SMiTSenseUsb_StopAndClose.argtypes = []
dll.SMiTSenseUsb_StopAndClose.restype = ctypes.c_int
# === 初始化设备 ===
ret = dll.SMiTSenseUsb_Init(0)
if ret != 0:
raise RuntimeError(f"Init failed: {ret}")
count = ctypes.c_int()
ret = dll.SMiTSenseUsb_ScanDevices(ctypes.byref(count))
if ret != 0 or count.value == 0:
raise RuntimeError("No devices found")
rows = ctypes.c_uint16()
cols = ctypes.c_uint16()
ret = dll.SMiTSenseUsb_OpenAndStart(0, ctypes.byref(rows), ctypes.byref(cols))
if ret != 0:
raise RuntimeError("OpenAndStart failed")
rows, cols = rows.value, cols.value
frame_size = rows * cols
buf_type = ctypes.c_uint16 * frame_size
buf = buf_type()
print(f"实时采集: {rows} 行 x {cols}")
# 固定映射范围(和原来 matplotlib 一样)
vmin, vmax = 0, 1000
try:
while True:
ret = dll.SMiTSenseUsb_GetLatestFrame(buf, frame_size)
if ret == 0:
data = np.frombuffer(buf, dtype=np.uint16).reshape((rows, cols))
# 固定范围映射到 0-255
norm_data = np.clip((data - vmin) / (vmax - vmin) * 255, 0, 255).astype(np.uint8)
# 颜色映射jet
heatmap = cv2.applyColorMap(norm_data, cv2.COLORMAP_JET)
# 放大显示(保持 nearest 效果)
heatmap = cv2.resize(heatmap, (cols * 4, rows * 4), interpolation=cv2.INTER_NEAREST)
# 显示
cv2.imshow("SMiTSense 足底压力分布", heatmap)
if cv2.waitKey(1) & 0xFF == 27: # ESC 退出
break
else:
print("读取数据帧失败")
time.sleep(0.05) # 20 FPS
except KeyboardInterrupt:
pass
finally:
dll.SMiTSenseUsb_StopAndClose()
cv2.destroyAllWindows()
print("设备已关闭")

View File

@ -19,7 +19,7 @@ camera_index = 0
camera_width = 640
camera_height = 480
camera_fps = 30
imu_port = COM3
imu_port = COM8
pressure_port = COM4
[DETECTION]

View File

@ -204,16 +204,16 @@
<div class="yline"></div>
</div>
<div
style="display: flex;justify-content: center;margin-top: 8px;font-size: 18px;width: 470px;margin-left: -95px;">
<div style="width: 215px;">
<span>左足总压力</span>
<span class="foot-container-paddingcolor">{{ footPressure.left_total
}}%</span>
style="display: flex;justify-content: center;margin-top: 8px;font-size: 18px;width: 470px;margin-left: -85px;">
<div style="width: 215px;display: flex;align-items: center;">
<div style="width:95px;">左足总压力</div>
<div style="width:130px;" class="foot-container-paddingcolor">{{ footPressure.left_total
}}%</div>
</div>
<div class="foot-container-marginleft" style="width: 215px;">
<span>右足总压力</span>
<span class="foot-container-paddingcolor">{{ footPressure.right_total
}}%</span>
<div class="foot-container-marginleft" style="width: 215px;display: flex;align-items: center;">
<div style="width:95px;">右足总压力</div>
<div style="width:130px;" class="foot-container-paddingcolor">{{ footPressure.right_total
}}%</div>
</div>
</div>
</div>