BodyBalanceEvaluation/backend/test_backend_optimization.py

235 lines
8.4 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
OpenCV后端优化验证脚本
测试DirectShow后端相对于MSMF的性能提升
"""
import sys
import os
import time
import logging
# 添加项目路径
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from devices.camera_manager import CameraManager
from devices.utils.config_manager import ConfigManager
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
def test_backend_performance(backend_name, test_name):
"""
测试指定后端的性能
Args:
backend_name: 后端名称 (directshow, msmf)
test_name: 测试名称
Returns:
dict: 性能数据
"""
print(f"\n{'='*60}")
print(f"📷 测试 {test_name} 后端性能")
print(f"{'='*60}")
# 创建配置管理器并设置后端
config_manager = ConfigManager()
# 获取原始配置
original_config = config_manager.get_device_config('camera')
# 设置测试后端
test_config = {
'backend': backend_name
}
config_manager.set_camera_config(test_config)
try:
# 创建相机管理器
camera = CameraManager(None, config_manager)
# 测试初始化性能
start_time = time.time()
success = camera.initialize()
total_time = (time.time() - start_time) * 1000
if success:
print(f"✅ 相机初始化成功: {total_time:.1f}ms")
# 获取实际后端信息
if camera.cap:
backend_info = camera.cap.getBackendName() if hasattr(camera.cap, 'getBackendName') else 'Unknown'
actual_width = int(camera.cap.get(cv2.CAP_PROP_FRAME_WIDTH))
actual_height = int(camera.cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
actual_fps = camera.cap.get(cv2.CAP_PROP_FPS)
print(f"🎯 实际后端: {backend_info}")
print(f"📐 实际分辨率: {actual_width}x{actual_height}@{actual_fps:.1f}fps")
# 测试首帧获取
frame_start = time.time()
ret, frame = camera.cap.read() if camera.cap else (False, None)
frame_time = (time.time() - frame_start) * 1000
if ret and frame is not None:
print(f"🖼️ 首帧获取: {frame_time:.1f}ms, 帧大小: {frame.shape}")
else:
print(f"❌ 首帧获取失败")
frame_time = -1
# 测试连续帧性能
print(f"🎬 测试连续帧获取性能...")
frame_times = []
for i in range(10):
frame_start = time.time()
ret, frame = camera.cap.read() if camera.cap else (False, None)
if ret:
frame_times.append((time.time() - frame_start) * 1000)
time.sleep(0.01) # 小延迟
if frame_times:
avg_frame_time = sum(frame_times) / len(frame_times)
min_frame_time = min(frame_times)
max_frame_time = max(frame_times)
print(f"📈 连续帧性能: 平均 {avg_frame_time:.1f}ms, 最快 {min_frame_time:.1f}ms, 最慢 {max_frame_time:.1f}ms")
else:
avg_frame_time = -1
print(f"❌ 连续帧测试失败")
# 清理资源
camera.cleanup()
print(f"🧹 相机资源已释放")
return {
'backend': backend_name,
'success': True,
'init_time': total_time,
'first_frame_time': frame_time,
'avg_frame_time': avg_frame_time,
'backend_info': backend_info if camera.cap else 'Unknown',
'resolution': f"{actual_width}x{actual_height}@{actual_fps:.1f}fps" if camera.cap else "未知"
}
else:
print(f"❌ 初始化失败")
return {
'backend': backend_name,
'success': False,
'init_time': total_time,
'first_frame_time': -1,
'avg_frame_time': -1,
'backend_info': 'Failed',
'resolution': "失败"
}
except Exception as e:
print(f"❌ 测试异常: {e}")
return {
'backend': backend_name,
'success': False,
'init_time': -1,
'first_frame_time': -1,
'avg_frame_time': -1,
'backend_info': 'Exception',
'resolution': "异常",
'error': str(e)
}
finally:
# 恢复原始配置
try:
restore_config = {
'backend': original_config['backend']
}
config_manager.set_camera_config(restore_config)
except Exception as e:
print(f"⚠️ 恢复配置失败: {e}")
def main():
"""
主函数测试不同后端的性能
"""
print("\n" + "="*80)
print("🚀 OpenCV后端性能优化验证")
print("="*80)
# 测试用例
test_cases = [
('directshow', 'DirectShow (推荐)'),
('msmf', 'MSMF (默认)')
]
results = []
# 执行测试
for backend, name in test_cases:
result = test_backend_performance(backend, name)
results.append(result)
time.sleep(1) # 测试间隔
# 汇总结果
print(f"\n\n{'='*80}")
print(f"📊 后端性能优化验证汇总")
print(f"{'='*80}")
# 表格头
print(f"{'后端':<12} {'状态':<8} {'初始化':<12} {'首帧':<12} {'连续帧':<12} {'实际后端':<15}")
print("-" * 80)
successful_results = [r for r in results if r['success']]
for result in results:
status = "✅成功" if result['success'] else "❌失败"
init_time = f"{result['init_time']:.1f}ms" if result['init_time'] > 0 else "失败"
first_frame = f"{result['first_frame_time']:.1f}ms" if result['first_frame_time'] > 0 else "失败"
avg_frame = f"{result['avg_frame_time']:.1f}ms" if result['avg_frame_time'] > 0 else "失败"
backend_info = result['backend_info'][:14] if len(result['backend_info']) > 14 else result['backend_info']
print(f"{result['backend']:<12} {status:<8} {init_time:<12} {first_frame:<12} {avg_frame:<12} {backend_info:<15}")
# 性能分析
if len(successful_results) >= 2:
print(f"\n📈 性能分析:")
# 找到最快的后端
fastest = min(successful_results, key=lambda x: x['init_time'])
slowest = max(successful_results, key=lambda x: x['init_time'])
print(f"🏆 最快后端: {fastest['backend']} - {fastest['init_time']:.1f}ms")
print(f"🐌 最慢后端: {slowest['backend']} - {slowest['init_time']:.1f}ms")
if fastest['init_time'] > 0 and slowest['init_time'] > 0:
improvement = ((slowest['init_time'] - fastest['init_time']) / slowest['init_time']) * 100
print(f"💡 性能提升: {improvement:.1f}% (使用最快后端)")
print(f"\n📋 详细性能对比:")
for result in successful_results:
if result != fastest:
slowdown = ((result['init_time'] - fastest['init_time']) / fastest['init_time']) * 100
print(f" {result['backend']}: 比最快后端慢 {slowdown:.1f}% ({result['init_time']:.1f}ms vs {fastest['init_time']:.1f}ms)")
print(f"\n🎯 建议:")
if successful_results:
fastest = min(successful_results, key=lambda x: x['init_time'])
print(f"✅ 推荐使用 {fastest['backend']} 后端以获得最佳性能")
print(f"📝 配置建议: 在配置文件中设置 backend = {fastest['backend']}")
if fastest['init_time'] > 5000:
print(f"⚠️ 性能评级: 需要优化 (> 5秒)")
elif fastest['init_time'] > 2000:
print(f"⚠️ 性能评级: 一般 (2-5秒)")
else:
print(f"✅ 性能评级: 良好 (< 2秒)")
else:
print(f"❌ 所有后端测试失败,请检查相机连接")
print(f"\n{'='*80}")
print(f"测试完成")
print(f"{'='*80}")
if __name__ == "__main__":
import cv2 # 需要导入cv2用于相机操作
main()