GiGi2k5 commited on
Commit
459e6b2
·
1 Parent(s): 49b505c

Add application file

Browse files
Files changed (3) hide show
  1. app.py +93 -0
  2. knn.pkl +3 -0
  3. requirements.txt +5 -0
app.py ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import numpy as np
3
+ import tensorflow as tf
4
+ import cv2
5
+ import joblib
6
+ import os
7
+ os.environ["TF_ENABLE_ONEDNN_OPTS"] = "0"
8
+
9
+
10
+ # Charger le modèle de segmentation
11
+ segmentation_model = tf.keras.models.load_model('unet_optimized.keras',
12
+ custom_objects={"dice_coefficient": lambda y_true, y_pred: y_pred})
13
+
14
+ # Charger le modèle de classification
15
+ classification_model = joblib.load('knn.pkl')
16
+
17
+ # Classes pour le diagnostic
18
+ categories = ['Apple___Apple_scab', 'Apple___Black_rot', 'Apple___Cedar_apple_rust', 'Apple___healthy']
19
+
20
+ def segment_image(image):
21
+ # Redimensionner et normaliser l'image
22
+ resized_image = cv2.resize(image, (256, 256)) / 255.0
23
+ input_image = np.expand_dims(resized_image, axis=0)
24
+
25
+ # Prédire le masque
26
+ mask = segmentation_model.predict(input_image)[0]
27
+
28
+ # Debugging : Visualiser les statistiques du masque
29
+ print("Raw mask - Min:", np.min(mask), "Max:", np.max(mask), "Mean:", np.mean(mask))
30
+
31
+ # Si nécessaire, normaliser le masque
32
+ if np.max(mask) > 1.0: # Si les valeurs sont hors de l'échelle attendue
33
+ mask = mask / np.max(mask)
34
+
35
+ # Seuillage pour obtenir une image binaire
36
+ mask = (mask.squeeze() > 0.1).astype(np.uint8)
37
+
38
+ # Debugging : Sauvegarder le masque binaire
39
+ cv2.imwrite("binary_mask.png", mask * 255)
40
+
41
+ # Redimensionner le masque à la taille originale
42
+ original_size = (image.shape[1], image.shape[0])
43
+ mask_resized = cv2.resize(mask, original_size, interpolation=cv2.INTER_NEAREST)
44
+
45
+ return mask_resized
46
+
47
+
48
+
49
+ # Fonction de classification
50
+ def classify_image(image):
51
+ # Extraire les caractéristiques pour la classification
52
+ gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
53
+ hist = cv2.calcHist([gray], [0], None, [256], [0, 256]).flatten()
54
+
55
+ # Prédire la classe
56
+ prediction = classification_model.predict([hist])
57
+ return prediction[0]
58
+
59
+ # Fonction principale pour Gradio
60
+ def process_image(image):
61
+ # Convertir l'image de PIL à NumPy
62
+ image = np.array(image)
63
+
64
+ # Segmentation
65
+ mask = segment_image(image)
66
+
67
+ # Classification
68
+ diagnosis = classify_image(image)
69
+
70
+ # Convertir le masque en image couleur pour l'affichage
71
+ mask_colored = cv2.cvtColor(mask * 255, cv2.COLOR_GRAY2BGR)
72
+
73
+ return mask_colored, diagnosis
74
+
75
+ # Interface Gradio
76
+ interface = gr.Interface(
77
+ fn=process_image,
78
+ inputs=gr.Image(label="Chargez une image de feuille", type="pil"),
79
+ outputs=[
80
+ gr.Image(label="Masque de segmentation"),
81
+ gr.Label(label="Diagnostic")
82
+ ],
83
+ title="SafeLeaf",
84
+ description=(
85
+ "Cette application est une application de détection des maladies des feuilles de pommiers, elle utilise deux modèles : "
86
+ "1. Un modèle de segmentation pour détecter la zone de la feuille malade. "
87
+ "2. Un modèle de classification pour diagnostiquer la maladie de la feuille. "
88
+ "Chargez une image pour commencer."
89
+ ),
90
+ )
91
+
92
+ # Lancer l'application
93
+ interface.launch()
knn.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:033341bdab487fb69f9e546b452a930ad6c67baae738ab6d665d77bec8529e53
3
+ size 2618340
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ gradio==3.42.0
2
+ numpy==1.23.5
3
+ tensorflow==2.14.0
4
+ opencv-python==4.8.1.78
5
+ joblib==1.3.2