raysarocha commited on
Commit
a826b39
·
verified ·
1 Parent(s): b761593

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +216 -0
app.py ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import tensorflow as tf
3
+ import numpy as np
4
+ from PIL import Image
5
+ import json
6
+ from huggingface_hub import hf_hub_download
7
+
8
+ # ============================================
9
+ # Configurações do modelo
10
+ # ============================================
11
+ REPO_ID = "raysarocha/plant-resnet50-38classes" # Seu repositório
12
+
13
+ # ============================================
14
+ # Carregamento do modelo
15
+ # ============================================
16
+ print("🔄 Carregando modelo...")
17
+
18
+ # Baixa os arquivos
19
+ cfg_path = hf_hub_download(REPO_ID, "config.json")
20
+ model_path = hf_hub_download(REPO_ID, "model.keras")
21
+
22
+ # Carrega configuração
23
+ with open(cfg_path, "r") as f:
24
+ cfg = json.load(f)
25
+
26
+ # Carrega modelo
27
+ model = tf.keras.models.load_model(model_path)
28
+ print("✅ Modelo carregado com sucesso!")
29
+
30
+ # ============================================
31
+ # Dicionário de nomes amigáveis
32
+ # ============================================
33
+ FRIENDLY_NAMES = {
34
+ "Apple___Apple_scab": "🍎 Maçã - Sarna",
35
+ "Apple___Black_rot": "🍎 Maçã - Podridão negra",
36
+ "Apple___Cedar_apple_rust": "🍎 Maçã - Ferrugem do cedro",
37
+ "Apple___healthy": "🍎 Maçã - Saudável",
38
+ "Blueberry___healthy": "🫐 Mirtilo - Saudável",
39
+ "Cherry_(including_sour)___Powdery_mildew": "🍒 Cereja - Oídio",
40
+ "Cherry_(including_sour)___healthy": "🍒 Cereja - Saudável",
41
+ "Corn_(maize)___Cercospora_leaf_spot Gray_leaf_spot": "🌽 Milho - Mancha de Cercospora",
42
+ "Corn_(maize)___Common_rust_": "🌽 Milho - Ferrugem comum",
43
+ "Corn_(maize)___Northern_Leaf_Blight": "🌽 Milho - Queima das folhas",
44
+ "Corn_(maize)___healthy": "🌽 Milho - Saudável",
45
+ "Grape___Black_rot": "🍇 Uva - Podridão negra",
46
+ "Grape___Esca_(Black_Measles)": "🍇 Uva - Esca",
47
+ "Grape___Leaf_blight_(Isariopsis_Leaf_Spot)": "🍇 Uva - Queima das folhas",
48
+ "Grape___healthy": "🍇 Uva - Saudável",
49
+ "Orange___Haunglongbing_(Citrus_greening)": "🍊 Laranja - Greening",
50
+ "Peach___Bacterial_spot": "🍑 Pêssego - Mancha bacteriana",
51
+ "Peach___healthy": "🍑 Pêssego - Saudável",
52
+ "Pepper,_bell___Bacterial_spot": "🫑 Pimentão - Mancha bacteriana",
53
+ "Pepper,_bell___healthy": "🫑 Pimentão - Saudável",
54
+ "Potato___Early_blight": "🥔 Batata - Requeima precoce",
55
+ "Potato___Late_blight": "🥔 Batata - Requeima tardia",
56
+ "Potato___healthy": "🥔 Batata - Saudável",
57
+ "Raspberry___healthy": "🫐 Framboesa - Saudável",
58
+ "Soybean___healthy": "🌱 Soja - Saudável",
59
+ "Squash___Powdery_mildew": "🎃 Abóbora - Oídio",
60
+ "Strawberry___Leaf_scorch": "🍓 Morango - Queima das folhas",
61
+ "Strawberry___healthy": "🍓 Morango - Saudável",
62
+ "Tomato___Bacterial_spot": "🍅 Tomate - Mancha bacteriana",
63
+ "Tomato___Early_blight": "🍅 Tomate - Requeima precoce",
64
+ "Tomato___Late_blight": "🍅 Tomate - Requeima tardia",
65
+ "Tomato___Leaf_Mold": "🍅 Tomate - Mofo das folhas",
66
+ "Tomato___Septoria_leaf_spot": "🍅 Tomate - Mancha de Septoria",
67
+ "Tomato___Spider_mites Two-spotted_spider_mite": "🍅 Tomate - Ácaros",
68
+ "Tomato___Target_Spot": "🍅 Tomate - Mancha alvo",
69
+ "Tomato___Tomato_Yellow_Leaf_Curl_Virus": "🍅 Tomate - Vírus do enrolamento",
70
+ "Tomato___Tomato_mosaic_virus": "🍅 Tomate - Vírus do mosaico",
71
+ "Tomato___healthy": "🍅 Tomate - Saudável"
72
+ }
73
+
74
+ # ============================================
75
+ # Função de classificação
76
+ # ============================================
77
+ def classify_plant(image):
78
+ """
79
+ Classifica a imagem da planta e retorna diagnóstico
80
+ """
81
+ if image is None:
82
+ return None, "Por favor, faça upload de uma imagem!"
83
+
84
+ # Preprocessamento
85
+ img = Image.fromarray(image).convert("RGB")
86
+ img = img.resize((cfg["image_size"], cfg["image_size"]))
87
+ arr = np.array(img).astype("float32") * cfg["rescale"]
88
+ arr = np.expand_dims(arr, axis=0)
89
+
90
+ # Predição
91
+ predictions = model(arr)
92
+ probs = tf.nn.softmax(predictions[0]).numpy()
93
+
94
+ # Top 5 resultados
95
+ top_5_idx = np.argsort(probs)[-5:][::-1]
96
+
97
+ # Formata resultados para o Gradio
98
+ results = {}
99
+ for idx in top_5_idx:
100
+ class_name = cfg["id2label"][str(idx)]
101
+ friendly_name = FRIENDLY_NAMES.get(class_name, class_name)
102
+ confidence = float(probs[idx])
103
+ results[friendly_name] = confidence
104
+
105
+ # Mensagem de diagnóstico
106
+ top_class = cfg["id2label"][str(top_5_idx[0])]
107
+ top_confidence = float(probs[top_5_idx[0]])
108
+
109
+ if "healthy" in top_class.lower():
110
+ status = "✅ Planta Saudável!"
111
+ message = f"Sua planta parece estar saudável! (Confiança: {top_confidence:.1%})"
112
+ color = "green"
113
+ else:
114
+ status = "⚠️ Doença Detectada"
115
+ message = f"Possível problema detectado. (Confiança: {top_confidence:.1%})"
116
+ color = "orange"
117
+
118
+ diagnosis = f"""
119
+ <div style='padding: 20px; border-radius: 10px; background-color: #{color}20; border: 2px solid {color};'>
120
+ <h2 style='color: {color};'>{status}</h2>
121
+ <p style='font-size: 16px;'>{message}</p>
122
+ </div>
123
+ """
124
+
125
+ return results, diagnosis
126
+
127
+ # ============================================
128
+ # Exemplos de imagens
129
+ # ============================================
130
+ examples = [
131
+ ["examples/tomato_healthy.jpg"],
132
+ ["examples/apple_scab.jpg"],
133
+ ["examples/potato_blight.jpg"],
134
+ ] # Adicione exemplos se tiver
135
+
136
+ # ============================================
137
+ # Interface Gradio
138
+ # ============================================
139
+ with gr.Blocks(title="Plant Disease Detector 🌿") as demo:
140
+ gr.Markdown("""
141
+ # 🌿 Detector de Doenças em Plantas
142
+
143
+ ### Como usar:
144
+ 1. **Faça upload** de uma foto da planta
145
+ 2. **Clique em Submit** para analisar
146
+ 3. **Veja o diagnóstico** e as probabilidades
147
+
148
+ **Dica:** Tire fotos das folhas em boa iluminação para melhores resultados!
149
+ """)
150
+
151
+ with gr.Row():
152
+ with gr.Column():
153
+ input_image = gr.Image(
154
+ label="📷 Upload da Imagem",
155
+ type="numpy",
156
+ height=300
157
+ )
158
+ submit_btn = gr.Button(
159
+ "🔍 Analisar Planta",
160
+ variant="primary",
161
+ size="lg"
162
+ )
163
+
164
+ with gr.Column():
165
+ diagnosis_output = gr.HTML(
166
+ label="Diagnóstico",
167
+ value="<div style='padding: 20px; text-align: center; color: gray;'>Aguardando imagem...</div>"
168
+ )
169
+ confidence_output = gr.Label(
170
+ label="📊 Probabilidades (Top 5)",
171
+ num_top_classes=5
172
+ )
173
+
174
+ # Exemplos (se você tiver imagens de exemplo)
175
+ # gr.Examples(
176
+ # examples=examples,
177
+ # inputs=input_image,
178
+ # outputs=[confidence_output, diagnosis_output],
179
+ # fn=classify_plant,
180
+ # )
181
+
182
+ gr.Markdown("""
183
+ ---
184
+ ### 📋 Informações:
185
+ - **Modelo:** ResNet50 treinado com 38 classes
186
+ - **Plantas:** Maçã, Tomate, Batata, Uva, Milho, e mais
187
+ - **Doenças:** Detecta várias doenças comuns em plantas
188
+
189
+ ### 🔗 Links:
190
+ - [Modelo no HuggingFace](https://huggingface.co/raysarocha/plant-resnet50-38classes)
191
+ - [Código no GitHub](#)
192
+ """)
193
+
194
+ # Conecta o botão
195
+ submit_btn.click(
196
+ fn=classify_plant,
197
+ inputs=input_image,
198
+ outputs=[confidence_output, diagnosis_output]
199
+ )
200
+
201
+ # Upload automático
202
+ input_image.change(
203
+ fn=classify_plant,
204
+ inputs=input_image,
205
+ outputs=[confidence_output, diagnosis_output]
206
+ )
207
+
208
+ # ============================================
209
+ # Executa a aplicação
210
+ # ============================================
211
+ if __name__ == "__main__":
212
+ demo.launch(
213
+ server_name="0.0.0.0",
214
+ share=False,
215
+ show_error=True
216
+ )