Spaces:
Running
on
Zero
Running
on
Zero
FrancescoLR
commited on
Update app.py
Browse files
app.py
CHANGED
@@ -8,7 +8,7 @@ import nibabel as nib
|
|
8 |
import matplotlib.pyplot as plt
|
9 |
import spaces # Import spaces for GPU decoration
|
10 |
import numpy as np
|
11 |
-
from scipy.ndimage import center_of_mass
|
12 |
|
13 |
# Define paths
|
14 |
MODEL_DIR = "./model" # Local directory to store the downloaded model
|
@@ -27,18 +27,50 @@ def download_model():
|
|
27 |
zip_path = hf_hub_download(repo_id=REPO_ID, filename="Dataset004_WML.zip", cache_dir=MODEL_DIR)
|
28 |
subprocess.run(["unzip", "-o", zip_path, "-d", MODEL_DIR])
|
29 |
print("Dataset004_WML downloaded and extracted.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
def extract_middle_slices(nifti_path, output_image_path, slice_size=180):
|
32 |
"""
|
33 |
Extracts slices centered around the center of mass of non-zero voxels in a 3D NIfTI image.
|
34 |
The slices are taken along axial, coronal, and sagittal planes and saved as a single PNG.
|
35 |
"""
|
36 |
-
# Load NIfTI image
|
37 |
img = nib.load(nifti_path)
|
38 |
data = img.get_fdata()
|
|
|
|
|
|
|
|
|
39 |
|
40 |
# Compute the center of mass of non-zero voxels
|
41 |
-
com = center_of_mass(
|
42 |
center = np.round(com).astype(int)
|
43 |
|
44 |
# Define half the slice size
|
@@ -67,9 +99,9 @@ def extract_middle_slices(nifti_path, output_image_path, slice_size=180):
|
|
67 |
return padded_slice
|
68 |
|
69 |
# Extract slices in axial, coronal, and sagittal planes
|
70 |
-
axial_slice = extract_2d_slice(
|
71 |
-
coronal_slice = extract_2d_slice(
|
72 |
-
sagittal_slice = extract_2d_slice(
|
73 |
|
74 |
# Apply rotations to each slice
|
75 |
axial_slice = np.rot90(axial_slice, k=-1) # 90 degrees clockwise
|
@@ -95,7 +127,7 @@ def extract_middle_slices(nifti_path, output_image_path, slice_size=180):
|
|
95 |
plt.tight_layout()
|
96 |
plt.savefig(output_image_path, bbox_inches="tight", pad_inches=0)
|
97 |
plt.close()
|
98 |
-
|
99 |
# Function to run nnUNet inference
|
100 |
@spaces.GPU # Decorate the function to allocate GPU for its execution
|
101 |
def run_nnunet_predict(nifti_file):
|
|
|
8 |
import matplotlib.pyplot as plt
|
9 |
import spaces # Import spaces for GPU decoration
|
10 |
import numpy as np
|
11 |
+
from scipy.ndimage import center_of_mass, zoom
|
12 |
|
13 |
# Define paths
|
14 |
MODEL_DIR = "./model" # Local directory to store the downloaded model
|
|
|
27 |
zip_path = hf_hub_download(repo_id=REPO_ID, filename="Dataset004_WML.zip", cache_dir=MODEL_DIR)
|
28 |
subprocess.run(["unzip", "-o", zip_path, "-d", MODEL_DIR])
|
29 |
print("Dataset004_WML downloaded and extracted.")
|
30 |
+
|
31 |
+
def resample_to_isotropic(data, affine, target_spacing=1.0):
|
32 |
+
"""
|
33 |
+
Resamples a 3D NIfTI image to isotropic voxel size.
|
34 |
+
|
35 |
+
Parameters:
|
36 |
+
data (numpy.ndarray): The input 3D image data.
|
37 |
+
affine (numpy.ndarray): The affine transformation matrix.
|
38 |
+
target_spacing (float): Desired isotropic voxel spacing (in mm).
|
39 |
+
|
40 |
+
Returns:
|
41 |
+
resampled_data (numpy.ndarray): Resampled image data.
|
42 |
+
resampled_affine (numpy.ndarray): Updated affine matrix.
|
43 |
+
"""
|
44 |
+
# Extract current voxel dimensions from the affine matrix
|
45 |
+
current_spacing = np.sqrt((affine[:3, :3] ** 2).sum(axis=0))
|
46 |
+
|
47 |
+
# Compute the scaling factors for resampling
|
48 |
+
scaling_factors = current_spacing / target_spacing
|
49 |
+
|
50 |
+
# Resample the data using zoom
|
51 |
+
resampled_data = zoom(data, zoom=scaling_factors, order=1) # Linear interpolation
|
52 |
|
53 |
+
# Update the affine matrix to reflect the new voxel dimensions
|
54 |
+
resampled_affine = affine.copy()
|
55 |
+
resampled_affine[:3, :3] /= scaling_factors[:, np.newaxis]
|
56 |
+
|
57 |
+
return resampled_data, resampled_affine
|
58 |
+
|
59 |
def extract_middle_slices(nifti_path, output_image_path, slice_size=180):
|
60 |
"""
|
61 |
Extracts slices centered around the center of mass of non-zero voxels in a 3D NIfTI image.
|
62 |
The slices are taken along axial, coronal, and sagittal planes and saved as a single PNG.
|
63 |
"""
|
64 |
+
# Load NIfTI image
|
65 |
img = nib.load(nifti_path)
|
66 |
data = img.get_fdata()
|
67 |
+
affine = img.affine
|
68 |
+
|
69 |
+
# Resample the image to 1 mm isotropic
|
70 |
+
resampled_data, _ = resample_to_isotropic(data, affine, target_spacing=1.0)
|
71 |
|
72 |
# Compute the center of mass of non-zero voxels
|
73 |
+
com = center_of_mass(resampled_data > 0)
|
74 |
center = np.round(com).astype(int)
|
75 |
|
76 |
# Define half the slice size
|
|
|
99 |
return padded_slice
|
100 |
|
101 |
# Extract slices in axial, coronal, and sagittal planes
|
102 |
+
axial_slice = extract_2d_slice(resampled_data, center, axis=2) # Axial (z-axis)
|
103 |
+
coronal_slice = extract_2d_slice(resampled_data, center, axis=1) # Coronal (y-axis)
|
104 |
+
sagittal_slice = extract_2d_slice(resampled_data, center, axis=0) # Sagittal (x-axis)
|
105 |
|
106 |
# Apply rotations to each slice
|
107 |
axial_slice = np.rot90(axial_slice, k=-1) # 90 degrees clockwise
|
|
|
127 |
plt.tight_layout()
|
128 |
plt.savefig(output_image_path, bbox_inches="tight", pad_inches=0)
|
129 |
plt.close()
|
130 |
+
|
131 |
# Function to run nnUNet inference
|
132 |
@spaces.GPU # Decorate the function to allocate GPU for its execution
|
133 |
def run_nnunet_predict(nifti_file):
|