File size: 8,584 Bytes
a1eba61
d191682
a1eba61
 
d191682
a1eba61
 
 
d191682
a1eba61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# 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)