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()