#!/usr/bin/env python3 """ Quick test script for YOLOv5 pipeline deployment using fixed configuration """ import sys import os # Add paths sys.path.append(os.path.join(os.path.dirname(__file__), 'ui', 'dialogs')) sys.path.append(os.path.join(os.path.dirname(__file__), 'core', 'functions')) def test_mflow_loading(): """Test loading and parsing the fixed .mflow file""" import json mflow_files = [ 'multi_series_example.mflow', 'multi_series_yolov5_fixed.mflow', 'test.mflow' ] print("=" * 60) print("Testing .mflow Configuration Loading") print("=" * 60) for mflow_file in mflow_files: if os.path.exists(mflow_file): print(f"\nšŸ“„ Loading {mflow_file}:") try: with open(mflow_file, 'r') as f: data = json.load(f) # Check for postprocess nodes postprocess_nodes = [ node for node in data.get('nodes', []) if node.get('type') == 'ExactPostprocessNode' ] if postprocess_nodes: for node in postprocess_nodes: props = node.get('properties', {}) postprocess_type = props.get('postprocess_type', 'NOT SET') confidence_threshold = props.get('confidence_threshold', 'NOT SET') class_names = props.get('class_names', 'NOT SET') print(f" āœ“ Found PostprocessNode: {node.get('name', 'Unnamed')}") print(f" - Type: {postprocess_type}") print(f" - Threshold: {confidence_threshold}") print(f" - Classes: {len(class_names.split(',')) if isinstance(class_names, str) else 'N/A'} classes") if postprocess_type == 'yolo_v5': print(f" āœ… Correctly configured for YOLOv5") else: print(f" āŒ Still using: {postprocess_type}") else: print(f" ⚠ No ExactPostprocessNode found") except Exception as e: print(f" āŒ Error loading file: {e}") else: print(f"\nšŸ“„ {mflow_file}: File not found") def test_deployment_direct(): """Test deployment using the deployment dialog directly""" try: from deployment import DeploymentDialog from PyQt5.QtWidgets import QApplication print(f"\n" + "=" * 60) print("Testing Direct Pipeline Deployment") print("=" * 60) # Load the fixed configuration import json config_file = 'multi_series_yolov5_fixed.mflow' if not os.path.exists(config_file): print(f"āŒ Configuration file not found: {config_file}") return with open(config_file, 'r') as f: pipeline_data = json.load(f) print(f"āœ“ Loaded configuration: {pipeline_data.get('project_name', 'Unknown')}") print(f"āœ“ Found {len(pipeline_data.get('nodes', []))} nodes") # Create minimal Qt app for testing app = QApplication.instance() if app is None: app = QApplication(sys.argv) # Create deployment dialog dialog = DeploymentDialog(pipeline_data) print(f"āœ“ Created deployment dialog") # Test analysis print(f"šŸ” Testing pipeline analysis...") try: from core.functions.mflow_converter import MFlowConverter converter = MFlowConverter() config = converter._convert_mflow_to_config(pipeline_data) print(f"āœ“ Pipeline conversion successful") print(f" - Pipeline name: {config.pipeline_name}") print(f" - Total stages: {len(config.stage_configs)}") # Check stage configurations for i, stage_config in enumerate(config.stage_configs, 1): print(f" Stage {i}: {stage_config.stage_id}") if hasattr(stage_config, 'postprocessor_options') and stage_config.postprocessor_options: print(f" - Postprocess type: {stage_config.postprocessor_options.postprocess_type.value}") print(f" - Threshold: {stage_config.postprocessor_options.threshold}") print(f" - Classes: {len(stage_config.postprocessor_options.class_names)}") if stage_config.postprocessor_options.postprocess_type.value == 'yolo_v5': print(f" āœ… YOLOv5 postprocessing configured correctly") else: print(f" āŒ Postprocessing type: {stage_config.postprocessor_options.postprocess_type.value}") except Exception as e: print(f"āŒ Pipeline conversion failed: {e}") import traceback traceback.print_exc() except ImportError as e: print(f"āŒ Cannot import deployment components: {e}") print(f" This is expected if running outside the full application") except Exception as e: print(f"āŒ Direct deployment test failed: {e}") import traceback traceback.print_exc() def show_fix_summary(): """Show summary of the fixes applied""" print(f"\n" + "=" * 60) print("FIX SUMMARY") print("=" * 60) print(f"\nšŸ”§ Applied Fixes:") print(f"1. āœ… Fixed dashboard.py postprocess property loading") print(f" - Added missing 'postprocess_type' property") print(f" - Added all missing postprocess properties") print(f" - Location: ui/windows/dashboard.py:1203-1213") print(f"\n2. āœ… Enhanced YOLOv5 postprocessing in Multidongle.py") print(f" - Improved _process_yolo_generic method") print(f" - Added proper NMS (Non-Maximum Suppression)") print(f" - Enhanced live view display") print(f"\n3. āœ… Updated .mflow configurations") print(f" - multi_series_example.mflow: enable_postprocessing = true") print(f" - multi_series_yolov5_fixed.mflow: Complete YOLOv5 setup") print(f" - Added ExactPostprocessNode with yolo_v5 type") print(f"\nšŸŽÆ Expected Results After Fix:") print(f" - āŒ 'No Fire (Prob: -0.39)' → āœ… 'person detected (Conf: 0.85)'") print(f" - āŒ Negative probabilities → āœ… Positive probabilities (0.0-1.0)") print(f" - āŒ No bounding boxes → āœ… Colorful bounding boxes with labels") print(f" - āŒ Fire detection classes → āœ… COCO 80 classes (person, car, etc.)") print(f"\nšŸ’” Usage Instructions:") print(f" 1. Run: python main.py") print(f" 2. Login to the dashboard") print(f" 3. Load: multi_series_yolov5_fixed.mflow") print(f" 4. Deploy the pipeline") print(f" 5. Check Live View tab for enhanced bounding boxes") def main(): print("Quick YOLOv5 Deployment Test") print("=" * 60) # Test configuration loading test_mflow_loading() # Test direct deployment (if possible) test_deployment_direct() # Show fix summary show_fix_summary() print(f"\nšŸŽ‰ Quick test completed!") print(f" Now try running: python main.py") print(f" And load: multi_series_yolov5_fixed.mflow") if __name__ == "__main__": main()