import torch from transformers import ViTFeatureExtractor, ViTForImageClassification from PIL import Image import matplotlib.pyplot as plt import numpy as np import gradio as gr import io import base64 MODEL_NAME = "ahishamm/vit-base-HAM-10000-sharpened-patch-32" feature_extractor = ViTFeatureExtractor.from_pretrained(MODEL_NAME) model = ViTForImageClassification.from_pretrained(MODEL_NAME) model.eval() CLASSES = [ "Queratosis actínica / Bowen", # 0 "Carcinoma células basales", # 1 "Lesión queratósica benigna", # 2 "Dermatofibroma", # 3 "Melanoma maligno", # 4 "Nevus melanocítico", # 5 "Lesión vascular" # 6 ] RISK_LEVELS = { 0: {'level': 'Moderado', 'color': '#ffaa00', 'weight': 0.6}, 1: {'level': 'Alto', 'color': '#ff4444', 'weight': 0.8}, 2: {'level': 'Bajo', 'color': '#44ff44', 'weight': 0.1}, 3: {'level': 'Bajo', 'color': '#44ff44', 'weight': 0.1}, 4: {'level': 'Crítico', 'color': '#cc0000', 'weight': 1.0}, 5: {'level': 'Bajo', 'color': '#44ff44', 'weight': 0.1}, 6: {'level': 'Bajo', 'color': '#44ff44', 'weight': 0.1} } def analizar_lesion_vit_web(img): inputs = feature_extractor(img, return_tensors="pt") with torch.no_grad(): outputs = model(**inputs) probs = outputs.logits.softmax(dim=-1).cpu().numpy()[0] pred_idx = int(np.argmax(probs)) pred_clase = CLASSES[pred_idx] confianza = probs[pred_idx] cancer_risk_score = sum(probs[i] * RISK_LEVELS[i]['weight'] for i in range(7)) melanoma_risk = probs[4] bcc_risk = probs[1] precancer_risk = probs[0] benign_total = sum(probs[i] for i in [2,3,5,6]) colors_bars = [RISK_LEVELS[i]['color'] for i in range(7)] fig, ax = plt.subplots(figsize=(8,3)) ax.bar(CLASSES, probs*100, color=colors_bars) ax.set_title("Probabilidad por tipo de lesión") ax.set_ylabel("Probabilidad (%)") ax.set_xticklabels(CLASSES, rotation=45, ha='right') ax.grid(axis='y', alpha=0.2) plt.tight_layout() buf = io.BytesIO() plt.savefig(buf, format="png") plt.close(fig) buf.seek(0) img_bytes = buf.getvalue() img_b64 = base64.b64encode(img_bytes).decode("utf-8") html_chart = f'' urgency = "" recommendation = "" timeframe = "" if cancer_risk_score > 0.6: urgency = "🚨 CRÍTICO" recommendation = "Derivación INMEDIATA a oncología dermatológica" timeframe = "En 24-48 horas máximo" elif cancer_risk_score > 0.4: urgency = "⚠️ ALTO RIESGO" recommendation = "Consulta urgente con dermatólogo especialista" timeframe = "En 1 semana máximo" elif cancer_risk_score > 0.2: urgency = "📋 RIESGO MODERADO" recommendation = "Evaluación dermatológica programada" timeframe = "En 2-4 semanas" else: urgency = "✅ BAJO RIESGO" recommendation = "Seguimiento de rutina" timeframe = "En 3-6 meses" informe = f"""

🏥 INFORME DE ANÁLISIS DERMATOLÓGICO CON IA

📊 Diagnóstico principal: {pred_clase}
🎯 Confianza del modelo: {confianza:.1%}
📈 Score de riesgo oncológico: {cancer_risk_score:.1%}

⚠️ Análisis de riesgo detallado:
 🔴 Melanoma maligno: {melanoma_risk:.1%}
 🟠 Carcinoma células basales: {bcc_risk:.1%}
 🟡 Lesión pre-cancerosa: {precancer_risk:.1%}
 🟢 Lesiones benignas: {benign_total:.1%}

🩺 Evaluación clínica:
 {urgency}
 💡 Recomendación: {recommendation}
 ⏰ Plazo: {timeframe}

🔍 Características analizadas:
""" if melanoma_risk > 0.3: informe += "• ⚠️ Posibles irregularidades sugestivas de melanoma
• 🔍 Asimetría o variación de color detectada
" if bcc_risk > 0.25: informe += "• 🔍 Características compatibles con carcinoma basocelular
" if precancer_risk > 0.25: informe += "• 🔍 Posible queratosis actínica (lesión pre-maligna)
" if benign_total > 0.6: informe += "• ✅ Características predominantemente benignas
" informe += "
📊 Diagnósticos diferenciales (ordenados por probabilidad):" informe += """
📋 Información técnica:
• Modelo: ViT-Base (HAM10000, sharpened)
• Precisión validada: 83.7%
• Preprocesamiento: Optimizado para dermatoscopia
• Clases detectadas: 7 tipos de lesiones cutáneas

📝 Notas clínicas:
""" if confianza < 0.7: informe += "• ⚠️ Confianza moderada - considerar segunda opinión
" if cancer_risk_score > 0.3: informe += "• 🩺 Documentar evolución con fotografías seriadas
" informe += "• 📏 Regla ABCDE: Evaluar Asimetría, Bordes, Color, Diámetro, Evolución
" informe += """

⚕️ ADVERTENCIA MÉDICA
• Este análisis es una HERRAMIENTA DE APOYO diagnóstico.
• NO sustituye la evaluación clínica de un dermatólogo.
• Ante cualquier duda, consulte con un profesional médico.
• La decisión terapéutica final corresponde al médico tratante.
""" return informe, html_chart demo = gr.Interface( fn=analizar_lesion_vit_web, inputs=gr.Image(type="pil", label="Sube una imagen de la lesión"), outputs=[gr.HTML(label="Informe detallado"), gr.HTML(label="Gráfico de barras")], title="Detector de Cáncer de Piel IA (HAM10000, ViT)", description="Sube una imagen dermatológica y obtén un informe detallado generado por IA (ViT-HAM10000, accuracy ~83.7%)", flagging_mode="never" ) if __name__ == "__main__": demo.launch()