File size: 3,318 Bytes
22055af
 
 
 
 
 
 
 
3822931
 
 
22055af
 
 
3822931
22055af
3822931
22055af
3822931
22055af
 
 
 
 
 
 
 
 
 
 
3822931
22055af
 
3822931
22055af
 
 
 
3822931
22055af
 
 
3822931
22055af
 
 
 
 
 
 
 
 
 
 
 
 
 
3822931
22055af
 
 
 
 
 
 
 
 
 
3822931
22055af
 
 
3822931
22055af
3822931
22055af
3822931
 
 
 
22055af
3822931
22055af
 
 
3822931
 
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
try:
    import json
    import os
    import torch
    from PIL import Image
    from transformers import pipeline
except ImportError:
    pass

class PerdixAdniEngine:
    def __init__(self):
        print("[Perdix] Descargando Inteligencia Artificial desde Research Hub...")
        # Descargará el modelo pre-entrenado la primera vez
        self.classifier = pipeline("image-classification", model="prithivMLmods/Alzheimer-Stage-Classifier")
        
    def diagnose_patient(self, image_path: str, age: float, mmse_score: float, edu_years: float):
        """

        Analiza JPGs/PNGs del cerebro usando un Transformers preentrenado.

        """
        assert os.path.exists(image_path), f"CRÍTICO: No se puede localizar MRI en {image_path}"
        
        print(f"\n--- [Perdix Engine] Analizando Imagen ---")
        
        try:
            image = Image.open(image_path).convert("RGB")
            results = self.classifier(image)
        except Exception as e:
            return {"status": "error", "message": f"Falló leer la imagen con la IA: {e}"}
            
        print(f"Predicciones Crudas del Modelo Transformer: {results}")
        
        # El modelo 'prithivMLmods' suele retornar labels como:
        # 'Mild Demented', 'Moderate Demented', 'Non Demented', 'Very Mild Demented'
        
        # Mapeamos a nuestras 3 categorías:
        # Non Demented -> CN
        # Very Mild / Mild -> MCI
        # Moderate -> AD
        
        prob_ad = 0.0
        prob_mci = 0.0
        prob_cn = 0.0
        
        for res in results:
            label = res['label'].lower()
            score = res['score']
            
            if 'non' in label:
                prob_cn += score
            elif 'very mild' in label or 'mild' in label and 'moderate' not in label:
                prob_mci += score
            elif 'moderate' in label or 'severe' in label:
                prob_ad += score
            else:
                # Fallback genérico a AD si etiqueta es rara pero indica demencia
                if 'demented' in label:
                    prob_mci += score
        
        # Ajustamos los pesos finales basado levemente en la edad o MMR (Late Fusion manual simulado)
        # Esto es solo si el doctor proporcionó un MMSE muy definitorio
        if mmse_score < 20: 
            prob_ad += 0.15
        elif mmse_score > 28:
            prob_cn += 0.15
            
        total = prob_ad + prob_mci + prob_cn
        if total == 0:
            total = 1.0 # fallback
        
        prob_ad /= total
        prob_mci /= total
        prob_cn /= total
        
        probs = [prob_mci, prob_ad, prob_cn]
        classes = ["Deterioro Cognitivo Leve (MCI)", "Alzheimer Agudo (AD)", "Cognitivamente Sano (CN)"]
        winner_index = int(np.argmax(probs)) if 'np' in globals() else probs.index(max(probs))
        
        return {
            "status": "success",
            "prediction_class": classes[winner_index],
            "confidence_score": round(max(probs) * 100, 2),
            "breakdown": {
                "AD": round(prob_ad * 100, 2),
                "MCI": round(prob_mci * 100, 2),
                "CN": round(prob_cn * 100, 2)
            }
        }