Spaces:
Build error
Build error
Update app.py
Browse files
app.py
CHANGED
@@ -4,113 +4,63 @@ from PIL import Image
|
|
4 |
import requests
|
5 |
from io import BytesIO
|
6 |
|
7 |
-
def process_image(image, api_key=None):
|
8 |
-
"""
|
9 |
-
Processa a imagem usando a API de análise nutricional
|
10 |
-
"""
|
11 |
-
try:
|
12 |
-
# Prepara a imagem
|
13 |
-
if isinstance(image, str):
|
14 |
-
img = Image.open(image)
|
15 |
-
else:
|
16 |
-
img = Image.fromarray(image)
|
17 |
-
|
18 |
-
# Converte para formato adequado
|
19 |
-
buffered = BytesIO()
|
20 |
-
img.save(buffered, format="JPEG")
|
21 |
-
img_bytes = buffered.getvalue()
|
22 |
-
|
23 |
-
# Headers da requisição
|
24 |
-
headers = {}
|
25 |
-
if api_key:
|
26 |
-
headers['Authorization'] = f'Bearer {api_key}'
|
27 |
-
|
28 |
-
# Faz a requisição para a API
|
29 |
-
files = {'image': ('image.jpg', img_bytes, 'image/jpeg')}
|
30 |
-
response = requests.post(
|
31 |
-
'http://localhost:7860/api/predict', # Ajuste a URL conforme necessário
|
32 |
-
files=files,
|
33 |
-
headers=headers
|
34 |
-
)
|
35 |
-
|
36 |
-
if response.status_code == 200:
|
37 |
-
return response.json()
|
38 |
-
else:
|
39 |
-
return f"Erro na API: {response.status_code}"
|
40 |
-
|
41 |
-
except Exception as e:
|
42 |
-
return f"Erro no processamento: {str(e)}"
|
43 |
-
|
44 |
def analyze_nutrition(image, api_key=""):
|
45 |
"""
|
46 |
Função principal que processa a imagem e retorna os resultados formatados
|
47 |
"""
|
48 |
try:
|
49 |
-
#
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
None # Recomendações
|
58 |
-
)
|
59 |
-
|
60 |
-
# Extrai informações do resultado
|
61 |
-
nutrients = result.get('nutrients', {})
|
62 |
|
63 |
# Prepara dados para o gráfico
|
64 |
-
|
65 |
-
|
66 |
-
'values': [
|
67 |
-
nutrients.get('proteinas', 0),
|
68 |
-
nutrients.get('carboidratos', 0),
|
69 |
-
nutrients.get('gorduras', 0)
|
70 |
-
]
|
71 |
-
}
|
72 |
|
73 |
# Prepara tabela nutricional
|
74 |
-
|
75 |
-
|
76 |
-
'
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
f"{nutrients.get('fibras', 0):.1f}g"
|
82 |
-
]
|
83 |
-
}
|
84 |
|
85 |
# Prepara recomendações
|
86 |
recommendations = []
|
87 |
-
if nutrients
|
88 |
recommendations.append("⚠️ Alto valor calórico - considere reduzir as porções")
|
89 |
-
if nutrients
|
90 |
recommendations.append("⚠️ Baixo teor de proteínas - considere adicionar fontes proteicas")
|
91 |
-
if nutrients
|
92 |
recommendations.append("⚠️ Baixo teor de fibras - adicione mais vegetais")
|
93 |
-
|
94 |
-
recommendations = "\n".join(recommendations) if recommendations else "✅ Valores nutricionais dentro das recomendações!"
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
),
|
105 |
-
|
106 |
-
headers=['Nutriente', 'Quantidade'],
|
107 |
-
data=list(zip(nutri_table['Nutriente'], nutri_table['Quantidade']))
|
108 |
-
), # Tabela
|
109 |
-
recommendations # Texto de recomendações
|
110 |
)
|
111 |
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
except Exception as e:
|
113 |
-
|
|
|
114 |
|
115 |
# Interface Gradio
|
116 |
with gr.Blocks(theme=gr.themes.Soft()) as iface:
|
@@ -120,21 +70,23 @@ with gr.Blocks(theme=gr.themes.Soft()) as iface:
|
|
120 |
""")
|
121 |
|
122 |
with gr.Row():
|
123 |
-
with gr.Column():
|
124 |
# Inputs
|
125 |
image_input = gr.Image(
|
126 |
type="pil",
|
127 |
label="Foto do Prato",
|
128 |
-
sources=['upload', 'webcam']
|
|
|
129 |
)
|
130 |
api_key = gr.Textbox(
|
131 |
label="API Key (opcional)",
|
132 |
placeholder="Digite sua API key aqui...",
|
133 |
-
type="password"
|
|
|
134 |
)
|
135 |
analyze_btn = gr.Button("📊 Analisar", variant="primary")
|
136 |
|
137 |
-
with gr.Column():
|
138 |
# Outputs
|
139 |
with gr.Tab("Resumo"):
|
140 |
recommendations = gr.Textbox(
|
@@ -143,16 +95,15 @@ with gr.Blocks(theme=gr.themes.Soft()) as iface:
|
|
143 |
)
|
144 |
nutri_table = gr.Dataframe(
|
145 |
label="Tabela Nutricional",
|
146 |
-
headers=['Nutriente', 'Quantidade']
|
|
|
147 |
)
|
148 |
macro_plot = gr.Plot(
|
149 |
-
label="Macronutrientes"
|
150 |
)
|
151 |
|
152 |
with gr.Tab("Detalhes"):
|
153 |
-
json_output = gr.JSON(
|
154 |
-
label="Resultado Detalhado"
|
155 |
-
)
|
156 |
|
157 |
# Eventos
|
158 |
analyze_btn.click(
|
@@ -164,9 +115,8 @@ with gr.Blocks(theme=gr.themes.Soft()) as iface:
|
|
164 |
gr.Markdown("""
|
165 |
### 📝 Instruções
|
166 |
1. Faça upload de uma foto do seu prato ou tire uma foto com a webcam
|
167 |
-
2.
|
168 |
-
3.
|
169 |
-
4. Veja os resultados nas abas "Resumo" e "Detalhes"
|
170 |
|
171 |
### 🎯 Dicas para melhores resultados
|
172 |
- Use fotos bem iluminadas
|
|
|
4 |
import requests
|
5 |
from io import BytesIO
|
6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
def analyze_nutrition(image, api_key=""):
|
8 |
"""
|
9 |
Função principal que processa a imagem e retorna os resultados formatados
|
10 |
"""
|
11 |
try:
|
12 |
+
# Simula resultado da análise (substitua pelo resultado real da sua API)
|
13 |
+
nutrients = {
|
14 |
+
"calorias": 450,
|
15 |
+
"proteinas": 25,
|
16 |
+
"carboidratos": 55,
|
17 |
+
"gorduras": 15,
|
18 |
+
"fibras": 8
|
19 |
+
}
|
|
|
|
|
|
|
|
|
|
|
20 |
|
21 |
# Prepara dados para o gráfico
|
22 |
+
labels = ['Proteínas', 'Carboidratos', 'Gorduras']
|
23 |
+
values = [nutrients['proteinas'], nutrients['carboidratos'], nutrients['gorduras']]
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
|
25 |
# Prepara tabela nutricional
|
26 |
+
table_data = [
|
27 |
+
["Calorias", f"{nutrients['calorias']:.1f} kcal"],
|
28 |
+
["Proteínas", f"{nutrients['proteinas']:.1f}g"],
|
29 |
+
["Carboidratos", f"{nutrients['carboidratos']:.1f}g"],
|
30 |
+
["Gorduras", f"{nutrients['gorduras']:.1f}g"],
|
31 |
+
["Fibras", f"{nutrients['fibras']:.1f}g"]
|
32 |
+
]
|
|
|
|
|
|
|
33 |
|
34 |
# Prepara recomendações
|
35 |
recommendations = []
|
36 |
+
if nutrients['calorias'] > 800:
|
37 |
recommendations.append("⚠️ Alto valor calórico - considere reduzir as porções")
|
38 |
+
if nutrients['proteinas'] < 15:
|
39 |
recommendations.append("⚠️ Baixo teor de proteínas - considere adicionar fontes proteicas")
|
40 |
+
if nutrients['fibras'] < 6:
|
41 |
recommendations.append("⚠️ Baixo teor de fibras - adicione mais vegetais")
|
|
|
|
|
42 |
|
43 |
+
recommendations_text = "\n".join(recommendations) if recommendations else "✅ Valores nutricionais dentro das recomendações!"
|
44 |
+
|
45 |
+
# Cria o gráfico
|
46 |
+
plot = gr.BarPlot(
|
47 |
+
value=(labels, values),
|
48 |
+
title="Distribuição de Macronutrientes",
|
49 |
+
x="Nutrientes",
|
50 |
+
y="Gramas",
|
51 |
+
tooltip=["Nutriente", "Quantidade (g)"],
|
52 |
+
height=300
|
|
|
|
|
|
|
|
|
53 |
)
|
54 |
|
55 |
+
# Retorna os componentes
|
56 |
+
return {
|
57 |
+
"message": "Análise concluída com sucesso!",
|
58 |
+
"nutrients": nutrients
|
59 |
+
}, plot, table_data, recommendations_text
|
60 |
+
|
61 |
except Exception as e:
|
62 |
+
error_json = {"error": str(e)}
|
63 |
+
return error_json, None, None, f"Erro na análise: {str(e)}"
|
64 |
|
65 |
# Interface Gradio
|
66 |
with gr.Blocks(theme=gr.themes.Soft()) as iface:
|
|
|
70 |
""")
|
71 |
|
72 |
with gr.Row():
|
73 |
+
with gr.Column(scale=1):
|
74 |
# Inputs
|
75 |
image_input = gr.Image(
|
76 |
type="pil",
|
77 |
label="Foto do Prato",
|
78 |
+
sources=['upload', 'webcam'],
|
79 |
+
height=300
|
80 |
)
|
81 |
api_key = gr.Textbox(
|
82 |
label="API Key (opcional)",
|
83 |
placeholder="Digite sua API key aqui...",
|
84 |
+
type="password",
|
85 |
+
visible=False # Oculto por enquanto
|
86 |
)
|
87 |
analyze_btn = gr.Button("📊 Analisar", variant="primary")
|
88 |
|
89 |
+
with gr.Column(scale=2):
|
90 |
# Outputs
|
91 |
with gr.Tab("Resumo"):
|
92 |
recommendations = gr.Textbox(
|
|
|
95 |
)
|
96 |
nutri_table = gr.Dataframe(
|
97 |
label="Tabela Nutricional",
|
98 |
+
headers=['Nutriente', 'Quantidade'],
|
99 |
+
wrap=True
|
100 |
)
|
101 |
macro_plot = gr.Plot(
|
102 |
+
label="Gráfico de Macronutrientes"
|
103 |
)
|
104 |
|
105 |
with gr.Tab("Detalhes"):
|
106 |
+
json_output = gr.JSON()
|
|
|
|
|
107 |
|
108 |
# Eventos
|
109 |
analyze_btn.click(
|
|
|
115 |
gr.Markdown("""
|
116 |
### 📝 Instruções
|
117 |
1. Faça upload de uma foto do seu prato ou tire uma foto com a webcam
|
118 |
+
2. Clique em "Analisar"
|
119 |
+
3. Veja os resultados nas abas "Resumo" e "Detalhes"
|
|
|
120 |
|
121 |
### 🎯 Dicas para melhores resultados
|
122 |
- Use fotos bem iluminadas
|