File size: 5,744 Bytes
5c0c96a
538b4a9
a9c5239
548dad1
a9c5239
f631343
a7603f9
a9c5239
 
 
538b4a9
ec914f9
30e029e
 
 
ad1b5eb
ec914f9
a9c5239
30e029e
538b4a9
ec914f9
a9c5239
ec914f9
 
 
 
 
 
f631343
 
a9c5239
 
 
ec914f9
a9c5239
 
f631343
a9c5239
 
f631343
a9c5239
ec914f9
 
f631343
 
 
 
 
 
 
a9c5239
ec914f9
 
 
 
 
 
 
 
a9c5239
 
 
 
 
 
 
 
 
 
ec914f9
 
 
 
 
a7603f9
 
a9c5239
 
 
f631343
a9c5239
a7603f9
ec914f9
 
548dad1
ec914f9
 
58996b4
ec914f9
a9c5239
538b4a9
30e029e
548dad1
30e029e
 
 
 
 
6fdacd7
30e029e
 
 
 
 
 
 
 
 
392b7ca
ec914f9
a9c5239
548dad1
30e029e
a9c5239
ec914f9
ad1b5eb
a9c5239
 
 
 
 
ad1b5eb
a9c5239
 
 
 
97ab7f8
30e029e
548dad1
30e029e
548dad1
 
97ab7f8
a9c5239
 
 
0f757cc
 
 
 
 
a9c5239
0f757cc
 
a9c5239
0f757cc
a9c5239
0f757cc
 
 
 
 
ec914f9
0f757cc
 
 
 
 
 
ec914f9
0f757cc
 
 
 
 
 
 
5c0c96a
 
ad1b5eb
94cd887
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
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)