smishr-18 commited on
Commit
fac7fdf
·
verified ·
1 Parent(s): da51680

Upload 5 files

Browse files
Files changed (5) hide show
  1. Dockerfile +13 -0
  2. app.py +66 -0
  3. best_model.pth +3 -0
  4. requirements.txt +10 -0
  5. unet.py +102 -0
Dockerfile ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # lightweight python
2
+ FROM python:3.11
3
+
4
+
5
+ # Copy local code to the container image.
6
+ WORKDIR /app
7
+ COPY . /app
8
+
9
+ # Install dependencies
10
+ RUN pip install -r requirements.txt
11
+ EXPOSE 8051
12
+ # Run the streamlit on container startup
13
+ CMD ["streamlit", "run", "app.py"]
app.py CHANGED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from unet import UNet
2
+ import streamlit as st
3
+ import torch
4
+ from torchvision import transforms
5
+ import albumentations as A
6
+ from albumentations.pytorch import ToTensorV2
7
+ from PIL import Image
8
+ import numpy as np
9
+
10
+ device = 'cuda' if torch.cuda.is_available() else 'cpu'
11
+ model = UNet(3, 1, [64, 128, 256, 512]).to(device)
12
+ model.load_state_dict(torch.load("best_model.pth", map_location=torch.device(device)))
13
+ # Set up transformations for the input image
14
+
15
+
16
+ transform = A.Compose([
17
+ A.Resize(224, 224, p=1.0),
18
+ ToTensorV2(),
19
+ ])
20
+ # Streamlit app
21
+ def main():
22
+ st.title("MRI segmenation App")
23
+
24
+ # Upload image through Streamlit
25
+ uploaded_image = st.file_uploader("Choose an image...", type=["jpg", "jpeg", "png"])
26
+
27
+ if uploaded_image is not None:
28
+ # Display the uploaded and processed images side by side
29
+ col1, col2 = st.columns(2) # Using beta_columns for side-by-side layout
30
+
31
+ # Display the uploaded image in the first column
32
+ col1.header("Original Image")
33
+ col1.image(uploaded_image, caption="Uploaded Image", use_column_width=True)
34
+
35
+ # Process the image (replace this with your processing logic)
36
+ processed_image = generate_image(uploaded_image)
37
+
38
+ # Display the processed image in the second column
39
+ col2.header("Processed Image")
40
+ col2.image(processed_image, caption="Processed Image", use_column_width=True)
41
+
42
+ # Function to generate an image using the PyTorch model
43
+ def generate_image(uploaded_image):
44
+ # Load the uploaded image
45
+ input_image = Image.open(uploaded_image)
46
+
47
+ image = np.array(input_image).astype(np.float32) / 255.
48
+ # Apply transformations
49
+ input_tensor = transform(image=image)["image"].unsqueeze(0)
50
+
51
+ # Generate an image using the PyTorch model
52
+ with torch.no_grad():
53
+ input_tensor = input_tensor.type(torch.FloatTensor).to(device)
54
+ pred = model(input_tensor)
55
+ pred = torch.sigmoid(pred)
56
+ mask = (pred > 0.6).float()
57
+ mask = mask[0].permute(1, 2, 0)
58
+ image = input_tensor[0].permute(1, 2, 0)
59
+
60
+ mask = image + mask*0.3
61
+ mask = mask.permute(2, 0, 1)
62
+ mask = transforms.ToPILImage()(mask)
63
+ return mask
64
+
65
+ if __name__ == "__main__":
66
+ main()
best_model.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:80bca9fca6dd62bb74e5072bcac8a4e2d232d43b6f45e0202bf6d5a353cd2b70
3
+ size 124203732
requirements.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ # Core Libraries
2
+ numpy>=1.21.0
3
+
4
+ pillow>=9.3.0
5
+
6
+ # Web Application Framework
7
+ streamlit>=1.28.0
8
+ torch>=2.1.2
9
+ torchvision>=0.16.2
10
+ albumentations>=1.3.1
unet.py ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+
4
+ class DownSampling(nn.Module):
5
+
6
+ def __init__(self, in_channels, out_channels, max_pool):
7
+ """
8
+ DownSampling block in the U-Net architecture.
9
+
10
+ Args:
11
+ in_channels (int): Number of input channels.
12
+ out_channels (int): Number of output channels.
13
+ max_pool (bool): Whether to use max pooling.
14
+ """
15
+ super(DownSampling, self).__init__()
16
+ self.max_pool = max_pool
17
+ self.conv1 = nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=3, stride=1, padding=1)
18
+ self.conv2 = nn.Conv2d(in_channels=out_channels, out_channels=out_channels, kernel_size=3, stride=1, padding=1)
19
+ self.batchnorm2d = nn.BatchNorm2d(out_channels)
20
+ self.relu = nn.ReLU()
21
+ self.maxpool2d = nn.MaxPool2d(kernel_size=2, stride=2)
22
+
23
+ def forward(self, x):
24
+ x = self.conv1(x)
25
+ x = self.conv2(x)
26
+
27
+ x = self.relu(self.batchnorm2d(x))
28
+ skip_connection = x
29
+
30
+ if self.max_pool:
31
+ next_layer = self.maxpool2d(x)
32
+ else:
33
+ return x
34
+ return next_layer, skip_connection
35
+
36
+ class UpSampling(nn.Module):
37
+ def __init__(self, in_channels, out_channels):
38
+ """
39
+ UpSampling block in the U-Net architecture.
40
+
41
+ Args:
42
+ in_channels (int): Number of input channels.
43
+ out_channels (int): Number of output channels.
44
+ """
45
+ super(UpSampling, self).__init__()
46
+ self.up = nn.ConvTranspose2d(in_channels, out_channels=out_channels, kernel_size=2, stride=2)
47
+ self.conv1 = nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=3, stride=1, padding=1)
48
+ self.relu = nn.ReLU()
49
+ self.conv2 = nn.Conv2d(in_channels=out_channels, out_channels=out_channels, kernel_size=3, stride=1, padding=1)
50
+ self.batchnorm = nn.BatchNorm2d(out_channels)
51
+
52
+ def forward(self, x, prev_skip):
53
+ x = self.up(x)
54
+ x = torch.cat((x, prev_skip), dim=1)
55
+ x = self.conv1(x)
56
+ x = self.conv2(x)
57
+ next_layer = self.relu(self.batchnorm(x))
58
+ return next_layer
59
+
60
+ class UNet(nn.Module):
61
+
62
+ """
63
+ U-Net architecture.
64
+
65
+ Args:
66
+ in_channels (int): Number of input channels.
67
+ out_channels (int): Number of output channels.
68
+ features (list): List of feature sizes for downsampling and upsampling.
69
+ """
70
+ def __init__(self, in_channels, out_channels, features):
71
+ super(UNet, self).__init__()
72
+ self.ups = nn.ModuleList()
73
+ self.downs = nn.ModuleList()
74
+
75
+ for feature in features:
76
+ self.downs.append(DownSampling(in_channels, feature, True))
77
+ in_channels = feature
78
+
79
+ for feature in reversed(features):
80
+ self.ups.append(UpSampling(2 * feature, feature))
81
+
82
+ self.bottleneck = DownSampling(features[-1], 2 * features[-1], False)
83
+ self.final_conv = nn.Conv2d(features[0], out_channels, kernel_size=1)
84
+
85
+ def forward(self, x):
86
+ skip_connections = []
87
+ for down in self.downs:
88
+ x, skip_connection = down(x)
89
+ skip_connections.append(skip_connection)
90
+ skip_connections = skip_connections[::-1]
91
+ x = self.bottleneck(x)
92
+ for i, up in enumerate(self.ups):
93
+ x = up(x, skip_connections[i])
94
+
95
+ return self.final_conv(x)
96
+
97
+ if __name__ == "__main__":
98
+ #Example Usage
99
+ device = 'cuda' if torch.cuda.is_available() else 'cpu'
100
+ features = [64, 128, 256, 512]
101
+ model = UNet(1, 1, features=features).to(device)
102
+ print(model(torch.rand(1, 1, 512, 512)).shape)