DHEIVER commited on
Commit
6fdacd7
·
verified ·
1 Parent(s): ec738f9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +130 -90
app.py CHANGED
@@ -8,19 +8,15 @@ import torch
8
 
9
  # Carrega variáveis de ambiente
10
  load_dotenv()
11
-
12
- # Obtém a API key da variável de ambiente
13
  API_KEY = os.getenv('NUTRITION_API_KEY', '')
14
 
15
- # Carrega o modelo BLIP2 para identificação de alimentos
16
  model_name = "Salesforce/blip2-opt-2.7b"
17
  processor = Blip2Processor.from_pretrained(model_name)
18
  model = Blip2ForConditionalGeneration.from_pretrained(model_name, torch_dtype=torch.float16, device_map="auto")
19
 
20
  def identify_foods(image):
21
- """
22
- Usa o modelo BLIP2 para identificar alimentos na imagem
23
- """
24
  prompt = "Liste todos os alimentos visíveis nesta imagem de refeição."
25
  inputs = processor(image, text=prompt, return_tensors="pt").to(model.device)
26
 
@@ -33,21 +29,15 @@ def identify_foods(image):
33
  top_p=0.9,
34
  )
35
 
36
- description = processor.decode(outputs[0], skip_special_tokens=True)
37
- return description
38
 
39
  def analyze_nutrition(image):
40
- """
41
- Função principal que processa a imagem e retorna os resultados formatados
42
- """
43
  try:
44
- if not API_KEY:
45
- raise ValueError("API Key não encontrada nas variáveis de ambiente. Configure NUTRITION_API_KEY no arquivo .env")
46
-
47
- # Identifica os alimentos na imagem
48
  identified_foods = identify_foods(image)
49
-
50
- # Simula resultado da análise (aqui você usaria a API_KEY para fazer a requisição real)
51
  nutrients = {
52
  "calorias": 450,
53
  "proteinas": 25,
@@ -56,13 +46,13 @@ def analyze_nutrition(image):
56
  "fibras": 8
57
  }
58
 
59
- # Prepara dados para o gráfico em formato DataFrame
60
  plot_data = pd.DataFrame({
61
  'Nutriente': ['Proteínas', 'Carboidratos', 'Gorduras'],
62
  'Quantidade': [nutrients['proteinas'], nutrients['carboidratos'], nutrients['gorduras']]
63
  })
64
 
65
- # Prepara tabela nutricional
66
  table_data = [
67
  ["Calorias", f"{nutrients['calorias']:.1f} kcal"],
68
  ["Proteínas", f"{nutrients['proteinas']:.1f}g"],
@@ -71,104 +61,154 @@ def analyze_nutrition(image):
71
  ["Fibras", f"{nutrients['fibras']:.1f}g"]
72
  ]
73
 
74
- # Prepara recomendações
75
- recommendations = []
76
  if nutrients['calorias'] > 800:
77
- recommendations.append("⚠️ Alto valor calórico - considere reduzir as porções")
78
  if nutrients['proteinas'] < 15:
79
- recommendations.append("⚠️ Baixo teor de proteínas - considere adicionar fontes proteicas")
80
  if nutrients['fibras'] < 6:
81
- recommendations.append("⚠️ Baixo teor de fibras - adicione mais vegetais")
82
-
83
- recommendations_text = "\n".join(recommendations) if recommendations else "✅ Valores nutricionais dentro das recomendações!"
84
 
85
- # Formata a descrição dos alimentos identificados
86
- foods_identified = f"🔍 Alimentos Identificados:\n{identified_foods}"
87
 
88
- return {
89
- "message": "Análise concluída com sucesso!",
90
- "nutrients": nutrients,
91
- "foods_identified": foods_identified
92
- }, plot_data, table_data, foods_identified, recommendations_text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
 
94
  except Exception as e:
95
- error_json = {"error": str(e)}
96
- return error_json, None, None, f"Erro na análise: {str(e)}", ""
 
 
 
97
 
98
  # Interface Gradio
99
  with gr.Blocks(theme=gr.themes.Soft()) as iface:
100
- gr.Markdown("""
101
- # 🍽️ Análise Nutricional com IA
102
- Faça upload de uma foto do seu prato para receber uma análise nutricional detalhada.
103
- """)
 
104
 
 
105
  with gr.Row():
106
- with gr.Column(scale=1):
107
- # Inputs
 
108
  image_input = gr.Image(
109
  type="pil",
110
- label="Foto do Prato",
111
- sources=['upload', 'webcam'],
112
- height=300
113
  )
114
- analyze_btn = gr.Button("📊 Analisar", variant="primary")
115
-
116
- with gr.Column(scale=2):
117
- # Outputs
118
- with gr.Tab("Resumo"):
119
- with gr.Row():
120
- foods_detected = gr.Textbox(
121
- label="Alimentos Identificados",
122
- lines=3
123
- )
124
 
125
- with gr.Row():
126
- recommendations = gr.Textbox(
127
- label="Recomendações",
128
- lines=3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  )
130
 
131
- with gr.Row():
132
- nutri_table = gr.Dataframe(
133
- headers=["Nutriente", "Quantidade"],
134
- label="Informação Nutricional"
135
- )
 
 
 
 
 
 
 
 
 
 
 
 
136
 
137
- with gr.Row():
138
- macro_plot = gr.BarPlot(
139
- label="Distribuição de Macronutrientes",
140
- title="Macronutrientes (gramas)",
141
- x="Nutriente",
142
- y="Quantidade",
143
- height=300,
144
- tooltip=["Nutriente", "Quantidade"]
145
- )
146
-
147
- with gr.Tab("Detalhes"):
148
- json_output = gr.JSON()
 
 
 
 
 
 
 
 
149
 
150
- # Eventos
151
  analyze_btn.click(
152
  fn=analyze_nutrition,
153
  inputs=[image_input],
154
- outputs=[json_output, macro_plot, nutri_table, foods_detected, recommendations]
 
 
 
 
 
 
 
155
  )
156
 
157
- gr.Markdown("""
158
- ### 📝 Instruções
159
- 1. Faça upload de uma foto do seu prato ou tire uma foto com a webcam
160
- 2. Clique em "Analisar"
161
- 3. Veja os resultados nas abas "Resumo" e "Detalhes"
162
-
163
- ### 🎯 Dicas para melhores resultados
164
- - Use fotos bem iluminadas
165
- - Fotografe de cima para baixo
166
- - Certifique-se que todos os alimentos estão visíveis
167
- - Evite sombras ou reflexos fortes
168
- """)
169
 
 
170
  if __name__ == "__main__":
171
- # Verifica se a API key está configurada
172
  if not API_KEY:
173
  print("⚠️ Atenção: API Key não encontrada!")
174
  print("Configure a variável de ambiente NUTRITION_API_KEY no arquivo .env")
 
8
 
9
  # Carrega variáveis de ambiente
10
  load_dotenv()
 
 
11
  API_KEY = os.getenv('NUTRITION_API_KEY', '')
12
 
13
+ # Carrega o modelo BLIP2
14
  model_name = "Salesforce/blip2-opt-2.7b"
15
  processor = Blip2Processor.from_pretrained(model_name)
16
  model = Blip2ForConditionalGeneration.from_pretrained(model_name, torch_dtype=torch.float16, device_map="auto")
17
 
18
  def identify_foods(image):
19
+ """Identifica alimentos na imagem usando BLIP2"""
 
 
20
  prompt = "Liste todos os alimentos visíveis nesta imagem de refeição."
21
  inputs = processor(image, text=prompt, return_tensors="pt").to(model.device)
22
 
 
29
  top_p=0.9,
30
  )
31
 
32
+ return processor.decode(outputs[0], skip_special_tokens=True)
 
33
 
34
  def analyze_nutrition(image):
35
+ """Análise nutricional da imagem"""
 
 
36
  try:
37
+ # Identifica alimentos
 
 
 
38
  identified_foods = identify_foods(image)
39
+
40
+ # Simula análise nutricional
41
  nutrients = {
42
  "calorias": 450,
43
  "proteinas": 25,
 
46
  "fibras": 8
47
  }
48
 
49
+ # Dados do gráfico
50
  plot_data = pd.DataFrame({
51
  'Nutriente': ['Proteínas', 'Carboidratos', 'Gorduras'],
52
  'Quantidade': [nutrients['proteinas'], nutrients['carboidratos'], nutrients['gorduras']]
53
  })
54
 
55
+ # Tabela nutricional
56
  table_data = [
57
  ["Calorias", f"{nutrients['calorias']:.1f} kcal"],
58
  ["Proteínas", f"{nutrients['proteinas']:.1f}g"],
 
61
  ["Fibras", f"{nutrients['fibras']:.1f}g"]
62
  ]
63
 
64
+ # Análise e recomendações
65
+ analysis = []
66
  if nutrients['calorias'] > 800:
67
+ analysis.append("⚠️ Alto valor calórico")
68
  if nutrients['proteinas'] < 15:
69
+ analysis.append("⚠️ Baixo teor de proteínas")
70
  if nutrients['fibras'] < 6:
71
+ analysis.append("⚠️ Baixo teor de fibras")
 
 
72
 
73
+ analysis_text = "\n".join(analysis) if analysis else "✅ Valores nutricionais adequados"
 
74
 
75
+ # Recomendações personalizadas
76
+ recommendations = []
77
+ if "Alto valor calórico" in analysis_text:
78
+ recommendations.append("• Considere reduzir as porções")
79
+ if "Baixo teor de proteínas" in analysis_text:
80
+ recommendations.append("• Adicione mais fontes de proteína como frango, peixe ou leguminosas")
81
+ if "Baixo teor de fibras" in analysis_text:
82
+ recommendations.append("• Inclua mais vegetais e grãos integrais")
83
+
84
+ recommendations_text = "\n".join(recommendations) if recommendations else "• Continue mantendo uma alimentação equilibrada!"
85
+
86
+ return (
87
+ identified_foods,
88
+ table_data,
89
+ plot_data,
90
+ analysis_text,
91
+ recommendations_text,
92
+ "success" # Status para UI
93
+ )
94
 
95
  except Exception as e:
96
+ return (
97
+ None, None, None, None,
98
+ f"Erro na análise: {str(e)}",
99
+ "error" # Status para UI
100
+ )
101
 
102
  # Interface Gradio
103
  with gr.Blocks(theme=gr.themes.Soft()) as iface:
104
+ # Cabeçalho
105
+ with gr.Row(variant="compact"):
106
+ gr.Markdown("""
107
+ # 🍽️ Análise Nutricional com IA
108
+ """)
109
 
110
+ # Container Principal
111
  with gr.Row():
112
+ # Coluna da Esquerda - Input
113
+ with gr.Column(scale=2):
114
+ gr.Markdown("### 📸 Foto do Prato")
115
  image_input = gr.Image(
116
  type="pil",
117
+ sources=["upload", "webcam"],
118
+ height=400,
119
+ label=""
120
  )
121
+ with gr.Row():
122
+ analyze_btn = gr.Button("🔍 Analisar Prato", variant="primary", size="lg")
123
+ clear_btn = gr.Button("🔄 Limpar", size="lg")
 
 
 
 
 
 
 
124
 
125
+ with gr.Accordion("📝 Dicas para Melhores Resultados", open=False):
126
+ gr.Markdown("""
127
+ - Use fotos bem iluminadas
128
+ - Fotografe de cima para baixo
129
+ - Certifique-se que todos os alimentos estão visíveis
130
+ - Evite sombras ou reflexos fortes
131
+ """)
132
+
133
+ # Coluna da Direita - Resultados
134
+ with gr.Column(scale=3):
135
+ # Status
136
+ status = gr.Markdown(visible=False)
137
+
138
+ with gr.Tabs():
139
+ # Tab de Identificação
140
+ with gr.Tab("🔍 Alimentos Identificados"):
141
+ foods_detected = gr.Markdown(
142
+ label="",
143
+ value="Faça o upload de uma imagem e clique em Analisar"
144
  )
145
 
146
+ # Tab de Nutrientes
147
+ with gr.Tab("📊 Informação Nutricional"):
148
+ with gr.Row():
149
+ nutri_table = gr.Dataframe(
150
+ headers=["Nutriente", "Quantidade"],
151
+ label="",
152
+ wrap=True
153
+ )
154
+ with gr.Row():
155
+ macro_plot = gr.BarPlot(
156
+ label="",
157
+ title="Distribuição de Macronutrientes (g)",
158
+ x="Nutriente",
159
+ y="Quantidade",
160
+ height=300,
161
+ tooltip=["Nutriente", "Quantidade"]
162
+ )
163
 
164
+ # Tab de Análise
165
+ with gr.Tab("💡 Análise e Recomendações"):
166
+ with gr.Box():
167
+ gr.Markdown("#### 📋 Análise")
168
+ analysis_output = gr.Markdown()
169
+
170
+ with gr.Box():
171
+ gr.Markdown("#### ✨ Recomendações")
172
+ recommendations_output = gr.Markdown()
173
+
174
+ # Event handlers
175
+ def clear_outputs():
176
+ return {
177
+ foods_detected: "Faça o upload de uma imagem e clique em Analisar",
178
+ nutri_table: None,
179
+ macro_plot: None,
180
+ analysis_output: None,
181
+ recommendations_output: None,
182
+ status: gr.Markdown(visible=False)
183
+ }
184
 
 
185
  analyze_btn.click(
186
  fn=analyze_nutrition,
187
  inputs=[image_input],
188
+ outputs=[
189
+ foods_detected,
190
+ nutri_table,
191
+ macro_plot,
192
+ analysis_output,
193
+ recommendations_output,
194
+ status
195
+ ]
196
  )
197
 
198
+ clear_btn.click(
199
+ fn=clear_outputs,
200
+ outputs=[
201
+ foods_detected,
202
+ nutri_table,
203
+ macro_plot,
204
+ analysis_output,
205
+ recommendations_output,
206
+ status
207
+ ]
208
+ )
 
209
 
210
+ # Inicia a interface
211
  if __name__ == "__main__":
 
212
  if not API_KEY:
213
  print("⚠️ Atenção: API Key não encontrada!")
214
  print("Configure a variável de ambiente NUTRITION_API_KEY no arquivo .env")