File size: 2,832 Bytes
2daee64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import gradio as gr
import cv2
import numpy as np

def calculate_sharpness(image):
    """
    Calculate the sharpness of an image using the Laplacian variance method.
    Higher variance = sharper edges = clearer image.
    """
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    # Calculate the variance of the Laplacian (standard measure for blurriness)
    score = cv2.Laplacian(gray, cv2.CV_64F).var()
    return score

def process_images(files):
    """
    Takes a list of file paths, finds the sharpest image, and returns it along with metrics.
    """
    if not files:
        raise gr.Error("Please upload at least one image.")

    best_image = None
    best_score = -1
    best_filename = ""
    
    results = []

    for file_path in files:
        # Read image using OpenCV
        # file_path is a temporary path provided by Gradio
        img = cv2.imread(file_path)
        
        if img is None:
            continue

        score = calculate_sharpness(img)
        filename = file_path.split('/')[-1] # Simple extraction of temp filename
        
        # Convert BGR (OpenCV standard) to RGB (Gradio standard) for display
        img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        
        results.append({"filename": filename, "sharpness_score": round(score, 2)})

        if score > best_score:
            best_score = score
            best_image = img_rgb
            best_filename = filename

    # Sort results for the data table
    results.sort(key=lambda x: x["sharpness_score"], reverse=True)
    
    info_text = f"🏆 Best Image: **{best_filename}**\n\n**Score:** {best_score:.2f} (Laplacian Variance)"
    
    return best_image, info_text, results

# --- Gradio UI Implementation ---
with gr.Blocks(title="Best Image Selector") as demo:
    gr.Markdown("# 📸 Smart Image Selector")
    gr.Markdown("Upload multiple photos. The app will analyze them for **clarity (sharpness)** and pick the best one.")

    with gr.Row():
        with gr.Column(scale=1):
            # Input: File uploader accepting multiple files
            file_input = gr.File(
                label="Upload Images", 
                file_count="multiple", 
                file_types=["image"]
            )
            process_btn = gr.Button("Find Best Image", variant="primary")

        with gr.Column(scale=1):
            # Output: Best Image display
            output_image = gr.Image(label="The Sharpest Image", type="numpy")
            output_info = gr.Markdown()
            
    # Output: Data table showing scores for all images
    output_table = gr.JSON(label="Analysis Details")

    # Wire the function
    process_btn.click(
        fn=process_images, 
        inputs=file_input, 
        outputs=[output_image, output_info, output_table]
    )

if __name__ == "__main__":
    demo.launch()