DHEIVER commited on
Commit
ec914f9
·
verified ·
1 Parent(s): 0f757cc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +64 -144
app.py CHANGED
@@ -1,120 +1,72 @@
1
  import gradio as gr
2
  import torch
 
3
  import pandas as pd
4
- import numpy as np
5
  from PIL import Image
6
- import re
7
 
8
- # Base de dados nutricional expandida com variações e sinônimos
9
- FOOD_ALIASES = {
10
- "arroz": ["arroz branco", "arroz integral", "arroz cozido", "arroz solto"],
11
- "feijão": ["feijão preto", "feijão carioca", "feijão vermelho", "feijões"],
12
- "frango": ["frango grelhado", "peito de frango", "filé de frango", "frango assado", "chicken"],
13
- "salada": ["alface", "tomate", "verduras", "legumes", "vegetais", "salada verde"],
14
- "batata": ["batata cozida", "batata assada", "purê de batata", "potato"],
15
- "carne": ["carne vermelha", "bife", "filé", "carne assada", "beef"],
16
- "peixe": ["filé de peixe", "peixe grelhado", "peixe assado", "fish"],
17
- "macarrão": ["espaguete", "massa", "pasta", "macarrão integral", "noodles"],
18
- "ovo": ["ovo frito", "ovo cozido", "ovos", "omelete", "eggs"]
19
- }
20
 
 
21
  NUTRITION_DB = {
22
  "arroz": {"calorias": 130, "proteinas": 2.7, "carboidratos": 28, "gorduras": 0.3},
23
  "feijão": {"calorias": 77, "proteinas": 5.2, "carboidratos": 13.6, "gorduras": 0.5},
24
- "frango": {"calorias": 165, "proteinas": 31, "carboidratos": 0, "gorduras": 3.6},
25
- "salada": {"calorias": 15, "proteinas": 1.4, "carboidratos": 2.9, "gorduras": 0.2},
26
- "batata": {"calorias": 93, "proteinas": 2.5, "carboidratos": 21, "gorduras": 0.1},
27
  "carne": {"calorias": 250, "proteinas": 26, "carboidratos": 0, "gorduras": 17},
28
- "peixe": {"calorias": 206, "proteinas": 22, "carboidratos": 0, "gorduras": 12},
29
- "macarrão": {"calorias": 158, "proteinas": 5.8, "carboidratos": 31, "gorduras": 1.2},
30
- "ovo": {"calorias": 155, "proteinas": 13, "carboidratos": 1.1, "gorduras": 11},
31
  }
32
 
33
- def identify_foods(description):
34
- """
35
- Identifica alimentos na descrição usando múltiplas verificações
36
- """
37
- found_foods = {}
38
- description = description.lower()
39
-
40
- # Primeira verificação: busca direta
41
- for base_food in NUTRITION_DB.keys():
42
- if base_food in description:
43
- found_foods[base_food] = {
44
- "confianca": "Alta",
45
- "mencoes": description.count(base_food),
46
- "variacao": base_food
47
- }
48
-
49
- # Segunda verificação: sinônimos e variações
50
- for base_food, aliases in FOOD_ALIASES.items():
51
- if base_food not in found_foods: # Só verifica se ainda não encontrou
52
- for alias in aliases:
53
- if alias in description:
54
- found_foods[base_food] = {
55
- "confianca": "Média",
56
- "mencoes": description.count(alias),
57
- "variacao": alias
58
- }
59
-
60
- # Terceira verificação: análise de contexto
61
- context_clues = {
62
- "prato": 0.1,
63
- "refeição": 0.1,
64
- "porção": 0.1,
65
- "servido": 0.1,
66
- "preparado": 0.1
67
  }
68
 
69
- for food in found_foods:
70
- confidence_boost = 0
71
- for clue, value in context_clues.items():
72
- if clue in description:
73
- confidence_boost += value
74
-
75
- if confidence_boost > 0:
76
- found_foods[food]["confianca"] = "Alta" if confidence_boost > 0.2 else found_foods[food]["confianca"]
77
 
78
- # Quarta verificação: validação de preparação
79
- cooking_methods = ["cozido", "assado", "grelhado", "frito", "cru"]
80
- for food in found_foods:
81
- for method in cooking_methods:
82
- if method in description:
83
- found_foods[food]["preparo"] = method
84
 
85
- return found_foods
86
 
87
- def analyze_foods(description):
88
- """Analisa a descrição e retorna informações nutricionais"""
89
  try:
90
- # Identificação detalhada dos alimentos
91
- identified_foods = identify_foods(description)
92
-
93
- if not identified_foods:
94
- return "Nenhum alimento conhecido identificado com confiança.", None, None
95
 
96
- # Calcula nutrientes
97
- total_nutrients = {
98
- "calorias": 0,
99
- "proteinas": 0,
100
- "carboidratos": 0,
101
- "gorduras": 0
102
- }
103
-
104
- # Lista detalhada de alimentos identificados
105
- foods_detail = []
106
- for food, info in identified_foods.items():
107
- foods_detail.append(f"• {food.capitalize()}")
108
- foods_detail.append(f" - Confiança: {info['confianca']}")
109
- foods_detail.append(f" - Menções: {info['mencoes']}")
110
- foods_detail.append(f" - Variação encontrada: {info['variacao']}")
111
- if 'preparo' in info:
112
- foods_detail.append(f" - Método de preparo: {info['preparo']}")
113
- foods_detail.append("") # Linha em branco para separar
114
-
115
- # Soma nutrientes
116
- for nutrient, value in NUTRITION_DB[food].items():
117
- total_nutrients[nutrient] += value
118
 
119
  # Prepara dados para visualização
120
  table_data = [
@@ -134,91 +86,59 @@ def analyze_foods(description):
134
  ]
135
  })
136
 
137
- analysis = f"""### 🍽️ Descrição do Modelo:
 
138
  {description}
139
 
140
- ### 🔍 Alimentos Identificados:
141
- {chr(10).join(foods_detail)}
142
 
143
- ### 📊 Análise Nutricional:
144
- • Calorias Totais: {total_nutrients['calorias']:.1f} kcal
145
  • Proteínas: {total_nutrients['proteinas']:.1f}g
146
  • Carboidratos: {total_nutrients['carboidratos']:.1f}g
147
  • Gorduras: {total_nutrients['gorduras']:.1f}g
148
 
149
- ### 💡 Avaliação:
150
- {" Refeição balanceada!" if total_nutrients['proteinas'] > 15 else "⚠️ Considere adicionar mais proteínas"}
151
- {" Carboidratos adequados" if total_nutrients['carboidratos'] < 60 else "⚠️ Alto teor de carboidratos"}
152
- {" Gorduras em nível adequado" if total_nutrients['gorduras'] < 20 else "⚠️ Alto teor de gorduras"}
153
  """
154
 
155
  return analysis, table_data, plot_data
156
 
157
- except Exception as e:
158
- raise gr.Error(f"Erro na análise: {str(e)}")
159
-
160
- def analyze_image(image):
161
- """Função principal que coordena o processo de análise"""
162
- try:
163
- # Simula a resposta do modelo (temporário até resolvermos o erro do DeepSeek)
164
- description = "Na imagem é possível ver um prato contendo arroz branco cozido, feijão preto, um pedaço de frango grelhado servido com salada de alface e tomate. O prato parece uma refeição completa preparada recentemente."
165
-
166
- # Analisa os alimentos
167
- analysis, table_data, plot_data = analyze_foods(description)
168
-
169
- return analysis, table_data, plot_data
170
-
171
  except Exception as e:
172
  return str(e), None, None
173
 
174
  # Interface Gradio
175
  with gr.Blocks(theme=gr.themes.Soft()) as iface:
176
- gr.Markdown("""
177
- # 🍽️ Análise Nutricional com IA
178
- Faça upload de uma foto do seu prato para análise nutricional detalhada.
179
- """)
180
 
181
  with gr.Row():
182
- # Coluna de Input
183
  with gr.Column():
184
  image_input = gr.Image(
185
  type="pil",
186
  label="Foto do Prato",
187
  sources=["upload", "webcam"]
188
  )
189
- analyze_btn = gr.Button("📊 Analisar", variant="primary", size="lg")
190
-
191
- with gr.Accordion("📝 Dicas", open=False):
192
- gr.Markdown("""
193
- - Use fotos bem iluminadas
194
- - Fotografe de cima para baixo
195
- - Certifique-se que todos os alimentos estão visíveis
196
- - Evite sombras ou reflexos fortes
197
- """)
198
 
199
- # Coluna de Output
200
  with gr.Column():
201
- # Análise textual
202
  output_text = gr.Markdown()
203
 
204
  with gr.Row():
205
- # Tabela nutricional
206
  output_table = gr.Dataframe(
207
  headers=["Nutriente", "Quantidade"],
208
- label="Informação Nutricional",
209
- wrap=True
210
  )
211
 
212
- # Gráfico
213
  output_plot = gr.BarPlot(
214
  x="Nutriente",
215
  y="Quantidade",
216
  title="Macronutrientes (g)",
217
- height=300,
218
- tooltip=["Nutriente", "Quantidade"]
219
  )
220
 
221
- # Eventos
222
  analyze_btn.click(
223
  fn=analyze_image,
224
  inputs=[image_input],
 
1
  import gradio as gr
2
  import torch
3
+ from transformers import AutoModel, AutoProcessor
4
  import pandas as pd
 
5
  from PIL import Image
 
6
 
7
+ # Carrega o modelo
8
+ model = AutoModel.from_pretrained("openbmb/MiniCPM-o-2_6", trust_remote_code=True)
9
+ processor = AutoProcessor.from_pretrained("openbmb/MiniCPM-o-2_6", trust_remote_code=True)
 
 
 
 
 
 
 
 
 
10
 
11
+ # Base de dados nutricional
12
  NUTRITION_DB = {
13
  "arroz": {"calorias": 130, "proteinas": 2.7, "carboidratos": 28, "gorduras": 0.3},
14
  "feijão": {"calorias": 77, "proteinas": 5.2, "carboidratos": 13.6, "gorduras": 0.5},
 
 
 
15
  "carne": {"calorias": 250, "proteinas": 26, "carboidratos": 0, "gorduras": 17},
16
+ "batata frita": {"calorias": 312, "proteinas": 3.4, "carboidratos": 41, "gorduras": 15},
17
+ "salada": {"calorias": 15, "proteinas": 1.4, "carboidratos": 2.9, "gorduras": 0.2}
 
18
  }
19
 
20
+ def process_image(image, progress=gr.Progress()):
21
+ """Processa a imagem usando o modelo MiniCPM"""
22
+ try:
23
+ progress(0.3, desc="Processando imagem...")
24
+
25
+ # Prepara a imagem
26
+ if isinstance(image, str):
27
+ image = Image.open(image)
28
+
29
+ # Processa a imagem com o modelo
30
+ inputs = processor(images=image, text="What foods are in this image?", return_tensors="pt")
31
+
32
+ progress(0.6, desc="Analisando conteúdo...")
33
+ # Gera a descrição
34
+ outputs = model.generate(**inputs, max_length=100)
35
+ description = processor.decode(outputs[0], skip_special_tokens=True)
36
+
37
+ progress(1.0, desc="Concluído!")
38
+ return description
39
+
40
+ except Exception as e:
41
+ raise gr.Error(f"Erro no processamento: {str(e)}")
42
+
43
+ def analyze_nutrition(foods_list):
44
+ """Analisa nutrientes dos alimentos identificados"""
45
+ total_nutrients = {
46
+ "calorias": 0,
47
+ "proteinas": 0,
48
+ "carboidratos": 0,
49
+ "gorduras": 0
 
 
 
 
50
  }
51
 
52
+ found_foods = []
 
 
 
 
 
 
 
53
 
54
+ for food in NUTRITION_DB.keys():
55
+ if food.lower() in foods_list.lower():
56
+ found_foods.append(food)
57
+ for nutrient, value in NUTRITION_DB[food].items():
58
+ total_nutrients[nutrient] += value
 
59
 
60
+ return total_nutrients, found_foods
61
 
62
+ def analyze_image(image):
63
+ """Função principal de análise"""
64
  try:
65
+ # Processa a imagem
66
+ description = process_image(image)
 
 
 
67
 
68
+ # Analisa nutrientes
69
+ total_nutrients, found_foods = analyze_nutrition(description)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
  # Prepara dados para visualização
72
  table_data = [
 
86
  ]
87
  })
88
 
89
+ # Monta o relatório
90
+ analysis = f"""### 🔍 Análise da Imagem:
91
  {description}
92
 
93
+ ### 🍽️ Alimentos Identificados:
94
+ {', '.join(found_foods)}
95
 
96
+ ### 📊 Informação Nutricional:
97
+ • Calorias: {total_nutrients['calorias']:.1f} kcal
98
  • Proteínas: {total_nutrients['proteinas']:.1f}g
99
  • Carboidratos: {total_nutrients['carboidratos']:.1f}g
100
  • Gorduras: {total_nutrients['gorduras']:.1f}g
101
 
102
+ ### 💡 Recomendações:
103
+ {"⚠️ Alto teor calórico" if total_nutrients['calorias'] > 800 else " Calorias adequadas"}
104
+ {"⚠️ Considere reduzir carboidratos" if total_nutrients['carboidratos'] > 60 else " Carboidratos adequados"}
105
+ {"⚠️ Alto teor de gorduras" if total_nutrients['gorduras'] > 20 else " Gorduras adequadas"}
106
  """
107
 
108
  return analysis, table_data, plot_data
109
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  except Exception as e:
111
  return str(e), None, None
112
 
113
  # Interface Gradio
114
  with gr.Blocks(theme=gr.themes.Soft()) as iface:
115
+ gr.Markdown("# 🍽️ Análise Nutricional com IA")
 
 
 
116
 
117
  with gr.Row():
 
118
  with gr.Column():
119
  image_input = gr.Image(
120
  type="pil",
121
  label="Foto do Prato",
122
  sources=["upload", "webcam"]
123
  )
124
+ analyze_btn = gr.Button("📊 Analisar", variant="primary")
 
 
 
 
 
 
 
 
125
 
 
126
  with gr.Column():
 
127
  output_text = gr.Markdown()
128
 
129
  with gr.Row():
 
130
  output_table = gr.Dataframe(
131
  headers=["Nutriente", "Quantidade"],
132
+ label="Informação Nutricional"
 
133
  )
134
 
 
135
  output_plot = gr.BarPlot(
136
  x="Nutriente",
137
  y="Quantidade",
138
  title="Macronutrientes (g)",
139
+ height=300
 
140
  )
141
 
 
142
  analyze_btn.click(
143
  fn=analyze_image,
144
  inputs=[image_input],