import gradio as gr import cv2 import numpy as np from PIL import Image IMG_SIZE = 256 REFERENCE_PATH = "reference_bottle.npy" THRESHOLD_SCORE = 400 reference = np.load(REFERENCE_PATH) def detect_classical(input_image): if input_image is None: return "

Veuillez importer une image.

", None, None, None img_rgb = np.array(input_image.convert("RGB")) img_rgb = cv2.resize(img_rgb, (IMG_SIZE, IMG_SIZE)) gray = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2GRAY) diff = cv2.absdiff(gray, reference) diff_blur = cv2.GaussianBlur(diff, (5, 5), 0) _, mask = cv2.threshold(diff_blur, 35, 255, cv2.THRESH_BINARY) kernel = np.ones((5, 5), np.uint8) mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel) mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel) anomaly_score = int(np.sum(mask > 0)) if anomaly_score > THRESHOLD_SCORE: prediction = "DÉFECTUEUSE" color = "#c0392b" emoji = "❌" else: prediction = "BONNE" color = "#27ae60" emoji = "✅" result_html = f"""

{emoji} Prédiction : {prediction}

Score d'anomalie : {anomaly_score}

Seuil utilisé : {THRESHOLD_SCORE}

""" return result_html, img_rgb, diff, mask custom_css = """ .gradio-container { max-width: 1250px !important; margin: auto !important; } h1 { font-size: 26px !important; margin-bottom: 5px !important; } .compact-text { font-size: 14px !important; margin-bottom: 5px !important; } footer { display: none !important; } """ example_paths = [ "examples/good_141.png", "examples/good_093.png", "examples/good_146.png", "examples/defect_017bd.png", "examples/defect_004sd.png", "examples/defect_010c.png", "examples/defect_016sd.png", ] def load_gallery_example(evt: gr.SelectData): image_path = example_paths[evt.index] image = Image.open(image_path).convert("RGB") result_html, original, diff, mask = detect_classical(image) return image, result_html, original, diff, mask with gr.Blocks( title="Détection de défauts - Méthode classique", css=custom_css ) as demo: gr.Markdown( """ # Détection de défauts sur bouteilles - Méthode classique

Comparaison avec une image de référence + score d'anomalie. Importer une image ou cliquer sur un exemple.

""" ) with gr.Row(): with gr.Column(scale=1): input_image = gr.Image( type="pil", label="Image à analyser", height=260 ) button = gr.Button("Analyser l'image", variant="primary") with gr.Column(scale=1): result_output = gr.HTML(label="Résultat") with gr.Row(): original_output = gr.Image(label="Image analysée", height=160) diff_output = gr.Image(label="Différence", height=160) mask_output = gr.Image(label="Masque", height=160) gr.Markdown("### Exemples de test") gallery = gr.Gallery( value=example_paths, label="Cliquer sur une image pour la tester", columns=7, height=140, object_fit="contain", allow_preview=False ) button.click( fn=detect_classical, inputs=input_image, outputs=[ result_output, original_output, diff_output, mask_output ] ) gallery.select( fn=load_gallery_example, inputs=None, outputs=[ input_image, result_output, original_output, diff_output, mask_output ] ) demo.launch()