File size: 1,524 Bytes
e2f2323
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import torch
import torch.nn.functional as F
import numpy as np

MOLD_HIGH = 0.85
MOLD_LOW  = 0.50
BIO_TH    = 0.70
UNCERT_TH = 0.15
PATCH_TH  = 0.50
DINO_TH   = 0.75

def enable_dropout(model):
    for m in model.modules():
        if m.__class__.__name__.startswith("Dropout"):
            m.train()

def mc_uncertainty(model, img_tensor, mold_idx, T=15):
    enable_dropout(model)
    probs = []
    for _ in range(T):
        out = model(img_tensor.unsqueeze(0))
        cp = F.softmax(out["class"],1)[0]
        probs.append(cp[mold_idx].item())
    model.eval()
    return float(np.mean(probs)), float(np.std(probs))

def patch_consistency(model, image, transform, mold_idx, device, stride=112):
    w,h = image.size
    votes = []
    for y in range(0, h-224+1, stride):
        for x in range(0, w-224+1, stride):
            patch = image.crop((x,y,x+224,y+224))
            pt = transform(patch).unsqueeze(0).to(device)
            with torch.no_grad():
                out = model(pt)
                cp = F.softmax(out["class"],1)[0]
            votes.append(cp[mold_idx].item())
    return float(np.mean(np.array(votes) > 0.7)) if votes else 0.0

def final_decision_v2(
    mold_p, bio_p, uncert, patch_ratio, dino_sim
):
    if (
        mold_p > MOLD_HIGH and
        bio_p > BIO_TH and
        uncert < UNCERT_TH and
        patch_ratio > PATCH_TH and
        dino_sim > DINO_TH
    ):
        return "Mold"

    if mold_p > MOLD_LOW and bio_p > BIO_TH:
        return "Possible Mold"

    return "Not Mold"