DHEIVER's picture
Update app.py
a7603f9 verified
raw
history blame
7.4 kB
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)