Spaces:
Sleeping
Sleeping
# app.py - Enhanced with Text Quality Assessment | |
import gradio as gr | |
from core import IQA, TextAwareIQA | |
import numpy as np | |
# Initialize both simple and advanced models | |
simple_metric = IQA("qualiclip+") | |
advanced_metric = TextAwareIQA("qualiclip+", text_weight=0.3) | |
def simple_assessment(image): | |
"""Original simple interface - backward compatible""" | |
score = simple_metric(image) | |
print(f"Simple score: {score}") # Debug output | |
return f"Quality Score: {score:.2f}/100" if score is not None else "Error: Invalid image" | |
def detailed_assessment(image, text_penalty_mode="balanced"): | |
"""Enhanced assessment with detailed breakdown""" | |
try: | |
# Get detailed analysis | |
details = advanced_metric.evaluate(image, text_penalty_mode=text_penalty_mode) | |
if details is None or 'error' in details: | |
return "Error: Could not analyze image", "", "" | |
# Format main result | |
main_result = f"**Combined Quality Score: {details['combined_score']:.2f}/100**" | |
# Format breakdown | |
breakdown = f""" | |
## Score Breakdown: | |
- **Traditional IQA ({details['model_used']}): {details['traditional_score']:.2f}/100** | |
- **Text Quality: {details['text_analysis']['text_quality_score']:.2f}/100** | |
- **Text Weight in Final Score: {details['text_weight']*100:.0f}%** | |
- **Penalty Mode: {details.get('penalty_mode', 'balanced')}** | |
""" | |
# Format text analysis details | |
text_analysis = details['text_analysis'] | |
if text_analysis['text_detected']: | |
text_details = f""" | |
## Text Analysis: | |
- **Text Regions Detected: {text_analysis['text_regions']}** | |
- **Low Quality Text Regions: {text_analysis['low_quality_regions']}** | |
- **Average OCR Confidence: {text_analysis['avg_confidence']:.3f}** | |
- **Assessment: {text_analysis['details']}** | |
### Text Quality Interpretation: | |
- **90-100**: Excellent text clarity, no distortions | |
- **70-89**: Good text quality, minor artifacts | |
- **50-69**: Readable but noticeable distortions | |
- **30-49**: Poor text quality, significant distortions | |
- **0-29**: Severely distorted or unreadable text | |
""" | |
else: | |
text_details = """ | |
## Text Analysis: | |
- **No text detected in image** | |
- **Using traditional IQA score only** | |
""" | |
return main_result, breakdown, text_details | |
except Exception as e: | |
error_msg = f"Error: {str(e)}" | |
return error_msg, "", "" | |
def batch_comparison(image): | |
"""Compare different penalty modes side by side""" | |
try: | |
modes = ['lenient', 'balanced', 'strict'] | |
results = [] | |
for mode in modes: | |
details = advanced_metric.evaluate(image, text_penalty_mode=mode) | |
if details and 'error' not in details: | |
results.append({ | |
'mode': mode.title(), | |
'score': details['combined_score'], | |
'traditional': details['traditional_score'], | |
'text': details['text_analysis']['text_quality_score'], | |
'text_detected': details['text_analysis']['text_detected'] | |
}) | |
if not results: | |
return "Error: Could not analyze image" | |
# Format comparison | |
comparison = "## Penalty Mode Comparison:\n\n" | |
for result in results: | |
comparison += f"**{result['mode']} Mode:**\n" | |
comparison += f"- Combined Score: {result['score']:.2f}/100\n" | |
comparison += f"- Traditional IQA: {result['traditional']:.2f}/100\n" | |
comparison += f"- Text Quality: {result['text']:.2f}/100\n\n" | |
if results[0]['text_detected']: | |
comparison += """ | |
### Mode Explanations: | |
- **Lenient**: Minimal penalty for text issues (10% weight) | |
- **Balanced**: Moderate penalty for text issues (30% weight) | |
- **Strict**: Heavy penalty for text issues (50% weight) | |
""" | |
else: | |
comparison += "\n*No text detected - all modes return same score*" | |
return comparison | |
except Exception as e: | |
return f"Error in batch comparison: {str(e)}" | |
# Create Gradio interface with tabs | |
with gr.Blocks(title="Enhanced Image Quality Assessment", theme=gr.themes.Soft()) as demo: | |
gr.Markdown(""" | |
# π Enhanced Image Quality Assessment | |
This tool evaluates image quality using both traditional perceptual metrics **AND** text-specific quality assessment. | |
Perfect for detecting letter distortions in AI-generated images that traditional IQA tools miss. | |
""") | |
with gr.Tabs(): | |
# Simple tab - backward compatible | |
with gr.TabItem("π Quick Assessment"): | |
gr.Markdown("### Simple quality score (backward compatible with your original setup)") | |
with gr.Row(): | |
with gr.Column(): | |
input_image_simple = gr.Image( | |
label="Upload Image", | |
type="pil", | |
format="png" | |
) | |
assess_btn_simple = gr.Button("Assess Quality", variant="primary") | |
with gr.Column(): | |
output_simple = gr.Textbox( | |
label="Quality Score", | |
lines=2 | |
) | |
assess_btn_simple.click( | |
simple_assessment, | |
inputs=input_image_simple, | |
outputs=output_simple | |
) | |
# Detailed tab - new enhanced features | |
with gr.TabItem("π¬ Detailed Analysis"): | |
gr.Markdown("### Comprehensive quality assessment with text-specific evaluation") | |
with gr.Row(): | |
with gr.Column(): | |
input_image_detailed = gr.Image( | |
label="Upload Image", | |
type="pil", | |
format="png" | |
) | |
penalty_mode = gr.Radio( | |
choices=["lenient", "balanced", "strict"], | |
value="balanced", | |
label="Text Penalty Mode", | |
info="How harshly to penalize text quality issues" | |
) | |
assess_btn_detailed = gr.Button("Detailed Analysis", variant="primary") | |
with gr.Column(): | |
output_main = gr.Markdown(label="Final Score") | |
output_breakdown = gr.Markdown(label="Score Breakdown") | |
output_text_details = gr.Markdown(label="Text Analysis") | |
assess_btn_detailed.click( | |
detailed_assessment, | |
inputs=[input_image_detailed, penalty_mode], | |
outputs=[output_main, output_breakdown, output_text_details] | |
) | |
# Comparison tab | |
with gr.TabItem("βοΈ Mode Comparison"): | |
gr.Markdown("### Compare how different penalty modes affect the final score") | |
with gr.Row(): | |
with gr.Column(): | |
input_image_comparison = gr.Image( | |
label="Upload Image", | |
type="pil", | |
format="png" | |
) | |
compare_btn = gr.Button("Compare All Modes", variant="primary") | |
with gr.Column(): | |
output_comparison = gr.Markdown(label="Comparison Results") | |
compare_btn.click( | |
batch_comparison, | |
inputs=input_image_comparison, | |
outputs=output_comparison | |
) | |
gr.Markdown(""" | |
--- | |
### π‘ How It Works: | |
- **Traditional IQA**: Uses qalign (or your chosen model) for overall perceptual quality | |
- **Text Quality**: Uses OCR confidence scores to detect letter distortions and rendering issues | |
- **Combined Score**: Weighted combination that penalizes text quality problems | |
### π― Perfect For: | |
- Detecting letter distortions in AI-generated images | |
- Evaluating text rendering quality in synthetic images | |
- Getting more accurate quality assessments for images containing text | |
### βοΈ Penalty Modes: | |
- **Lenient**: Light penalty for text issues (good for artistic images) | |
- **Balanced**: Moderate penalty (recommended for most use cases) | |
- **Strict**: Heavy penalty for any text problems (best for document quality) | |
""") | |
if __name__ == "__main__": | |
demo.launch(share=True) |