File size: 6,973 Bytes
dbd941d
6e8113e
dbd941d
10eabe4
6e8113e
10eabe4
53476e6
e9001d7
123d916
0f5c7cd
 
dbd941d
0f5c7cd
 
 
 
 
ef7a048
6e8113e
 
 
dbd941d
6e8113e
10eabe4
e9001d7
6e8113e
 
 
e9001d7
 
 
73ef356
 
dbd941d
 
6e8113e
10eabe4
 
6e8113e
ef7a048
73ef356
ef7a048
73ef356
 
 
 
 
 
 
ef7a048
 
6e8113e
0f5c7cd
10eabe4
ef7a048
6e8113e
53476e6
 
6e8113e
53476e6
 
 
 
 
 
6e8113e
0f5c7cd
53476e6
 
0f5c7cd
53476e6
 
e9001d7
53476e6
 
 
e9001d7
53476e6
e9001d7
53476e6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e9001d7
 
0f5c7cd
53476e6
 
0f5c7cd
ae59519
 
 
e9001d7
53476e6
0f5c7cd
 
 
 
ae59519
53476e6
ef7a048
ae59519
 
ae8e572
ae59519
 
 
 
 
 
 
53476e6
 
 
 
0f5c7cd
 
 
 
e39300d
ae59519
 
53476e6
e39300d
53476e6
 
e39300d
0f5c7cd
53476e6
 
 
e39300d
53476e6
0f5c7cd
53476e6
 
 
 
 
6e8113e
0f5c7cd
 
 
 
 
ae59519
e9001d7
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
import gradio as gr
from huggingface_hub import InferenceClient
from PIL import Image
import io
import base64
from functools import lru_cache
import tempfile
import hashlib

# Variável global para armazenar o token da API (padrão vazio)
API_TOKEN = ""

# Função para atualizar o token da API
def update_api_token(new_token):
    global API_TOKEN
    API_TOKEN = new_token.strip()
    return f"✅ Token atualizado com sucesso: {API_TOKEN[:8]}... (ocultado)"

# Função para criar uma instância da API com o token atualizado usando InferenceClient
def get_inference_client(model):
    return InferenceClient(model=model, token=API_TOKEN)

# Função para interpretar a imagem com cache utilizando InferenceClient (captioning)
@lru_cache(maxsize=128)
def interpret_image_cached(image_hash):
    # Instanciar o client para o modelo de captioning
    client = get_inference_client("Salesforce/blip2-opt-2.7b")
    
    # Chamada da API usando método post para gerar a descrição da imagem
    response = client.post(data=image_hash, task="image-to-text")
    description = response.get("generated_text", "").strip().capitalize()
    if not description.endswith("."):
        description += "."
    return description

# Função para análise nutricional com cache utilizando InferenceClient e método post
@lru_cache(maxsize=128)
def nutritional_analysis_cached(description):
    client = get_inference_client("google/flan-t5-large")
    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:"
    )
    response = client.post(json={"inputs": prompt})
    analysis = response.get("generated_text", "").replace("Análise nutricional:", "").strip()
    return analysis

# Função para gerar dicas de saúde com cache utilizando InferenceClient e método post
@lru_cache(maxsize=128)
def health_tips_cached(description):
    client = get_inference_client("google/flan-t5-large")
    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:"
    )
    response = client.post(json={"inputs": prompt})
    tips = response.get("generated_text", "").replace("Dicas de saúde:", "").strip()
    return tips

# Função principal para processar a imagem e gerar resultados
def process_image(image):
    try:
        # Converter imagem para bytes e gerar um hash
        buffered = io.BytesIO()
        image.save(buffered, format="JPEG")
        image_bytes = buffered.getvalue()
        image_hash = hashlib.md5(image_bytes).hexdigest()
        
        description = interpret_image_cached(image_hash)
        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!"
        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)
            tmp_path = tmp.name
        return tmp_path
    except Exception:
        return None

# Interface Gradio com aba Settings para configurar o token da API
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](pplx://action/followup)** de pratos a partir de imagens.
        - **[Análise nutricional detalhada](pplx://action/followup)** com estimativas precisas de calorias e macronutrientes.
        - **[Dicas de saúde personalizadas](pplx://action/followup)** para aprimorar sua alimentação.
        - **[Resultado completo para download](pplx://action/followup)** 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.TabItem("Settings"):
                    api_token_input = gr.Textbox(label="Token da API Hugging Face", placeholder="Insira seu token aqui...")
                    update_button = gr.Button("Atualizar Token")
                    update_feedback = gr.Markdown("")

    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")
    )
    
    update_button.click(
        update_api_token,
        inputs=api_token_input,
        outputs=update_feedback
    )

demo.launch()