XRayModelV5 / app.py
JobenTan's picture
Update app.py
3804cb1 verified
Raw
History Blame Contribute Delete
2.9 kB
import torch
import gradio as gr
from PIL import Image
import numpy as np
from torchvision.models import densenet121, DenseNet121_Weights
import albumentations as A
from albumentations.pytorch import ToTensorV2
from torchvision import transforms
import segmentation_models_pytorch as smp
import torch.nn as nn
import cv2
import matplotlib.cm as cm
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# Segmentation Model
m1 = smp.Unet(
encoder_name="resnet34",
encoder_weights=None,
in_channels=1,
classes=1
).to(device)
m1.load_state_dict(torch.load("weights/Segmentation_Model.pth", map_location=device))
m1.eval()
# Classification Model
m2 = densenet121(weights=None)
m2.classifier = nn.Linear(1024, 4)
m2.load_state_dict(torch.load("weights/Classification_Model.pth", map_location=device))
m2.eval().to(device)
# Transforms
unet_transform = A.Compose([
A.Resize(256, 256),
A.Normalize(mean=0.5, std=0.5),
ToTensorV2()
])
classifier_transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize(mean=0.41, std=0.16)
])
# Inference Function
def analyze(image):
# Grayscale image for UNet
image_gray = image.convert("L")
img_np = np.array(image_gray)
# UNet input
augmented = unet_transform(image=img_np)
unet_input = augmented["image"].unsqueeze(0).to(device)
# Segmentation
with torch.no_grad():
mask_pred = m1(unet_input)
mask_pred = torch.sigmoid(mask_pred)
mask = (mask_pred > 0.5).float().squeeze().cpu().numpy()
# Resize to match classifier input
resized_gray = image_gray.resize((224, 224), Image.BILINEAR)
mask_img = Image.fromarray((mask * 255).astype(np.uint8))
mask_resized = transforms.functional.resize(mask_img, [224, 224])
image_np = np.array(resized_gray).astype(np.float32)
mask_np = (np.array(mask_resized) > 127).astype(np.float32)
lung_image = image_np * mask_np
lung_image_3ch = np.stack([lung_image] * 3, axis=-1)
lung_image_3ch = np.clip(lung_image_3ch, 0, 255).astype(np.uint8)
lung_image_pil = Image.fromarray(lung_image_3ch)
input_tensor = classifier_transform(lung_image_pil).unsqueeze(0).to(device)
# Classification
with torch.no_grad():
logits = m2(input_tensor)
probs = torch.softmax(logits, dim=1)
confidence, pred_class = torch.max(probs, dim=1)
classes = ["COVID", "Lung_Opacity", "Normal", "Viral Pneumonia"]
confidence_percent = f"{confidence.item() * 100:.2f}%"
return classes[pred_class.item()], confidence_percent
# Gradio UI
interface = gr.Interface(
fn=analyze,
inputs=gr.Image(type="pil"),
outputs=[
gr.Text(label="Prediction"),
gr.Text(label="Confidence")],
title="Chest X-Ray Analysis",
description="Upload a chest X-ray to detect disease."
)
interface.launch()