Spaces:
Build error
Build error
import gradio as gr | |
import torch | |
from transformers import AutoModelForCausalLM, AutoProcessor | |
from PIL import Image | |
import pandas as pd | |
import numpy as np | |
# Carrega o modelo Emu3-Gen | |
model = AutoModelForCausalLM.from_pretrained("BAAI/Emu3-Gen", trust_remote_code=True) | |
processor = AutoProcessor.from_pretrained("BAAI/Emu3-Gen", trust_remote_code=True) | |
# Base de dados nutricional | |
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}, | |
"carne": {"calorias": 250, "proteinas": 26, "carboidratos": 0, "gorduras": 17}, | |
"batata frita": {"calorias": 312, "proteinas": 3.4, "carboidratos": 41, "gorduras": 15}, | |
"salada": {"calorias": 15, "proteinas": 1.4, "carboidratos": 2.9, "gorduras": 0.2} | |
} | |
def process_image(image, progress=gr.Progress()): | |
"""Processa a imagem usando Emu3-Gen""" | |
try: | |
progress(0.3, desc="Processando imagem...") | |
# Prepara a imagem | |
if isinstance(image, str): | |
image = Image.open(image) | |
elif isinstance(image, np.ndarray): | |
image = Image.fromarray(image) | |
# Prompt específico para análise de alimentos | |
prompt = "Describe in detail all the foods present in this image, including their preparation methods." | |
progress(0.6, desc="Analisando conteúdo...") | |
# Processa a imagem | |
inputs = processor( | |
images=image, | |
text=prompt, | |
return_tensors="pt" | |
).to(model.device) | |
# Gera a descrição | |
outputs = model.generate( | |
**inputs, | |
max_new_tokens=100, | |
num_beams=5, | |
temperature=0.7, | |
top_p=0.9 | |
) | |
description = processor.decode(outputs[0], skip_special_tokens=True) | |
progress(1.0, desc="Concluído!") | |
return description | |
except Exception as e: | |
raise gr.Error(f"Erro no processamento: {str(e)}") | |
def analyze_nutrition(description): | |
"""Analisa nutrientes baseado na descrição""" | |
found_foods = [] | |
# Identifica alimentos na descrição | |
for food in NUTRITION_DB.keys(): | |
if food.lower() in description.lower(): | |
found_foods.append(food) | |
# Calcula nutrientes | |
total_nutrients = { | |
"calorias": 0, | |
"proteinas": 0, | |
"carboidratos": 0, | |
"gorduras": 0 | |
} | |
for food in found_foods: | |
for nutrient, value in NUTRITION_DB[food].items(): | |
total_nutrients[nutrient] += value | |
return total_nutrients, found_foods | |
def analyze_image(image): | |
"""Função principal de análise""" | |
try: | |
# Processa a imagem | |
description = process_image(image) | |
# Analisa nutrientes | |
total_nutrients, found_foods = analyze_nutrition(description) | |
# 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'] | |
] | |
}) | |
# Monta o relatório | |
analysis = f"""### 🔍 Análise da Imagem: | |
{description} | |
### 🍽️ Alimentos Identificados: | |
{', '.join(found_foods)} | |
### 📊 Informação Nutricional: | |
• Calorias: {total_nutrients['calorias']:.1f} kcal | |
• Proteínas: {total_nutrients['proteinas']:.1f}g | |
• Carboidratos: {total_nutrients['carboidratos']:.1f}g | |
• Gorduras: {total_nutrients['gorduras']:.1f}g | |
### 💡 Recomendações: | |
{"⚠️ Alto valor calórico" if total_nutrients['calorias'] > 800 else "✅ Calorias adequadas"} | |
{"⚠️ Considere reduzir carboidratos" if total_nutrients['carboidratos'] > 60 else "✅ Carboidratos adequados"} | |
{"⚠️ Alto teor de gorduras" if total_nutrients['gorduras'] > 20 else "✅ Gorduras adequadas"} | |
""" | |
return analysis, table_data, plot_data | |
except Exception as e: | |
return str(e), None, None | |
# Interface Gradio | |
with gr.Blocks(theme=gr.themes.Soft()) as iface: | |
gr.Markdown("# 🍽️ NutriAI - Análise Nutricional com IA") | |
with gr.Row(): | |
with gr.Column(): | |
image_input = gr.Image( | |
type="pil", | |
label="Foto do Prato", | |
sources=["upload", "webcam"] | |
) | |
analyze_btn = gr.Button("📊 Analisar", variant="primary") | |
with gr.Column(): | |
output_text = gr.Markdown() | |
with gr.Row(): | |
output_table = gr.Dataframe( | |
headers=["Nutriente", "Quantidade"], | |
label="Informação Nutricional" | |
) | |
output_plot = gr.BarPlot( | |
x="Nutriente", | |
y="Quantidade", | |
title="Macronutrientes (g)", | |
height=300 | |
) | |
analyze_btn.click( | |
fn=analyze_image, | |
inputs=[image_input], | |
outputs=[output_text, output_table, output_plot] | |
) | |
if __name__ == "__main__": | |
print(f"Usando dispositivo: {'CUDA' if torch.cuda.is_available() else 'CPU'}") | |
iface.launch(share=False) |