JobenTan commited on
Commit
e822203
·
verified ·
1 Parent(s): 0c4f9b9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +62 -44
app.py CHANGED
@@ -13,6 +13,16 @@ import segmentation_models_pytorch as smp
13
  from torchvision.models import densenet121, DenseNet121_Weights
14
  import gradio as gr
15
  import os
 
 
 
 
 
 
 
 
 
 
16
 
17
  # Device
18
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
@@ -22,67 +32,75 @@ app = FastAPI()
22
 
23
  # ================== MODEL DEFINITIONS ==================
24
 
25
- class UNet(nn.Module):
26
- def __init__(self):
27
- super().__init__()
28
- self.model = smp.Unet(
29
- encoder_name="resnet34",
30
- encoder_weights="imagenet",
31
- in_channels=1,
32
- classes=1
33
- )
34
-
35
- def forward(self, x):
36
- return self.model(x)
37
-
38
- class MyClassifier(nn.Module):
39
- def __init__(self, num_classes=4):
40
- super().__init__()
41
- base_model = densenet121(weights=DenseNet121_Weights.IMAGENET1K_V1)
42
- in_features = base_model.classifier.in_features
43
- base_model.classifier = nn.Linear(in_features, num_classes)
44
- self.model = base_model
45
-
46
- def forward(self, x):
47
- return self.model(x)
48
-
49
- # ================== LOAD MODELS ==================
50
- m1 = UNet()
51
- m1.model.load_state_dict(torch.load("weights/Segmentation_Model.pth", map_location=device))
52
- m1.to(device).eval()
53
-
54
- m2 = MyClassifier()
55
- m2.load_state_dict(torch.load("weights/Classification_Model.pth", map_location=device))
56
  m2.eval().to(device)
57
 
58
  classes = ["COVID", "Lung_Opacity", "Normal", "Viral Pneumonia"]
59
 
60
- # ================== INFERENCE FUNCTION ==================
 
 
 
 
61
 
 
 
 
 
 
 
 
62
  def analyze(image):
 
63
  image_gray = image.convert("L")
64
- image_tensor = transforms.ToTensor()(image_gray).unsqueeze(0).to(device)
 
 
 
 
65
 
 
66
  with torch.no_grad():
67
- mask = m1(image_tensor).sigmoid()
68
- mask = (mask > 0.5).float()
69
- masked = image_tensor * mask
70
 
71
- masked_rgb = masked.squeeze(0).repeat(3, 1, 1)
 
 
 
 
 
72
 
73
- transform = transforms.Compose([
74
- transforms.Resize((224, 224)),
75
- transforms.Normalize(mean=[0.41]*3, std=[0.16]*3)
76
- ])
77
 
78
- processed = transform(masked_rgb).unsqueeze(0).to(device)
79
 
 
80
  with torch.no_grad():
81
- logits = m2(processed)
82
  probs = torch.softmax(logits, dim=1)
83
  confidence, pred_class = torch.max(probs, dim=1)
84
 
85
- return classes[pred_class.item()], f"{confidence.item() * 100:.2f}%"
 
 
 
86
 
87
  # ================== GRADIO INTERFACE ==================
88
 
 
13
  from torchvision.models import densenet121, DenseNet121_Weights
14
  import gradio as gr
15
  import os
16
+ import torch
17
+ import gradio as gr
18
+ from PIL import Image
19
+ import numpy as np
20
+ import albumentations as A
21
+ from albumentations.pytorch import ToTensorV2
22
+ from torchvision import transforms
23
+ import torch.nn as nn
24
+ import cv2
25
+ import matplotlib.cm as cm
26
 
27
  # Device
28
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
 
32
 
33
  # ================== MODEL DEFINITIONS ==================
34
 
35
+ m1 = smp.Unet(
36
+ encoder_name="resnet34",
37
+ encoder_weights="imagenet",
38
+ in_channels=1,
39
+ classes=1
40
+ ).to(device)
41
+ m1.load_state_dict(torch.load("Segmentation_Model.pth", map_location=device))
42
+ m1.eval()
43
+
44
+ # Classification Model
45
+ m2 = densenet121(weights=DenseNet121_Weights.IMAGENET1K_V1)
46
+ m2.classifier = nn.Linear(1024, 4)
47
+ m2.load_state_dict(torch.load("Classification_Model.pth", map_location=device))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  m2.eval().to(device)
49
 
50
  classes = ["COVID", "Lung_Opacity", "Normal", "Viral Pneumonia"]
51
 
52
+ unet_transform = A.Compose([
53
+ A.Resize(256, 256),
54
+ A.Normalize(mean=0.5, std=0.5),
55
+ ToTensorV2()
56
+ ])
57
 
58
+ classifier_transform = transforms.Compose([
59
+ transforms.Resize((224, 224)),
60
+ transforms.ToTensor(),
61
+ transforms.Normalize(mean=0.41, std=0.16)
62
+ ])
63
+
64
+ # Inference Function
65
  def analyze(image):
66
+ # Grayscale image for UNet
67
  image_gray = image.convert("L")
68
+ img_np = np.array(image_gray)
69
+
70
+ # UNet input
71
+ augmented = unet_transform(image=img_np)
72
+ unet_input = augmented["image"].unsqueeze(0).to(device)
73
 
74
+ # Segmentation
75
  with torch.no_grad():
76
+ mask_pred = m1(unet_input)
77
+ mask_pred = torch.sigmoid(mask_pred)
78
+ mask = (mask_pred > 0.5).float().squeeze().cpu().numpy()
79
 
80
+ # Resize to match classifier input
81
+ resized_gray = image_gray.resize((224, 224), Image.BILINEAR)
82
+ mask_img = Image.fromarray((mask * 255).astype(np.uint8))
83
+ mask_resized = transforms.functional.resize(mask_img, [224, 224])
84
+ image_np = np.array(resized_gray).astype(np.float32)
85
+ mask_np = (np.array(mask_resized) > 127).astype(np.float32)
86
 
87
+ lung_image = image_np * mask_np
88
+ lung_image_3ch = np.stack([lung_image] * 3, axis=-1)
89
+ lung_image_3ch = np.clip(lung_image_3ch, 0, 255).astype(np.uint8)
90
+ lung_image_pil = Image.fromarray(lung_image_3ch)
91
 
92
+ input_tensor = classifier_transform(lung_image_pil).unsqueeze(0).to(device)
93
 
94
+ # Classification
95
  with torch.no_grad():
96
+ logits = m2(input_tensor)
97
  probs = torch.softmax(logits, dim=1)
98
  confidence, pred_class = torch.max(probs, dim=1)
99
 
100
+ classes = ["COVID", "Lung_Opacity", "Normal", "Viral Pneumonia"]
101
+ confidence_percent = f"{confidence.item() * 100:.2f}%"
102
+
103
+ return classes[pred_class.item()], confidence_percent
104
 
105
  # ================== GRADIO INTERFACE ==================
106