|
|
|
|
|
""" |
|
|
Parameter behavior analysis for mosaic generator |
|
|
Focuses on: parameter degradation effects, CIFAR comparison, cross-image consistency |
|
|
Analyzes three images: akaza, IMG_5090, IMG_6914 |
|
|
""" |
|
|
|
|
|
import json |
|
|
import pandas as pd |
|
|
import numpy as np |
|
|
import matplotlib.pyplot as plt |
|
|
import seaborn as sns |
|
|
from pathlib import Path |
|
|
import re |
|
|
from collections import defaultdict |
|
|
import warnings |
|
|
warnings.filterwarnings('ignore') |
|
|
|
|
|
|
|
|
METRICS_DIR = Path('./output/test_result/metrics') |
|
|
OUTPUT_DIR = Path('./output/analysis') |
|
|
TARGET_IMAGES = ['akaza', 'IMG_3378', 'IMG_5090', 'IMG_6914'] |
|
|
|
|
|
|
|
|
plt.style.use('default') |
|
|
sns.set_palette("husl") |
|
|
|
|
|
def setup_directories(): |
|
|
"""Create analysis output directories""" |
|
|
OUTPUT_DIR.mkdir(parents=True, exist_ok=True) |
|
|
for image in TARGET_IMAGES: |
|
|
(OUTPUT_DIR / image).mkdir(parents=True, exist_ok=True) |
|
|
print(f"[INFO] Created analysis directories under {OUTPUT_DIR}") |
|
|
|
|
|
def parse_filename(filename): |
|
|
"""Parse filename to extract parameters""" |
|
|
|
|
|
pattern = r'(.+)-min(\d+)-max(\d+)-sub([0-9p]+)-quant(\d+)-(.+)_metrics\.json' |
|
|
match = re.match(pattern, filename) |
|
|
|
|
|
if not match: |
|
|
return None |
|
|
|
|
|
image, min_size, max_size, sub_threshold, quantization, tile_library = match.groups() |
|
|
|
|
|
|
|
|
sub_threshold = sub_threshold.replace('p', '.') |
|
|
|
|
|
return { |
|
|
'image': image, |
|
|
'min_size': int(min_size), |
|
|
'max_size': int(max_size), |
|
|
'sub_threshold': float(sub_threshold), |
|
|
'quantization': int(quantization), |
|
|
'tile_library': tile_library |
|
|
} |
|
|
|
|
|
def load_metrics_data(): |
|
|
"""Load all metrics data and organize by image""" |
|
|
data_by_image = defaultdict(list) |
|
|
|
|
|
print("[INFO] Loading metrics data...") |
|
|
|
|
|
for json_file in METRICS_DIR.glob('*.json'): |
|
|
|
|
|
if not any(img in json_file.name for img in TARGET_IMAGES): |
|
|
continue |
|
|
|
|
|
parsed = parse_filename(json_file.name) |
|
|
if parsed is None: |
|
|
continue |
|
|
|
|
|
|
|
|
try: |
|
|
with open(json_file, 'r') as f: |
|
|
metrics = json.load(f) |
|
|
|
|
|
|
|
|
record = {**parsed, **metrics} |
|
|
data_by_image[parsed['image']].append(record) |
|
|
|
|
|
except Exception as e: |
|
|
print(f"[WARNING] Failed to load {json_file.name}: {e}") |
|
|
|
|
|
|
|
|
dfs = {} |
|
|
for image, records in data_by_image.items(): |
|
|
df = pd.DataFrame(records) |
|
|
dfs[image] = df |
|
|
print(f"[INFO] Loaded {len(df)} records for {image}") |
|
|
|
|
|
return dfs |
|
|
|
|
|
def create_heatmaps(df, image_name): |
|
|
"""Create heatmap visualizations for an image""" |
|
|
print(f"[INFO] Creating heatmaps for {image_name}") |
|
|
|
|
|
fig, axes = plt.subplots(2, 2, figsize=(16, 12)) |
|
|
fig.suptitle(f'Parameter Impact Heatmaps - {image_name}', fontsize=16, fontweight='bold') |
|
|
|
|
|
|
|
|
pivot1 = df.pivot_table(values='SSIM', index='min_size', columns='max_size', aggfunc='mean') |
|
|
sns.heatmap(pivot1, annot=True, fmt='.3f', ax=axes[0,0], cmap='RdYlGn') |
|
|
axes[0,0].set_title('SSIM by Min/Max Size') |
|
|
axes[0,0].set_xlabel('Max Size') |
|
|
axes[0,0].set_ylabel('Min Size') |
|
|
|
|
|
|
|
|
pivot2 = df.pivot_table(values='Overall_Quality', index='quantization', columns='tile_library', aggfunc='mean') |
|
|
sns.heatmap(pivot2, annot=True, fmt='.3f', ax=axes[0,1], cmap='RdYlGn') |
|
|
axes[0,1].set_title('Overall Quality by Quantization/Tile Library') |
|
|
axes[0,1].set_xlabel('Tile Library') |
|
|
axes[0,1].set_ylabel('Quantization') |
|
|
|
|
|
|
|
|
pivot3 = df.pivot_table(values='MSE', index='sub_threshold', columns='quantization', aggfunc='mean') |
|
|
sns.heatmap(pivot3, annot=True, fmt='.0f', ax=axes[1,0], cmap='RdYlGn_r') |
|
|
axes[1,0].set_title('MSE by Subdivision/Quantization') |
|
|
axes[1,0].set_xlabel('Quantization') |
|
|
axes[1,0].set_ylabel('Subdivision Threshold') |
|
|
|
|
|
|
|
|
pivot4 = df.pivot_table(values='Edge_Similarity', index='tile_library', columns='min_size', aggfunc='mean') |
|
|
sns.heatmap(pivot4, annot=True, fmt='.3f', ax=axes[1,1], cmap='RdYlGn') |
|
|
axes[1,1].set_title('Edge Similarity by Tile Library/Min Size') |
|
|
axes[1,1].set_xlabel('Min Size') |
|
|
axes[1,1].set_ylabel('Tile Library') |
|
|
|
|
|
plt.tight_layout() |
|
|
output_path = OUTPUT_DIR / image_name / 'heatmaps.png' |
|
|
plt.savefig(output_path, dpi=300, bbox_inches='tight') |
|
|
plt.close() |
|
|
print(f"[INFO] Saved heatmaps to {output_path}") |
|
|
|
|
|
def create_metric_comparisons(df, image_name): |
|
|
"""Create metric comparison charts""" |
|
|
print(f"[INFO] Creating metric comparisons for {image_name}") |
|
|
|
|
|
fig, axes = plt.subplots(2, 2, figsize=(16, 12)) |
|
|
fig.suptitle(f'Metric Comparisons - {image_name}', fontsize=16, fontweight='bold') |
|
|
|
|
|
|
|
|
metrics_to_plot = ['SSIM', 'Histogram_Correlation', 'Edge_Similarity', 'Overall_Quality'] |
|
|
|
|
|
for i, metric in enumerate(metrics_to_plot): |
|
|
ax = axes[i//2, i%2] |
|
|
df.boxplot(column=metric, by='tile_library', ax=ax) |
|
|
ax.set_title(f'{metric} by Tile Library') |
|
|
ax.set_xlabel('Tile Library') |
|
|
ax.set_ylabel(metric) |
|
|
ax.grid(True, alpha=0.3) |
|
|
|
|
|
plt.suptitle('') |
|
|
fig.suptitle(f'Metric Distribution by Tile Library - {image_name}', fontsize=16, fontweight='bold') |
|
|
plt.tight_layout() |
|
|
|
|
|
output_path = OUTPUT_DIR / image_name / 'metric_comparison.png' |
|
|
plt.savefig(output_path, dpi=300, bbox_inches='tight') |
|
|
plt.close() |
|
|
print(f"[INFO] Saved metric comparison to {output_path}") |
|
|
|
|
|
def create_parameter_impact(df, image_name): |
|
|
"""Create parameter impact analysis""" |
|
|
print(f"[INFO] Creating parameter impact analysis for {image_name}") |
|
|
|
|
|
fig, axes = plt.subplots(2, 3, figsize=(18, 12)) |
|
|
fig.suptitle(f'Parameter Impact Analysis - {image_name}', fontsize=16, fontweight='bold') |
|
|
|
|
|
|
|
|
quantization_impact = df.groupby('quantization')[['MSE', 'SSIM', 'Histogram_Correlation', 'Edge_Similarity']].mean() |
|
|
|
|
|
quality_metrics = ['SSIM', 'Histogram_Correlation', 'Edge_Similarity'] |
|
|
quantization_impact[quality_metrics].plot(kind='bar', ax=axes[0,0]) |
|
|
axes[0,0].set_title('Quality Metrics by Quantization') |
|
|
axes[0,0].set_xlabel('Quantization') |
|
|
axes[0,0].set_ylabel('Metric Value') |
|
|
axes[0,0].legend() |
|
|
axes[0,0].tick_params(axis='x', rotation=0) |
|
|
axes[0,0].grid(True, alpha=0.3) |
|
|
|
|
|
|
|
|
quantization_impact['MSE'].plot(kind='bar', ax=axes[0,1], color='red') |
|
|
axes[0,1].set_title('MSE by Quantization') |
|
|
axes[0,1].set_xlabel('Quantization') |
|
|
axes[0,1].set_ylabel('MSE') |
|
|
axes[0,1].tick_params(axis='x', rotation=0) |
|
|
axes[0,1].grid(True, alpha=0.3) |
|
|
|
|
|
|
|
|
df['size_ratio'] = df['max_size'] / df['min_size'] |
|
|
size_ratio_impact = df.groupby('size_ratio')['Overall_Quality'].mean() |
|
|
size_ratio_impact.plot(kind='bar', ax=axes[0,2], color='skyblue') |
|
|
axes[0,2].set_title('Overall Quality by Size Ratio (Max/Min)') |
|
|
axes[0,2].set_xlabel('Size Ratio') |
|
|
axes[0,2].set_ylabel('Overall Quality') |
|
|
axes[0,2].tick_params(axis='x', rotation=45) |
|
|
axes[0,2].grid(True, alpha=0.3) |
|
|
|
|
|
|
|
|
sub_impact = df.groupby('sub_threshold')['Overall_Quality'].mean() |
|
|
sub_impact.plot(kind='bar', ax=axes[1,0], color='lightcoral') |
|
|
axes[1,0].set_title('Overall Quality by Subdivision Threshold') |
|
|
axes[1,0].set_xlabel('Subdivision Threshold') |
|
|
axes[1,0].set_ylabel('Overall Quality') |
|
|
axes[1,0].tick_params(axis='x', rotation=0) |
|
|
axes[1,0].grid(True, alpha=0.3) |
|
|
|
|
|
|
|
|
tile_performance = df.groupby('tile_library')[['MSE', 'SSIM', 'Histogram_Correlation', 'Edge_Similarity']].mean() |
|
|
quality_metrics = ['SSIM', 'Histogram_Correlation', 'Edge_Similarity'] |
|
|
tile_performance[quality_metrics].plot(kind='bar', ax=axes[1,1]) |
|
|
axes[1,1].set_title('Quality Metrics by Tile Library') |
|
|
axes[1,1].set_xlabel('Tile Library') |
|
|
axes[1,1].set_ylabel('Metric Value') |
|
|
axes[1,1].legend() |
|
|
axes[1,1].tick_params(axis='x', rotation=45) |
|
|
axes[1,1].grid(True, alpha=0.3) |
|
|
|
|
|
|
|
|
tile_performance['MSE'].plot(kind='bar', ax=axes[1,2], color='red') |
|
|
axes[1,2].set_title('MSE by Tile Library') |
|
|
axes[1,2].set_xlabel('Tile Library') |
|
|
axes[1,2].set_ylabel('MSE') |
|
|
axes[1,2].tick_params(axis='x', rotation=45) |
|
|
axes[1,2].grid(True, alpha=0.3) |
|
|
|
|
|
plt.tight_layout() |
|
|
output_path = OUTPUT_DIR / image_name / 'parameter_impact.png' |
|
|
plt.savefig(output_path, dpi=300, bbox_inches='tight') |
|
|
plt.close() |
|
|
print(f"[INFO] Saved parameter impact to {output_path}") |
|
|
|
|
|
def analyze_parameter_degradation(df, image_name): |
|
|
"""Analyze which parameters cause quality degradation (for artistic/mosaic effects)""" |
|
|
print(f"[INFO] Analyzing parameter degradation effects for {image_name}") |
|
|
|
|
|
fig, axes = plt.subplots(2, 2, figsize=(16, 12)) |
|
|
fig.suptitle(f'Parameter Degradation Analysis (For Artistic Effects) - {image_name}', fontsize=16, fontweight='bold') |
|
|
|
|
|
|
|
|
mse_by_param = {} |
|
|
mse_by_param['quantization'] = df.groupby('quantization')['MSE'].mean() |
|
|
mse_by_param['min_size'] = df.groupby('min_size')['MSE'].mean() |
|
|
mse_by_param['max_size'] = df.groupby('max_size')['MSE'].mean() |
|
|
mse_by_param['sub_threshold'] = df.groupby('sub_threshold')['MSE'].mean() |
|
|
|
|
|
|
|
|
ax = axes[0,0] |
|
|
colors = ['red', 'orange', 'green', 'blue'] |
|
|
for i, (param, values) in enumerate(mse_by_param.items()): |
|
|
ax.plot(values.index, values.values, marker='o', label=param, color=colors[i], linewidth=2) |
|
|
|
|
|
ax.set_title('MSE by Parameters (Higher = More Artistic)') |
|
|
ax.set_xlabel('Parameter Value') |
|
|
ax.set_ylabel('Average MSE') |
|
|
ax.legend() |
|
|
ax.grid(True, alpha=0.3) |
|
|
|
|
|
|
|
|
ssim_by_param = {} |
|
|
ssim_by_param['quantization'] = df.groupby('quantization')['SSIM'].mean() |
|
|
ssim_by_param['min_size'] = df.groupby('min_size')['SSIM'].mean() |
|
|
ssim_by_param['max_size'] = df.groupby('max_size')['SSIM'].mean() |
|
|
ssim_by_param['sub_threshold'] = df.groupby('sub_threshold')['SSIM'].mean() |
|
|
|
|
|
ax = axes[0,1] |
|
|
for i, (param, values) in enumerate(ssim_by_param.items()): |
|
|
ax.plot(values.index, values.values, marker='s', label=param, color=colors[i], linewidth=2) |
|
|
|
|
|
ax.set_title('SSIM by Parameters (Lower = More Artistic)') |
|
|
ax.set_xlabel('Parameter Value') |
|
|
ax.set_ylabel('Average SSIM') |
|
|
ax.legend() |
|
|
ax.grid(True, alpha=0.3) |
|
|
|
|
|
|
|
|
degradation_impact = {} |
|
|
|
|
|
|
|
|
for param in ['quantization', 'min_size', 'max_size', 'sub_threshold']: |
|
|
mse_range = mse_by_param[param].max() - mse_by_param[param].min() |
|
|
ssim_range = ssim_by_param[param].max() - ssim_by_param[param].min() |
|
|
|
|
|
|
|
|
mse_impact = mse_range / df['MSE'].std() |
|
|
ssim_impact = ssim_range / df['SSIM'].std() |
|
|
|
|
|
degradation_impact[param] = (mse_impact + ssim_impact) / 2 |
|
|
|
|
|
|
|
|
ax = axes[1,0] |
|
|
params = list(degradation_impact.keys()) |
|
|
impacts = list(degradation_impact.values()) |
|
|
|
|
|
ax.bar(params, impacts, color='lightcoral') |
|
|
ax.set_title('Parameter Impact on Quality Degradation') |
|
|
ax.set_xlabel('Parameters') |
|
|
ax.set_ylabel('Impact Score') |
|
|
ax.tick_params(axis='x', rotation=45) |
|
|
ax.grid(True, alpha=0.3) |
|
|
|
|
|
|
|
|
for i, (param, impact) in enumerate(zip(params, impacts)): |
|
|
ax.text(i, impact + 0.05, f'{impact:.2f}', ha='center', va='bottom') |
|
|
|
|
|
|
|
|
axes[1,1].axis('off') |
|
|
|
|
|
plt.tight_layout() |
|
|
output_path = OUTPUT_DIR / image_name / 'parameter_degradation.png' |
|
|
plt.savefig(output_path, dpi=300, bbox_inches='tight') |
|
|
plt.close() |
|
|
print(f"[INFO] Saved parameter degradation analysis to {output_path}") |
|
|
|
|
|
def analyze_cifar_comparison(df, image_name): |
|
|
"""Direct comparison between CIFAR-10 and CIFAR-100""" |
|
|
print(f"[INFO] Analyzing CIFAR-10 vs CIFAR-100 comparison for {image_name}") |
|
|
|
|
|
|
|
|
cifar_data = df[df['tile_library'].isin(['cifar-10', 'cifar-100'])].copy() |
|
|
|
|
|
if len(cifar_data) == 0: |
|
|
print(f"[WARNING] No CIFAR data found for {image_name}") |
|
|
return |
|
|
|
|
|
fig, axes = plt.subplots(2, 2, figsize=(16, 12)) |
|
|
fig.suptitle(f'CIFAR-10 vs CIFAR-100 Direct Comparison - {image_name}', fontsize=16, fontweight='bold') |
|
|
|
|
|
|
|
|
metrics = ['MSE', 'SSIM', 'Histogram_Correlation', 'Edge_Similarity'] |
|
|
cifar_comparison = cifar_data.groupby('tile_library')[metrics].mean() |
|
|
|
|
|
quality_metrics = ['SSIM', 'Histogram_Correlation', 'Edge_Similarity'] |
|
|
cifar_comparison[quality_metrics].T.plot(kind='bar', ax=axes[0,0], color=['lightblue', 'lightcoral']) |
|
|
axes[0,0].set_title('Quality Metrics Comparison') |
|
|
axes[0,0].set_ylabel('Metric Value') |
|
|
axes[0,0].legend(title='Tile Library') |
|
|
axes[0,0].tick_params(axis='x', rotation=45) |
|
|
axes[0,0].grid(True, alpha=0.3) |
|
|
|
|
|
|
|
|
cifar_comparison['MSE'].plot(kind='bar', ax=axes[0,1], color=['red', 'orange']) |
|
|
axes[0,1].set_title('MSE Comparison') |
|
|
axes[0,1].set_ylabel('MSE') |
|
|
axes[0,1].legend(['CIFAR-10', 'CIFAR-100']) |
|
|
axes[0,1].grid(True, alpha=0.3) |
|
|
|
|
|
|
|
|
|
|
|
cifar_data['param_combo'] = (cifar_data['min_size'].astype(str) + '_' + |
|
|
cifar_data['max_size'].astype(str) + '_' + |
|
|
cifar_data['sub_threshold'].astype(str) + '_' + |
|
|
cifar_data['quantization'].astype(str)) |
|
|
|
|
|
|
|
|
cifar10_combos = set(cifar_data[cifar_data['tile_library'] == 'cifar-10']['param_combo']) |
|
|
cifar100_combos = set(cifar_data[cifar_data['tile_library'] == 'cifar-100']['param_combo']) |
|
|
common_combos = cifar10_combos.intersection(cifar100_combos) |
|
|
|
|
|
paired_data = [] |
|
|
for combo in common_combos: |
|
|
combo_data = cifar_data[cifar_data['param_combo'] == combo] |
|
|
if len(combo_data) == 2: |
|
|
cifar10_row = combo_data[combo_data['tile_library'] == 'cifar-10'].iloc[0] |
|
|
cifar100_row = combo_data[combo_data['tile_library'] == 'cifar-100'].iloc[0] |
|
|
|
|
|
paired_data.append({ |
|
|
'combo': combo, |
|
|
'cifar10_ssim': cifar10_row['SSIM'], |
|
|
'cifar100_ssim': cifar100_row['SSIM'], |
|
|
'cifar10_mse': cifar10_row['MSE'], |
|
|
'cifar100_mse': cifar100_row['MSE'], |
|
|
'ssim_diff': cifar10_row['SSIM'] - cifar100_row['SSIM'], |
|
|
'mse_diff': cifar10_row['MSE'] - cifar100_row['MSE'] |
|
|
}) |
|
|
|
|
|
paired_df = pd.DataFrame(paired_data) |
|
|
|
|
|
|
|
|
ax = axes[1,0] |
|
|
if len(paired_df) > 0: |
|
|
ssim_wins = (paired_df['ssim_diff'] > 0).sum() |
|
|
ssim_losses = (paired_df['ssim_diff'] < 0).sum() |
|
|
|
|
|
mse_wins = (paired_df['mse_diff'] < 0).sum() |
|
|
mse_losses = (paired_df['mse_diff'] > 0).sum() |
|
|
|
|
|
categories = ['SSIM', 'MSE'] |
|
|
cifar10_scores = [ssim_wins, mse_wins] |
|
|
cifar100_scores = [ssim_losses, mse_losses] |
|
|
|
|
|
x = np.arange(len(categories)) |
|
|
width = 0.35 |
|
|
|
|
|
ax.bar(x - width/2, cifar10_scores, width, label='CIFAR-10 Wins', color='lightblue') |
|
|
ax.bar(x + width/2, cifar100_scores, width, label='CIFAR-100 Wins', color='lightcoral') |
|
|
|
|
|
ax.set_title(f'Win/Loss Analysis ({len(paired_df)} comparisons)') |
|
|
ax.set_ylabel('Number of Wins') |
|
|
ax.set_xticks(x) |
|
|
ax.set_xticklabels(categories) |
|
|
ax.legend() |
|
|
ax.grid(True, alpha=0.3) |
|
|
|
|
|
|
|
|
for i, (c10, c100) in enumerate(zip(cifar10_scores, cifar100_scores)): |
|
|
ax.text(i - width/2, c10 + 0.5, str(c10), ha='center', va='bottom') |
|
|
ax.text(i + width/2, c100 + 0.5, str(c100), ha='center', va='bottom') |
|
|
|
|
|
|
|
|
ax = axes[1,1] |
|
|
if len(paired_df) > 0: |
|
|
ax.hist(paired_df['ssim_diff'], bins=20, alpha=0.7, color='skyblue', edgecolor='black') |
|
|
ax.axvline(x=0, color='red', linestyle='--', linewidth=2) |
|
|
ax.set_title('SSIM Difference Distribution (CIFAR-10 - CIFAR-100)') |
|
|
ax.set_xlabel('SSIM Difference') |
|
|
ax.set_ylabel('Frequency') |
|
|
ax.grid(True, alpha=0.3) |
|
|
|
|
|
plt.tight_layout() |
|
|
output_path = OUTPUT_DIR / image_name / 'cifar_comparison.png' |
|
|
plt.savefig(output_path, dpi=300, bbox_inches='tight') |
|
|
plt.close() |
|
|
print(f"[INFO] Saved CIFAR comparison to {output_path}") |
|
|
|
|
|
def analyze_size_consistency(all_dfs): |
|
|
"""Analyze if min/max size effects are consistent across images""" |
|
|
print("[INFO] Analyzing min/max size consistency across images") |
|
|
|
|
|
fig, axes = plt.subplots(2, 2, figsize=(16, 12)) |
|
|
fig.suptitle('Min/Max Size Effects Consistency Across Images', fontsize=16, fontweight='bold') |
|
|
|
|
|
|
|
|
combined_data = [] |
|
|
for image_name, df in all_dfs.items(): |
|
|
df_copy = df.copy() |
|
|
df_copy['image'] = image_name |
|
|
combined_data.append(df_copy) |
|
|
|
|
|
combined_df = pd.concat(combined_data, ignore_index=True) |
|
|
|
|
|
|
|
|
ax = axes[0,0] |
|
|
for image in TARGET_IMAGES: |
|
|
image_data = combined_df[combined_df['image'] == image] |
|
|
min_size_effect = image_data.groupby('min_size')['SSIM'].mean() |
|
|
ax.plot(min_size_effect.index, min_size_effect.values, marker='o', label=image, linewidth=2) |
|
|
|
|
|
ax.set_title('Min Size Effect on SSIM') |
|
|
ax.set_xlabel('Min Size') |
|
|
ax.set_ylabel('Average SSIM') |
|
|
ax.legend() |
|
|
ax.grid(True, alpha=0.3) |
|
|
|
|
|
|
|
|
ax = axes[0,1] |
|
|
for image in TARGET_IMAGES: |
|
|
image_data = combined_df[combined_df['image'] == image] |
|
|
max_size_effect = image_data.groupby('max_size')['SSIM'].mean() |
|
|
ax.plot(max_size_effect.index, max_size_effect.values, marker='s', label=image, linewidth=2) |
|
|
|
|
|
ax.set_title('Max Size Effect on SSIM') |
|
|
ax.set_xlabel('Max Size') |
|
|
ax.set_ylabel('Average SSIM') |
|
|
ax.legend() |
|
|
ax.grid(True, alpha=0.3) |
|
|
|
|
|
|
|
|
combined_df['size_ratio'] = combined_df['max_size'] / combined_df['min_size'] |
|
|
|
|
|
ax = axes[1,0] |
|
|
for image in TARGET_IMAGES: |
|
|
image_data = combined_df[combined_df['image'] == image] |
|
|
ratio_effect = image_data.groupby('size_ratio')['Overall_Quality'].mean() |
|
|
ax.plot(ratio_effect.index, ratio_effect.values, marker='^', label=image, linewidth=2) |
|
|
|
|
|
ax.set_title('Size Ratio Effect on Overall Quality') |
|
|
ax.set_xlabel('Size Ratio (Max/Min)') |
|
|
ax.set_ylabel('Average Overall Quality') |
|
|
ax.legend() |
|
|
ax.grid(True, alpha=0.3) |
|
|
|
|
|
|
|
|
ax = axes[1,1] |
|
|
|
|
|
|
|
|
consistency_analysis = {} |
|
|
|
|
|
for size_param in ['min_size', 'max_size']: |
|
|
param_effects = {} |
|
|
for image in TARGET_IMAGES: |
|
|
image_data = combined_df[combined_df['image'] == image] |
|
|
effect = image_data.groupby(size_param)['SSIM'].mean() |
|
|
param_effects[image] = effect |
|
|
|
|
|
|
|
|
correlations = [] |
|
|
images = list(param_effects.keys()) |
|
|
for i in range(len(images)): |
|
|
for j in range(i+1, len(images)): |
|
|
|
|
|
common_params = set(param_effects[images[i]].index).intersection( |
|
|
set(param_effects[images[j]].index) |
|
|
) |
|
|
if len(common_params) > 1: |
|
|
vals_i = [param_effects[images[i]][p] for p in common_params] |
|
|
vals_j = [param_effects[images[j]][p] for p in common_params] |
|
|
corr = np.corrcoef(vals_i, vals_j)[0,1] |
|
|
correlations.append(corr) |
|
|
|
|
|
consistency_analysis[size_param] = np.mean(correlations) if correlations else 0 |
|
|
|
|
|
|
|
|
params = list(consistency_analysis.keys()) |
|
|
correlations = list(consistency_analysis.values()) |
|
|
|
|
|
ax.bar(params, correlations, color=['skyblue', 'lightgreen']) |
|
|
ax.set_title('Parameter Consistency Across Images') |
|
|
ax.set_xlabel('Size Parameters') |
|
|
ax.set_ylabel('Average Correlation') |
|
|
ax.set_ylim(0, 1) |
|
|
ax.grid(True, alpha=0.3) |
|
|
|
|
|
|
|
|
for i, (param, corr) in enumerate(zip(params, correlations)): |
|
|
ax.text(i, corr + 0.02, f'{corr:.3f}', ha='center', va='bottom') |
|
|
|
|
|
plt.tight_layout() |
|
|
output_path = OUTPUT_DIR / 'size_consistency_analysis.png' |
|
|
plt.savefig(output_path, dpi=300, bbox_inches='tight') |
|
|
plt.close() |
|
|
print(f"[INFO] Saved size consistency analysis to {output_path}") |
|
|
|
|
|
|
|
|
def main(): |
|
|
"""Main analysis function""" |
|
|
print("=" * 60) |
|
|
print("MOSAIC PARAMETER BEHAVIOR ANALYSIS") |
|
|
print("=" * 60) |
|
|
|
|
|
setup_directories() |
|
|
|
|
|
|
|
|
all_dfs = load_metrics_data() |
|
|
|
|
|
if not all_dfs: |
|
|
print("[ERROR] No data loaded. Check metrics directory.") |
|
|
return |
|
|
|
|
|
|
|
|
for image_name, df in all_dfs.items(): |
|
|
print(f"\n[INFO] Analyzing {image_name}...") |
|
|
|
|
|
|
|
|
create_heatmaps(df, image_name) |
|
|
create_parameter_impact(df, image_name) |
|
|
|
|
|
|
|
|
analyze_parameter_degradation(df, image_name) |
|
|
analyze_cifar_comparison(df, image_name) |
|
|
|
|
|
|
|
|
analyze_size_consistency(all_dfs) |
|
|
|
|
|
print("\n" + "=" * 60) |
|
|
print("ANALYSIS COMPLETE!") |
|
|
print("=" * 60) |
|
|
print(f"Results saved to: {OUTPUT_DIR}") |
|
|
print("\nGenerated analyses:") |
|
|
print("• heatmaps.png - Parameter impact heatmaps") |
|
|
print("• parameter_impact.png - Parameter effect analysis") |
|
|
print("• parameter_degradation.png - Settings for artistic effects") |
|
|
print("• cifar_comparison.png - CIFAR-10 vs CIFAR-100 comparison") |
|
|
print("• size_consistency_analysis.png - Cross-image size effect consistency") |
|
|
|
|
|
if __name__ == "__main__": |
|
|
main() |