darragh commited on
Commit
e6d2f8f
β€’
1 Parent(s): 40200b2
Files changed (4) hide show
  1. README.md +9 -4
  2. app.py +116 -0
  3. packages.txt +1 -0
  4. requirements.txt +12 -0
README.md CHANGED
@@ -1,8 +1,8 @@
1
  ---
2
  title: Swinunetr Dicom Video
3
- emoji: πŸ¦€
4
- colorFrom: green
5
- colorTo: indigo
6
  sdk: gradio
7
  sdk_version: 3.0.24
8
  app_file: app.py
@@ -10,4 +10,9 @@ pinned: false
10
  license: apache-2.0
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
1
  ---
2
  title: Swinunetr Dicom Video
3
+ emoji: πŸ“–πŸŽ¬
4
+ colorFrom: blue
5
+ colorTo: purple
6
  sdk: gradio
7
  sdk_version: 3.0.24
8
  app_file: app.py
 
10
  license: apache-2.0
11
  ---
12
 
13
+ This repository contains the code for UNETR: Transformers for 3D Medical Image Segmentation. UNETR is the first 3D segmentation network that uses a pure vision transformer as its encoder without relying on CNNs for feature extraction. The code presents a volumetric (3D) multi-organ segmentation application using the BTCV challenge dataset.
14
+
15
+ Check out the Beyond the Cranial Vault source Swin-UNET models [here](https://huggingface.co/darragh/swinunetr-btcv-small). Also in the link, you can see links to the original BTCV winning solution.
16
+
17
+ This is a small demo on a subset of the test data for the [BTCV competition](https://zenodo.org/record/1169361#.YtGvn-xKhb8).
18
+
app.py ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+ import os
3
+ import glob
4
+ import shutil
5
+ import torch
6
+ import argparse
7
+ import mediapy
8
+ import cv2
9
+ import numpy as np
10
+ import gradio as gr
11
+ from skimage import color, img_as_ubyte
12
+ from monai import transforms, data
13
+
14
+ os.system("git clone https://github.com/darraghdog/Project-MONAI-research-contributions pmrc")
15
+ sys.path.append("pmrc/SwinUNETR/BTCV")
16
+ from swinunetr import SwinUnetrModelForInference, SwinUnetrConfig
17
+
18
+
19
+ ffmpeg_path = shutil.which('ffmpeg')
20
+ mediapy.set_ffmpeg(ffmpeg_path)
21
+
22
+ # Load model
23
+ model = SwinUnetrModelForInference.from_pretrained('darragh/swinunetr-btcv-tiny')
24
+ model.eval()
25
+
26
+ # Pull files from github
27
+ input_files = glob.glob('pmrc/SwinUNETR/BTCV/dataset/imagesSampleTs/*.nii.gz')
28
+ input_files = dict((f.split('/')[-1], f) for f in input_files)
29
+
30
+ # Load and process dicom with monai transforms
31
+ test_transform = transforms.Compose(
32
+ [
33
+ transforms.LoadImaged(keys=["image"]),
34
+ transforms.AddChanneld(keys=["image"]),
35
+ transforms.Spacingd(keys="image",
36
+ pixdim=(1.5, 1.5, 2.0),
37
+ mode="bilinear"),
38
+ transforms.ScaleIntensityRanged(keys=["image"],
39
+ a_min=-175.0,
40
+ a_max=250.0,
41
+ b_min=0.0,
42
+ b_max=1.0,
43
+ clip=True),
44
+ # transforms.Resized(keys=["image"], spatial_size = (256,256,-1)),
45
+ transforms.ToTensord(keys=["image"]),
46
+ ])
47
+
48
+ # Create Data Loader
49
+ def create_dl(test_files):
50
+ ds = test_transform(test_files)
51
+ loader = data.DataLoader(ds,
52
+ batch_size=1,
53
+ shuffle=False)
54
+ return loader
55
+
56
+ # Inference and video generation
57
+ def generate_dicom_video(selected_file, n_frames):
58
+
59
+ # Data processor
60
+ test_file = input_files[selected_file]
61
+ test_files = [{'image': test_file}]
62
+ dl = create_dl(test_files)
63
+ batch = next(iter(dl))
64
+
65
+ # Select dicom slices
66
+ tst_inputs = batch["image"]
67
+ tst_inputs = tst_inputs[:,:,:,:,-n_frames:]
68
+
69
+ # Inference
70
+ with torch.no_grad():
71
+ outputs = model(tst_inputs,
72
+ (96,96,96),
73
+ 8,
74
+ overlap=0.5,
75
+ mode="gaussian")
76
+ tst_outputs = torch.softmax(outputs.logits, 1)
77
+ tst_outputs = torch.argmax(tst_outputs, axis=1)
78
+
79
+ # Write frames to video
80
+ for inp, outp in zip(tst_inputs, tst_outputs):
81
+ frames = []
82
+ for idx in range(inp.shape[-1]):
83
+ # Segmentation
84
+ seg = outp[:,:,idx].numpy().astype(np.uint8)
85
+ # Input dicom frame
86
+ img = (inp[0,:,:,idx]*255).numpy().astype(np.uint8)
87
+ img = cv2.cvtColor(img,cv2.COLOR_GRAY2RGB)
88
+ frame = color.label2rgb(seg,img, bg_label = 0)
89
+ frame = img_as_ubyte(frame)
90
+ frame = np.concatenate((img, frame), 1)
91
+ frames.append(frame)
92
+ mediapy.write_video("dicom.mp4", frames, fps=4)
93
+
94
+ return 'dicom.mp4'
95
+
96
+
97
+ theme = 'dark-peach'
98
+ with gr.Blocks(theme=theme) as demo:
99
+
100
+ gr.Markdown('''<center><h1>SwinUnetr BTCV</h1></center>
101
+ This is a Gradio Blocks app of the winning transformer in the Beyond the Cranial Vault (BTCV) Segmentation Challenge, <a href="https://github.com/darraghdog/Project-MONAI-research-contributions/tree/main/SwinUNETR/BTCV">SwinUnetr</a> (tiny version).
102
+ ''')
103
+ selected_dicom_key = gr.inputs.Dropdown(
104
+ choices=sorted(input_files),
105
+ type="value",
106
+ label="Select a dicom file")
107
+ n_frames = gr.Slider(1, 100, value=32, label="Choose the number of dicom slices to process", step = 1)
108
+ button_gen_video = gr.Button("Generate Video")
109
+ output_interpolation = gr.Video(label="Generated Video")
110
+ button_gen_video.click(fn=generate_dicom_video,
111
+ inputs=[selected_dicom_key, n_frames],
112
+ outputs=output_interpolation)
113
+
114
+ demo.launch(debug=True, enable_queue=True)
115
+
116
+
packages.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ ffmpeg
requirements.txt ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ transformers==4.20.1
2
+ torch==1.10.0
3
+
4
+ git+https://github.com/Project-MONAI/MONAI#egg.gitmonai@0.8.1+271.g07de215c
5
+ nibabel==3.1.1
6
+ tqdm==4.59.0
7
+ einops==0.4.1
8
+ tensorboardX==2.1
9
+ scipy==1.5.0
10
+ mediapy==1.0.3
11
+ scikit-image==0.17.2
12
+ opencv-python==4.6.0.66