#!/usr/bin/env python3 """ Parameter Optimization Script for Advanced Panel Splitting This script iteratively tests different percentile and min_gap parameters to find the optimal settings that result in exactly 8 panels for layout 6791346.jpg. """ import os import sys import cv2 import numpy as np from pathlib import Path from PIL import Image from advanced_splitter import AdvancedPanelSplitter import itertools def test_parameters(image_path: str, percentile: float, min_gap: int, target_panels: int = 8, verbose: bool = False) -> dict: """ Test a specific combination of parameters and return results Args: image_path: Path to the layout image percentile: Percentile threshold for gutter detection min_gap: Minimum gap size for gutter detection target_panels: Target number of panels (default: 8) verbose: Print detailed information Returns: Dict with test results """ try: # Create splitter with test parameters splitter = AdvancedPanelSplitter(percentile=percentile, min_gap=min_gap, debug=False) # Load image img = Image.open(image_path).convert("RGB") img_gray = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2GRAY) # Find boundaries boundaries = splitter.find_boundaries_auto(img_gray) panel_count = len(boundaries) - 1 # Number of panels is boundaries - 1 if verbose: print(f" Percentile: {percentile:5.1f}, Min Gap: {min_gap:2d} → {panel_count:2d} panels (boundaries: {boundaries})") return { 'percentile': percentile, 'min_gap': min_gap, 'panel_count': panel_count, 'boundaries': boundaries, 'exact_match': panel_count == target_panels, 'error': abs(panel_count - target_panels) } except Exception as e: if verbose: print(f" ERROR with percentile={percentile}, min_gap={min_gap}: {e}") return { 'percentile': percentile, 'min_gap': min_gap, 'panel_count': 0, 'boundaries': [], 'exact_match': False, 'error': float('inf'), 'exception': str(e) } def optimize_parameters(image_path: str, target_panels: int = 8) -> dict: """ Optimize parameters to achieve the target number of panels Args: image_path: Path to the layout image target_panels: Target number of panels Returns: Dict with optimization results """ if not os.path.exists(image_path): raise FileNotFoundError(f"Image not found: {image_path}") print(f"Optimizing parameters for {os.path.basename(image_path)}") print(f"Target panel count: {target_panels}") print("-" * 60) # Define parameter ranges to test percentile_range = list(range(1, 51)) # 1% to 50% min_gap_range = list(range(1, 21)) # 1 to 20 pixels # Store all results all_results = [] exact_matches = [] print("Testing parameter combinations...") total_combinations = len(percentile_range) * len(min_gap_range) tested = 0 # Test all combinations for percentile in percentile_range: for min_gap in min_gap_range: tested += 1 if tested % 50 == 0: print(f" Progress: {tested}/{total_combinations} ({tested/total_combinations*100:.1f}%)") result = test_parameters(image_path, percentile, min_gap, target_panels) all_results.append(result) if result['exact_match']: exact_matches.append(result) print(f"\nCompleted testing {total_combinations} parameter combinations") print(f"Found {len(exact_matches)} exact matches for {target_panels} panels") # Analysis if exact_matches: print("\n" + "="*60) print("EXACT MATCHES FOUND!") print("="*60) print(f"\nAll parameter combinations that produce exactly {target_panels} panels:") print("Percentile | Min Gap | Boundaries") print("-" * 40) for match in exact_matches: boundaries_str = str(match['boundaries']) if len(boundaries_str) > 40: boundaries_str = boundaries_str[:37] + "..." print(f"{match['percentile']:9.1f} | {match['min_gap']:7d} | {boundaries_str}") # Find the "best" match (middle percentile value for stability) exact_matches.sort(key=lambda x: x['percentile']) middle_idx = len(exact_matches) // 2 best_match = exact_matches[middle_idx] print(f"\nRECOMMENDED PARAMETERS:") print(f" Percentile: {best_match['percentile']}") print(f" Min Gap: {best_match['min_gap']}") print(f" Result: {best_match['panel_count']} panels") print(f" Boundaries: {best_match['boundaries']}") return best_match else: print("\n" + "="*60) print("NO EXACT MATCHES FOUND") print("="*60) # Find closest matches all_results.sort(key=lambda x: x['error']) closest_matches = [r for r in all_results[:10] if r['error'] == all_results[0]['error']] print(f"\nClosest matches (error = {all_results[0]['error']}):") print("Percentile | Min Gap | Panels | Error | Boundaries") print("-" * 60) for match in closest_matches: boundaries_str = str(match['boundaries']) if len(boundaries_str) > 30: boundaries_str = boundaries_str[:27] + "..." print(f"{match['percentile']:9.1f} | {match['min_gap']:7d} | {match['panel_count']:6d} | {match['error']:5.1f} | {boundaries_str}") best_match = closest_matches[0] print(f"\nBEST AVAILABLE PARAMETERS:") print(f" Percentile: {best_match['percentile']}") print(f" Min Gap: {best_match['min_gap']}") print(f" Result: {best_match['panel_count']} panels (target: {target_panels})") print(f" Boundaries: {best_match['boundaries']}") return best_match def test_optimized_parameters(image_path: str, percentile: float, min_gap: int): """ Test the optimized parameters and show detailed results """ print("\n" + "="*60) print("TESTING OPTIMIZED PARAMETERS") print("="*60) # Create splitter with optimized parameters splitter = AdvancedPanelSplitter(percentile=percentile, min_gap=min_gap, debug=True) # Test the parameters result = test_parameters(image_path, percentile, min_gap, target_panels=8, verbose=True) # Also create the actual splits to verify print(f"\nCreating actual splits with optimized parameters...") splits = splitter.split_panels(image_path, target_panel_count=8) print(f"Successfully created {len(splits)} splits:") for i, split in enumerate(splits): bounds = split['bounds'] print(f" Panel {i+1}: bounds=({bounds[0]}, {bounds[1]}, {bounds[2]}, {bounds[3]}), " f"confidence={split['confidence']:.3f}, method={split['method']}") return result def main(): """Main execution function""" # Check if layout image exists layout_path = "layouts/6791346.jpg" if not os.path.exists(layout_path): print(f"Error: Layout image not found at {layout_path}") print("Please ensure the image exists in the layouts directory") return 1 try: # Run optimization best_result = optimize_parameters(layout_path, target_panels=8) # Test the optimized parameters test_result = test_optimized_parameters( layout_path, best_result['percentile'], best_result['min_gap'] ) print("\n" + "="*60) print("FINAL RECOMMENDATION") print("="*60) print(f"For layout 6791346.jpg to achieve 8 panels:") print(f" --percentile {best_result['percentile']}") print(f" --min-gap {best_result['min_gap']}") print(f"\nCommand line usage:") print(f" python cli.py --test --hybrid --split-advanced --percentile {best_result['percentile']} --min-gap {best_result['min_gap']}") return 0 except Exception as e: print(f"Error during optimization: {e}") return 1 if __name__ == "__main__": exit(main())