Spaces:
Build error
Build error
import gradio as gr | |
import torch | |
import pandas as pd | |
import numpy as np | |
from PIL import Image | |
import re | |
# Base de dados nutricional expandida com variações e sinônimos | |
FOOD_ALIASES = { | |
"arroz": ["arroz branco", "arroz integral", "arroz cozido", "arroz solto"], | |
"feijão": ["feijão preto", "feijão carioca", "feijão vermelho", "feijões"], | |
"frango": ["frango grelhado", "peito de frango", "filé de frango", "frango assado", "chicken"], | |
"salada": ["alface", "tomate", "verduras", "legumes", "vegetais", "salada verde"], | |
"batata": ["batata cozida", "batata assada", "purê de batata", "potato"], | |
"carne": ["carne vermelha", "bife", "filé", "carne assada", "beef"], | |
"peixe": ["filé de peixe", "peixe grelhado", "peixe assado", "fish"], | |
"macarrão": ["espaguete", "massa", "pasta", "macarrão integral", "noodles"], | |
"ovo": ["ovo frito", "ovo cozido", "ovos", "omelete", "eggs"] | |
} | |
NUTRITION_DB = { | |
"arroz": {"calorias": 130, "proteinas": 2.7, "carboidratos": 28, "gorduras": 0.3}, | |
"feijão": {"calorias": 77, "proteinas": 5.2, "carboidratos": 13.6, "gorduras": 0.5}, | |
"frango": {"calorias": 165, "proteinas": 31, "carboidratos": 0, "gorduras": 3.6}, | |
"salada": {"calorias": 15, "proteinas": 1.4, "carboidratos": 2.9, "gorduras": 0.2}, | |
"batata": {"calorias": 93, "proteinas": 2.5, "carboidratos": 21, "gorduras": 0.1}, | |
"carne": {"calorias": 250, "proteinas": 26, "carboidratos": 0, "gorduras": 17}, | |
"peixe": {"calorias": 206, "proteinas": 22, "carboidratos": 0, "gorduras": 12}, | |
"macarrão": {"calorias": 158, "proteinas": 5.8, "carboidratos": 31, "gorduras": 1.2}, | |
"ovo": {"calorias": 155, "proteinas": 13, "carboidratos": 1.1, "gorduras": 11}, | |
} | |
def identify_foods(description): | |
""" | |
Identifica alimentos na descrição usando múltiplas verificações | |
""" | |
found_foods = {} | |
description = description.lower() | |
# Primeira verificação: busca direta | |
for base_food in NUTRITION_DB.keys(): | |
if base_food in description: | |
found_foods[base_food] = { | |
"confianca": "Alta", | |
"mencoes": description.count(base_food), | |
"variacao": base_food | |
} | |
# Segunda verificação: sinônimos e variações | |
for base_food, aliases in FOOD_ALIASES.items(): | |
if base_food not in found_foods: # Só verifica se ainda não encontrou | |
for alias in aliases: | |
if alias in description: | |
found_foods[base_food] = { | |
"confianca": "Média", | |
"mencoes": description.count(alias), | |
"variacao": alias | |
} | |
# Terceira verificação: análise de contexto | |
context_clues = { | |
"prato": 0.1, | |
"refeição": 0.1, | |
"porção": 0.1, | |
"servido": 0.1, | |
"preparado": 0.1 | |
} | |
for food in found_foods: | |
confidence_boost = 0 | |
for clue, value in context_clues.items(): | |
if clue in description: | |
confidence_boost += value | |
if confidence_boost > 0: | |
found_foods[food]["confianca"] = "Alta" if confidence_boost > 0.2 else found_foods[food]["confianca"] | |
# Quarta verificação: validação de preparação | |
cooking_methods = ["cozido", "assado", "grelhado", "frito", "cru"] | |
for food in found_foods: | |
for method in cooking_methods: | |
if method in description and food in FOOD_ALIASES: | |
found_foods[food]["preparo"] = method | |
return found_foods | |
def analyze_foods(description): | |
"""Analisa a descrição e retorna informações nutricionais""" | |
try: | |
# Identificação detalhada dos alimentos | |
identified_foods = identify_foods(description) | |
if not identified_foods: | |
return "Nenhum alimento conhecido identificado com confiança.", None, None | |
# Calcula nutrientes | |
total_nutrients = { | |
"calorias": 0, | |
"proteinas": 0, | |
"carboidratos": 0, | |
"gorduras": 0 | |
} | |
# Lista detalhada de alimentos identificados | |
foods_detail = [] | |
for food, info in identified_foods.items(): | |
foods_detail.append(f"• {food.capitalize()}") | |
foods_detail.append(f" - Confiança: {info['confianca']}") | |
foods_detail.append(f" - Menções: {info['mencoes']}") | |
foods_detail.append(f" - Variação encontrada: {info['variacao']}") | |
if 'preparo' in info: | |
foods_detail.append(f" - Método de preparo: {info['preparo']}") | |
# Soma nutrientes | |
for nutrient, value in NUTRITION_DB[food].items(): | |
total_nutrients[nutrient] += value | |
# Prepara dados para visualização | |
table_data = [ | |
["Calorias", f"{total_nutrients['calorias']:.1f} kcal"], | |
["Proteínas", f"{total_nutrients['proteinas']:.1f}g"], | |
["Carboidratos", f"{total_nutrients['carboidratos']:.1f}g"], | |
["Gorduras", f"{total_nutrients['gorduras']:.1f}g"] | |
] | |
# Dados para o gráfico | |
plot_data = pd.DataFrame({ | |
'Nutriente': ['Proteínas', 'Carboidratos', 'Gorduras'], | |
'Quantidade': [ | |
total_nutrients['proteinas'], | |
total_nutrients['carboidratos'], | |
total_nutrients['gorduras'] | |
] | |
}) | |
analysis = f"""### 🍽️ Descrição do Modelo: | |
{description} | |
### 🔍 Alimentos Identificados: | |
{chr(10).join(foods_detail)} | |
### 📊 Análise Nutricional: | |
• Calorias Totais: {total_nutrients['calorias']:.1f} kcal | |
• Proteínas: {total_nutrients['proteinas']:.1f}g | |
• Carboidratos: {total_nutrients['carboidratos']:.1f}g | |
• Gorduras: {total_nutrients['gorduras']:.1f}g | |
### 💡 Avaliação: | |
{"✅ Refeição balanceada!" if total_nutrients['proteinas'] > 15 else "⚠️ Considere adicionar mais proteínas"} | |
{"✅ Carboidratos adequados" if total_nutrients['carboidratos'] < 60 else "⚠️ Alto teor de carboidratos"} | |
{"✅ Gorduras em nível adequado" if total_nutrients['gorduras'] < 20 else "⚠️ Alto teor de gorduras"} | |
""" | |
return analysis, table_data, plot_data | |
except Exception as e: | |
raise gr.Error(f"Erro na análise: {str(e)}") | |
def analyze_image(image): | |
"""Função principal que coordena o processo de análise""" | |
try: | |
# Simula a resposta do modelo (temporário até resolvermos o erro do DeepSeek) | |
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." | |
# Analisa os alimentos | |
analysis, table_data, plot_data = analyze_foods(description) | |
return analysis, table_data, plot_data | |
except Exception as e: | |
return str(e), None, None | |
# Interface Gradio (resto do código permanece o mesmo) | |
with gr.Blocks(theme=gr.themes.Soft()) as iface: | |
# ... (resto do código da interface permanece igual) | |
if __name__ == "__main__": | |
print(f"Usando dispositivo: {'CUDA' if torch.cuda.is_available() else 'CPU'}") | |
iface.launch(share=False) |