File size: 7,708 Bytes
dbd941d
e6a5fa4
dbd941d
123d916
10eabe4
 
53476e6
123d916
 
 
 
 
 
dbd941d
e6a5fa4
123d916
 
 
 
 
 
 
 
 
ef7a048
53476e6
123d916
 
 
 
 
 
 
dbd941d
10eabe4
 
 
53476e6
dbd941d
e6a5fa4
dbd941d
73ef356
 
 
dbd941d
 
10eabe4
 
 
ef7a048
73ef356
ef7a048
73ef356
 
 
 
 
 
 
ef7a048
 
e6a5fa4
73ef356
10eabe4
ef7a048
53476e6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ae59519
 
 
53476e6
 
 
 
 
 
ae59519
53476e6
ef7a048
ae59519
 
ae8e572
ae59519
 
 
 
 
 
 
53476e6
 
 
 
 
ae59519
 
53476e6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ae59519
 
 
 
53476e6
 
 
ae59519
53476e6
 
ae59519
53476e6
ae8e572
 
 
 
ae59519
53476e6
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
172
173
174
175
176
import gradio as gr
from transformers import Blip2Processor, Blip2ForConditionalGeneration, pipeline
from PIL import Image
import os
import io
from functools import lru_cache
import tempfile

# Função para verificar se o modelo existe localmente
def check_model_locally(model_name):
    cache_dir = os.path.expanduser("~/.cache/huggingface/transformers")
    model_path = os.path.join(cache_dir, model_name.replace("/", "--"))
    return os.path.exists(model_path)

# Carregar o modelo BLIP-2 para geração de descrições de imagens
model_blip2_name = "Salesforce/blip2-opt-2.7b"
if check_model_locally(model_blip2_name):
    print(f"Modelo {model_blip2_name} encontrado localmente.")
    processor = Blip2Processor.from_pretrained(model_blip2_name, local_files_only=True)
    model_blip2 = Blip2ForConditionalGeneration.from_pretrained(model_blip2_name, local_files_only=True)
else:
    print(f"Modelo {model_blip2_name} não encontrado localmente. Baixando...")
    processor = Blip2Processor.from_pretrained(model_blip2_name)
    model_blip2 = Blip2ForConditionalGeneration.from_pretrained(model_blip2_name)

# Carregar o modelo de linguagem para análise nutricional (exemplo: Flan-T5)
nutrition_model_name = "google/flan-t5-large"
if check_model_locally(nutrition_model_name):
    print(f"Modelo {nutrition_model_name} encontrado localmente.")
    nutrition_model = pipeline("text2text-generation", model=nutrition_model_name, local_files_only=True)
else:
    print(f"Modelo {nutrition_model_name} não encontrado localmente. Baixando...")
    nutrition_model = pipeline("text2text-generation", model=nutrition_model_name)

# Função para interpretar a imagem com cache
@lru_cache(maxsize=128)
def interpret_image_cached(image_bytes):
    image = Image.open(io.BytesIO(image_bytes)).convert("RGB")
    inputs = processor(image, return_tensors="pt")
    out = model_blip2.generate(**inputs)
    description = processor.decode(out[0], skip_special_tokens=True)
    description = description.strip().capitalize()
    if not description.endswith("."):
        description += "."
    return description

# Função para análise nutricional com cache
@lru_cache(maxsize=128)
def nutritional_analysis_cached(description):
    prompt = (
        f"Com base na descrição do prato de comida abaixo, forneça uma análise nutricional detalhada.\n\n"
        f"Descrição do prato: {description}\n\n"
        f"Siga este formato:\n"
        f"- Calorias totais estimadas: [valor]\n"
        f"- Macronutrientes (em gramas):\n"
        f"  - Carboidratos: [valor]\n"
        f"  - Proteínas: [valor]\n"
        f"  - Gorduras: [valor]\n"
        f"- Recomendações para melhorar o prato: [sugestões]\n\n"
        f"Análise nutricional:"
    )
    analysis = nutrition_model(prompt, max_length=300)[0]['generated_text']
    analysis = analysis.replace("Análise nutricional:", "").strip()
    return analysis

# Função para gerar dicas de saúde com cache
@lru_cache(maxsize=128)
def health_tips_cached(description):
    prompt = (
        f"Com base na descrição do prato de comida abaixo, forneça dicas de saúde e sugestões "
        f"para melhorar o prato, tornando-o mais equilibrado e nutritivo. Liste as dicas em tópicos.\n\n"
        f"Descrição do prato: {description}\n\n"
        f"Dicas de saúde:"
    )
    tips = nutrition_model(prompt, max_length=150)[0]['generated_text']
    tips = tips.replace("Dicas de saúde:", "").strip()
    return tips

# Função para processar a imagem e gerar todos os resultados
def process_image(image):
    try:
        # Converter a imagem para bytes e gerar a descrição com cache
        buffered = io.BytesIO()
        image.save(buffered, format="JPEG")
        image_bytes = buffered.getvalue()
        
        description = interpret_image_cached(image_bytes)
        analysis = nutritional_analysis_cached(description)
        tips = health_tips_cached(description)
        complete_result = (
            f"Descrição do Prato:\n{description}\n\n"
            f"Análise Nutricional:\n{analysis}\n\n"
            f"Dicas de Saúde:\n{tips}"
        )
        feedback_message = "✅ Análise concluída com sucesso!"
        # Retorne os 5 outputs: cada aba e um estado oculto com o resultado completo
        return description, analysis, tips, complete_result, complete_result, feedback_message
    except Exception as e:
        feedback_message = f"❌ Erro ao processar a imagem: {str(e)}"
        return "", "", "", "", "", feedback_message

# Função para gerar um arquivo de download com o resultado completo
def generate_download(complete_result):
    try:
        with tempfile.NamedTemporaryFile(delete=False, suffix=".txt", mode="w", encoding="utf-8") as tmp:
            tmp.write(complete_result)
            return tmp.name
    except Exception as e:
        return None

with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="cyan")) as demo:
    with gr.Row():
        gr.Markdown("""
        # 🍽️ Agente Nutricionista Inteligente Avançado
        ### Revolucione a análise de suas refeições com IA de última geração!
        - **Descrição automática** de pratos a partir de imagens.
        - **Análise nutricional detalhada** com estimativas precisas de calorias e macronutrientes.
        - **Dicas de saúde personalizadas** para aprimorar sua alimentação.
        - **Resultado completo para download** em formato TXT.
        """)

    with gr.Row():
        with gr.Column(scale=1):
            gr.Markdown("### 📸 Carregue uma Imagem")
            image_input = gr.Image(type="pil", label="Upload de Imagem", height=300)
        with gr.Column(scale=2):
            gr.Markdown("### 🔍 Resultados")
            with gr.Tabs():
                with gr.TabItem("Descrição do Prato"):
                    description_output = gr.Textbox(label="Descrição Gerada", lines=3, interactive=False)
                with gr.TabItem("Análise Nutricional"):
                    analysis_output = gr.Textbox(label="Análise Nutricional", lines=8, interactive=False)
                with gr.TabItem("Dicas de Saúde"):
                    tips_output = gr.Textbox(label="Dicas de Saúde", lines=6, interactive=False)
                with gr.TabItem("Resultado Completo"):
                    complete_result_output = gr.Textbox(label="Resultado Completo", lines=15, interactive=False)

    with gr.Row():
        submit_button = gr.Button("✨ Analisar Prato", variant="primary")
        download_button = gr.Button("💾 Baixar Resultado", variant="secondary")

    # Estado oculto para armazenar o resultado completo para o download
    result_state = gr.State("")
    feedback = gr.Markdown("")

    submit_button.click(
        process_image,
        inputs=image_input,
        outputs=[description_output, analysis_output, tips_output, complete_result_output, result_state, feedback]
    )

    download_button.click(
        generate_download,
        inputs=result_state,
        outputs=gr.File(label="Seu Resultado")
    )

    with gr.Row():
        gr.Markdown("""
        ---
        ### 💡 Dicas para Melhores Resultados:
        - Utilize imagens de alta resolução e boa iluminação.
        - Certifique-se de que todos os ingredientes estejam visíveis.
        - Experimente diferentes ângulos para capturar os detalhes do prato.
        
        ### 🌟 Conecte-se Conosco
        - Para mais informações, visite nosso site oficial ou siga nossas redes sociais!
        """)

    examples = [
        "https://huggingface.co/spaces/DHEIVER/blip-image-captioning-base/blob/main/img.jpg"
    ]
    gr.Examples(examples, inputs=image_input)

demo.launch()