Spaces:
Runtime error
Runtime error
import os | |
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' # Suprimir avisos do TensorFlow | |
import gradio as gr | |
import tensorflow as tf | |
from tensorflow.keras.models import load_model | |
import numpy as np | |
from PIL import Image | |
import requests | |
import json | |
import matplotlib.pyplot as plt | |
from fpdf import FPDF | |
# ================== CARREGAMENTO DO MODELO ================== | |
try: | |
model = load_model('wound_classifier_model_googlenet.h5') | |
print("✅ Modelo carregado com sucesso") | |
except Exception as e: | |
raise RuntimeError(f"❌ Falha ao carregar o modelo: {str(e)}") | |
# ================== RÓTULOS DAS CLASSES ================== | |
CLASS_LABELS = [ | |
"Abrasões", "Hematomas", "Queimaduras", "Corte", "Feridas Diabéticas", "Gengivite", | |
"Feridas Cirúrgicas", "Feridas Venosas", "Pé de Atleta", "Celulite", | |
"Catapora", "Larva Migrans Cutânea", "Impetigo", "Fungo nas Unhas", | |
"Micose", "Herpes-Zóster", "Descoloração dos Dentes", "Úlcera" | |
] | |
# Verificar compatibilidade do modelo | |
assert len(CLASS_LABELS) == model.output_shape[-1], \ | |
f"Discrepância de classes: O modelo espera {model.output_shape[-1]} classes, encontradas {len(CLASS_LABELS)}" | |
# ================== CONFIGURAÇÃO DO OPENROUTER ================== | |
OPENROUTER_API_KEY = "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" | |
OPENROUTER_API_URL = "https://openrouter.ai/api/v1/chat/completions" | |
MODEL_NAME = "mistralai/mistral-7b-instruct" | |
# ================== PROCESSAMENTO DE IMAGENS ================== | |
def preprocess_image(image, target_size=(224, 224)): | |
"""Processar e validar imagens de entrada""" | |
try: | |
if not image: | |
raise ValueError("🚨 Nenhuma imagem fornecida") | |
image = image.convert("RGB").resize(target_size) | |
array = np.array(image) / 255.0 | |
print(f"🖼️ Imagem processada: Formato {array.shape}") | |
return array | |
except Exception as e: | |
raise RuntimeError(f"🖼️ Falha no processamento da imagem: {str(e)}") | |
# ================== DIRETRIZES MÉDICAS ================== | |
def get_medical_guidelines(wound_type): | |
"""Buscar diretrizes de tratamento da API OpenRouter""" | |
headers = { | |
"Authorization": f"Bearer {OPENROUTER_API_KEY}", | |
"Content-Type": "application/json", | |
"HTTP-Referer": "https://huggingface.co/spaces/MahatirTusher/Wound_Treatment" | |
} | |
prompt = f"""Você é um especialista médico fornecendo orientações para um paciente com {wound_type}. | |
Primeiro, apresente brevemente o que são {wound_type} e suas características típicas. | |
Em seguida, forneça um guia abrangente de cuidados, incluindo: | |
1. Passos de Primeiros Socorros Imediatos | |
2. Instruções de Cuidados Domiciliares | |
3. Dicas de Prevenção | |
4. Sinais de Alerta (quando procurar atendimento de emergência) | |
Formate sua resposta em seções claras com espaçamento adequado. Use linguagem simples, | |
não técnica, que o público em geral possa entender.""" | |
try: | |
print(f"📡 Enviando solicitação de API para {wound_type}...") | |
response = requests.post( | |
OPENROUTER_API_URL, | |
headers=headers, | |
json={ | |
"model": MODEL_NAME, | |
"messages": [{"role": "user", "content": prompt}], | |
"temperature": 0.5 | |
}, | |
timeout=20 | |
) | |
response.raise_for_status() | |
result = response.json() | |
print("🔧 Resposta bruta da API:", json.dumps(result, indent=2)) | |
if not result.get("choices"): | |
return "⚠️ Formato de resposta da API inesperado" | |
return result["choices"][0]["message"]["content"] | |
except Exception as e: | |
return f"⚠️ Diretrizes indisponíveis: {str(e)}" | |
# ================== PREDIÇÃO PRINCIPAL ================== | |
def predict(image, description): | |
"""Pipeline completo de predição""" | |
try: | |
# Pré-processar imagem | |
processed_img = preprocess_image(image) | |
input_tensor = np.expand_dims(processed_img, axis=0) | |
# Fazer predição | |
predictions = model.predict(input_tensor)[0] | |
sorted_indices = np.argsort(predictions)[::-1] # Ordem decrescente | |
# Formatando resultados | |
results = { | |
CLASS_LABELS[i]: float(predictions[i]) | |
for i in sorted_indices[:3] # Top 3 predições | |
} | |
top_class = CLASS_LABELS[sorted_indices[0]] | |
# Obter diretrizes | |
guidelines = get_medical_guidelines(top_class) | |
# Gerar gráfico de barras | |
plot_predictions(results) | |
# Salvar resultados em PDF | |
save_results_to_pdf(results, guidelines, description) | |
return results, guidelines | |
except Exception as e: | |
return {f"🚨 Erro": str(e)}, "" | |
def plot_predictions(results): | |
"""Gerar gráfico de barras para as predições""" | |
labels = list(results.keys()) | |
values = list(results.values()) | |
plt.figure(figsize=(10, 6)) | |
plt.barh(labels, values, color='skyblue') | |
plt.xlabel('Probabilidade') | |
plt.title('Probabilidades das Classes Preditas') | |
plt.gca().invert_yaxis() | |
plt.savefig('predictions.png') | |
plt.close() | |
def save_results_to_pdf(results, guidelines, description): | |
"""Salvar resultados em um arquivo PDF""" | |
pdf = FPDF() | |
pdf.add_page() | |
# Adicionar título | |
pdf.set_font("Arial", size=16) | |
pdf.cell(200, 10, txt="Relatório de Análise de Ferida", ln=True, align='C') | |
# Adicionar descrição | |
pdf.set_font("Arial", size=12) | |
pdf.multi_cell(200, 10, txt=f"Descrição: {description}") | |
# Adicionar resultados | |
pdf.cell(200, 10, txt="Resultados da Análise:", ln=True) | |
for label, prob in results.items(): | |
pdf.cell(200, 10, txt=f"{label}: {prob:.2f}", ln=True) | |
# Adicionar diretrizes | |
pdf.cell(200, 10, txt="Diretrizes Médicas:", ln=True) | |
pdf.multi_cell(200, 10, txt=guidelines) | |
# Salvar PDF | |
pdf.output("analysis_report.pdf") | |
# ================== ESTILOS CSS ================== | |
custom_css = """ | |
.gradio-container { | |
font-family: 'Times New Roman', Times, serif !important; | |
} | |
.container { | |
background: rgba(255, 255, 255, 0.9); | |
border-radius: 20px; | |
padding: 2rem; | |
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); | |
backdrop-filter: blur(4px); | |
border: 1px solid rgba(255, 255, 255, 0.18); | |
margin: 1rem 0; | |
} | |
.title { | |
color: #2D3748; | |
text-align: center; | |
font-size: 2.5rem; | |
margin-bottom: 1rem; | |
} | |
.subtitle { | |
color: #4A5568; | |
text-align: center; | |
font-size: 1.2rem; | |
margin-bottom: 2rem; | |
} | |
.warning { | |
background-color: #FED7D7; | |
border-left: 4px solid #F56565; | |
padding: 1rem; | |
margin: 1rem 0; | |
border-radius: 8px; | |
} | |
.info-section { | |
background-color: #E6F6FF; | |
border-radius: 12px; | |
padding: 1.5rem; | |
margin: 1rem 0; | |
} | |
.guidelines-box { | |
background: #F7FAFC; | |
border-radius: 10px; | |
padding: 1rem; | |
margin-top: 1rem; | |
} | |
""" | |
# ================== INTERFACE GRADIO ================== | |
def create_interface(): | |
with gr.Blocks(css=custom_css, title="WoundWise AI") as demo: | |
# Logo e Introdução | |
with gr.Column(elem_classes="container"): | |
gr.Image("logo.png", show_label=False, container=False) | |
gr.Markdown("# Bem-vindo ao WoundWise AI") | |
gr.Markdown(""" | |
No mundo acelerado de hoje, a detecção precoce de condições médicas pode ser um divisor de águas. | |
O WoundWise AI é um sistema avançado de classificação de feridas baseado em IA, desenvolvido como parte | |
do EarlyMed, uma iniciativa de estudantes do Vellore Institute of Technology. Nossa missão | |
é simples, mas impactante: "Detecção Precoce, Decisão Inteligente." | |
Utilizando deep learning, este sistema analisa imagens de feridas para fornecer classificações precisas | |
e diretrizes de tratamento essenciais. Seja um corte menor ou uma condição de pele grave, nossa IA ajuda a | |
identificar riscos potenciais, auxiliando os usuários a tomarem decisões informadas sobre a saúde em estágio inicial. | |
""") | |
# Interface Principal | |
with gr.Column(elem_classes="container"): | |
gr.Markdown("## 📸 Envie ou Capture a Imagem da Ferida") | |
gr.Markdown("Use a câmera do seu dispositivo ou envie uma imagem existente") | |
file_input = gr.Image(type="pil", label="Enviar Imagem da Ferida") | |
description_input = gr.Textbox(label="Descrição Adicional da Ferida", lines=2) | |
submit_btn = gr.Button("Analisar Agora", variant="primary") | |
# Exemplos de Imagens | |
gr.Examples( | |
examples=["abrasion.jpg", "burn.png", "bruise.png", "chicken-pox.png", "cut.png"], | |
inputs=file_input, | |
label="Exemplos de Imagens" | |
) | |
output_label = gr.Label(label="Resultados da Análise", num_top_classes=3) | |
output_guidelines = gr.Textbox( | |
label="Diretrizes Médicas", | |
lines=12, | |
elem_classes="guidelines-box" | |
) | |
output_plot = gr.Image(label="Gráfico de Probabilidades", type="plot") | |
# Por que Cuidar das Feridas | |
with gr.Column(elem_classes="info-section"): | |
gr.Markdown(""" | |
## ⚠️ Por que o Cuidado com Feridas é Importante | |
Ignorar feridas pode levar a complicações sérias: | |
- Risco de infecção bacteriana | |
- Cicatrização lenta e formação de cicatrizes | |
- Desenvolvimento de feridas crônicas | |
- Problemas de saúde sistêmicos | |
- Aumento dos custos médicos | |
A intervenção precoce e o cuidado adequado são cruciais para a cicatrização ideal e a prevenção de complicações. | |
""") | |
# Como Funciona Nosso Modelo | |
with gr.Column(elem_classes="info-section"): | |
gr.Markdown(""" | |
## 🔬 Nossa Tecnologia | |
O WoundWise AI utiliza um modelo de deep learning de ponta baseado na arquitetura GoogLeNet, | |
treinado com milhares de imagens médicas. O sistema: | |
1. Analisa imagens de feridas usando visão computacional avançada | |
2. Identifica 18 tipos diferentes de feridas e condições de pele | |
3. Fornece classificação em tempo real com pontuações de confiança | |
4. Gera diretrizes médicas usando IA avançada | |
Nosso modelo alcança alta precisão por meio de treinamento e validação extensivos por | |
profissionais médicos. | |
""") | |
# Aviso Médico | |
with gr.Column(elem_classes="warning"): | |
gr.Markdown(""" | |
## ⚕️ Aviso Médico | |
Este sistema de IA é projetado para auxiliar na avaliação preliminar de feridas. Ele não é | |
um substituto para o conselho médico profissional, diagnóstico ou tratamento. Sempre procure | |
o conselho de profissionais de saúde qualificados para qualquer dúvida sobre sua condição médica. Se você acredita que sua ferida é grave ou ameaça a vida, | |
procure atendimento médico imediato. | |
""") | |
# Conectar entrada ao processamento | |
submit_btn.click( | |
fn=predict, | |
inputs=[file_input, description_input], | |
outputs=[output_label, output_guidelines, output_plot] | |
) | |
return demo | |
if __name__ == "__main__": | |
iface = create_interface() | |
iface.launch( | |
server_name="0.0.0.0", | |
server_port=7860, | |
share=True | |
) | |