#!/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()