|
a |
|
b/Preprocessing Medical Data Pipeline/MSKMulticlass.py |
|
|
1 |
import numpy as np |
|
|
2 |
import nibabel as nib |
|
|
3 |
import matplotlib.pyplot as plt |
|
|
4 |
import os |
|
|
5 |
from image_preprocessing import uniform_resizing |
|
|
6 |
|
|
|
7 |
def CreateMasks4MulticlassMSK(input_scan_dir, scan_dir, directory, mask_index, TIBIA_encoding, FEMUR_encoding, FIBULA_encoding, PELVIS_encoding, output_dir, AOIThresholding, FriedLanderDataset): |
|
|
8 |
aoi_fnames = os.listdir(directory) |
|
|
9 |
resizing_size = 256 |
|
|
10 |
print('Regions of Interest for Segmentation: ', aoi_fnames) |
|
|
11 |
|
|
|
12 |
fnames = [] |
|
|
13 |
for aoi_fname in aoi_fnames: |
|
|
14 |
directory_aoi = (directory + ('/{}').format(aoi_fname)) |
|
|
15 |
aoi_fname = os.listdir(directory_aoi) |
|
|
16 |
aoi_fname = sorted(aoi_fname) |
|
|
17 |
fnames.append(aoi_fname) |
|
|
18 |
|
|
|
19 |
n_segmentation_classes = len(fnames) |
|
|
20 |
print('Number of Segmentation Classes: ', n_segmentation_classes) |
|
|
21 |
|
|
|
22 |
|
|
|
23 |
|
|
|
24 |
suffix_index_dict = {} |
|
|
25 |
for idx, file_list in enumerate(fnames): |
|
|
26 |
for filename in file_list: |
|
|
27 |
# Extract the suffix index from the filename |
|
|
28 |
parts = filename.split('_') |
|
|
29 |
if len(parts) > 1: |
|
|
30 |
suffix_index = parts[1].split('.')[0] # Extracting the index before '.' |
|
|
31 |
suffix_index = int(suffix_index) # Convert index to integer |
|
|
32 |
# Add the filename to the corresponding list in the dictionary |
|
|
33 |
if suffix_index in suffix_index_dict: |
|
|
34 |
suffix_index_dict[suffix_index].append(filename) |
|
|
35 |
else: |
|
|
36 |
suffix_index_dict[suffix_index] = [filename] |
|
|
37 |
|
|
|
38 |
# for index, filenames in suffix_index_dict.items(): |
|
|
39 |
# print(f"Segmentation Mask {index}: {filenames}") |
|
|
40 |
|
|
|
41 |
combined_mask = None |
|
|
42 |
for fname_mask in suffix_index_dict[mask_index]: |
|
|
43 |
print(fname_mask) |
|
|
44 |
mask = nib.load(('{}/{}/{}').format(directory, (fname_mask.split('_'))[0], fname_mask)) |
|
|
45 |
mask_data = mask.get_fdata().astype(np.uint8) |
|
|
46 |
aoi = (fname_mask.split('_'))[0] |
|
|
47 |
|
|
|
48 |
if (FriedLanderDataset == True): |
|
|
49 |
mask_data = np.expand_dims(mask_data, axis = -1) |
|
|
50 |
mask_data = mask_data.transpose(1, 0, 2, 3) |
|
|
51 |
print(('Unprocessed {} Mask Shape: {}').format(aoi, mask_data.shape)) |
|
|
52 |
mask_data = uniform_resizing(mask_data, resizing_size) |
|
|
53 |
|
|
|
54 |
|
|
|
55 |
if (aoi == 'TIBIA'): |
|
|
56 |
mask_data = np.where(mask_data != 0, TIBIA_encoding, 0) |
|
|
57 |
if (aoi == 'FEMUR'): |
|
|
58 |
mask_data = np.where(mask_data != 0, FEMUR_encoding, 0) |
|
|
59 |
if (aoi == 'FIBULA'): |
|
|
60 |
mask_data = np.where(mask_data != 0, FIBULA_encoding, 0) |
|
|
61 |
if (aoi == 'PELVIS'): |
|
|
62 |
mask_data = np.where(mask_data != 0, PELVIS_encoding, 0) |
|
|
63 |
if combined_mask is None: |
|
|
64 |
combined_mask = mask_data |
|
|
65 |
else: |
|
|
66 |
combined_mask += mask_data # Combine the pixel arrays by adding them element-wise |
|
|
67 |
combined_mask = np.array(combined_mask) |
|
|
68 |
combined_mask[combined_mask > n_segmentation_classes] = 0 |
|
|
69 |
|
|
|
70 |
if (AOIThresholding == True): |
|
|
71 |
threshold = 0 |
|
|
72 |
|
|
|
73 |
combined_mask = np.array(combined_mask) |
|
|
74 |
indices = np.transpose(np.nonzero(combined_mask != 0)) |
|
|
75 |
if indices.size > 0: |
|
|
76 |
first_non_zero_index_2d = tuple(indices[0]) |
|
|
77 |
else: |
|
|
78 |
first_non_zero_index_2d = None |
|
|
79 |
|
|
|
80 |
if indices.size > 0: |
|
|
81 |
last_non_zero_index_2d = tuple(indices[-1]) |
|
|
82 |
else: |
|
|
83 |
last_non_zero_index_2d = None |
|
|
84 |
|
|
|
85 |
|
|
|
86 |
print(first_non_zero_index_2d) |
|
|
87 |
print(last_non_zero_index_2d) |
|
|
88 |
first_slice_aoi = (first_non_zero_index_2d[0]) - int(threshold) |
|
|
89 |
last_slice_aoi = (last_non_zero_index_2d[0]) + int(threshold) |
|
|
90 |
print("AOI Slice Start (Final with Thresholding): ", first_slice_aoi) |
|
|
91 |
print("AOI Slice End (Final with Thresholding): ", last_slice_aoi) |
|
|
92 |
|
|
|
93 |
mask_index = '{:03d}'.format(mask_index) |
|
|
94 |
combined_mask = combined_mask[first_slice_aoi:last_slice_aoi, :, :, :] |
|
|
95 |
scan = nib.load(('{}/msk_{}.nii.gz').format(input_scan_dir, mask_index)) |
|
|
96 |
scan_data = scan.get_fdata() |
|
|
97 |
# scan_og = nib.Nifti1Image(scan_data, scan.affine) |
|
|
98 |
# nib.save(scan_og, ('{}/msk_{}_og.nii.gz').format(output_dir, mask_index)) |
|
|
99 |
|
|
|
100 |
if (FriedLanderDataset == True): |
|
|
101 |
scan_data = np.expand_dims(scan_data, axis = -1) |
|
|
102 |
scan_data = scan_data.transpose(1, 0, 2, 3) |
|
|
103 |
print('Unprocessed Scan Shape: ', scan_data.shape) |
|
|
104 |
scan_data = uniform_resizing(scan_data, resizing_size) |
|
|
105 |
scan_data = scan_data.astype('float32') |
|
|
106 |
scan_data /= np.max(scan_data) # scale scans to [0, 1] |
|
|
107 |
print('Max Pixel Value in Scan: ', np.max(scan_data)) |
|
|
108 |
|
|
|
109 |
scan_data = scan_data[first_slice_aoi:last_slice_aoi, :, :, :] |
|
|
110 |
print('Final Training Scans Input Shape: ', scan_data.shape) |
|
|
111 |
print('Final Training Masks Input Shape: ', combined_mask.shape) |
|
|
112 |
|
|
|
113 |
# np.savetxt('output.txt', scan_data[100,:,:,0], fmt="%d", delimiter=",") |
|
|
114 |
combined_mask = combined_mask.astype(int) |
|
|
115 |
combined_img = nib.Nifti1Image(combined_mask, mask.affine) |
|
|
116 |
print('Multi-class Labels: ', np.unique(combined_mask)) |
|
|
117 |
nib.save(combined_img, ('{}/msk_{}.nii.gz').format(output_dir, mask_index)) |
|
|
118 |
|
|
|
119 |
combined_img = nib.Nifti1Image(scan_data, scan.affine) |
|
|
120 |
nib.save(combined_img, ('{}/msk_{}.nii.gz').format(scan_dir, mask_index)) |
|
|
121 |
|
|
|
122 |
print(('MSK Multiclass Mask Made Using {}, Saved To {}, and Region of Interest Slice Thresholding = {} !').format(aoi_fnames, ('{}/msk_{}.nii.gz').format(output_dir, mask_index), AOIThresholding)) |
|
|
123 |
print('\n') |