Skip to content

Commit ba8262b

Browse files
dbougetdbouget
andauthored
Included support for other input types, but not fully tested yet (#11)
Co-authored-by: dbouget <david.bouget@sintef.no>
1 parent 329fbcc commit ba8262b

File tree

3 files changed

+61
-4
lines changed

3 files changed

+61
-4
lines changed

raidionicsval/Utils/io_converters.py

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import nibabel as nib
77
from typing import Tuple, List
88
from PIL import Image
9+
import SimpleITK as sitk
910

1011

1112
def get_fold_from_file(filename, fold_number):
@@ -58,6 +59,23 @@ def reload_optimal_validation_parameters(study_filename):
5859
return optimums['Detection threshold'], optimums['Dice threshold']
5960

6061
def open_image_file(input_filename: str) -> Tuple[np.ndarray, str, List]:
62+
"""
63+
Opens the input file and associated metadata, which should be compatible for 2D or 3D inputs.\n
64+
Currently supported format in 2D: *.tif, *.tiff, *.png\n
65+
Currently supported format in 3D: *.nii, *.nii.gz, *.nrrd, *.nhdr, *.mha, *.mhd
66+
@TODO. Not fully tested with SimpleITK as loader!
67+
68+
Parameters
69+
----------
70+
input_filename: str
71+
Location on disk where the image lies.
72+
73+
Return
74+
----------
75+
Tuple[np.ndarray, str, List]
76+
Loaded content as an array of the input image (np.ndarray), extension format (str), and metadata where the
77+
first element is the image affine matrix and second element is the image spacings as Tuple.
78+
"""
6179
ext = '.' + '.'.join(input_filename.split('.')[1:])
6280
input_array = None
6381
input_specifics = []
@@ -68,6 +86,14 @@ def open_image_file(input_filename: str) -> Tuple[np.ndarray, str, List]:
6886
input_ni = nib.four_to_three(input_ni)[0]
6987
input_array = input_ni.get_fdata()[:]
7088
input_specifics = [input_ni.affine, input_ni.header.get_zooms()]
89+
elif ext in [".nrrd", ".nhdr", ".mhd", ".mha"]:
90+
image_sitk = sitk.ReadImage(input_filename)
91+
input_array = sitk.GetArrayFromImage(image_sitk)
92+
tmp_affine = np.asarray(image_sitk.GetDirection()).reshape(3,3)
93+
affine = np.eye(4).astype('float32')
94+
affine[:3, :3] = tmp_affine
95+
spacings = image_sitk.GetSpacing()
96+
input_specifics = [affine, spacings]
7197
elif ext in [".tif", ".tiff", ".png"]:
7298
input_array = Image.open(input_filename)
7399
input_specifics = [np.eye(4, dtype=int), [1., 1.]]
@@ -77,11 +103,29 @@ def open_image_file(input_filename: str) -> Tuple[np.ndarray, str, List]:
77103
return input_array, ext, input_specifics
78104

79105

80-
def save_image_file(output_array, output_filename: str, specifics: List = None) -> None:
106+
def save_image_file(output_array: np.ndarray, output_filename: str, specifics: List = None) -> None:
107+
"""
108+
Saves an array on disk using the corresponding file format.
109+
110+
Parameters
111+
----------
112+
output_array: np.ndarray
113+
Array to write on disk.
114+
output_filename: str
115+
Location on disk where to save the array
116+
specifics: List
117+
Metadata including the image header corresponding to the array (e.g., affine matrix, spacings)
118+
119+
Returns
120+
--------
121+
None
122+
"""
81123
ext = '.'.join(output_filename.split('.')[1:])
82124

83125
if ext == ".nii" or ext == ".nii.gz":
84126
nib.save(nib.Nifti1Image(output_array, affine=specifics[0]), output_filename)
127+
elif ext in [".nrrd", ".nhdr", ".mhd", ".mha"]:
128+
sitk.WriteImage(sitk.GetImageFromArray(output_array), output_filename)
85129
elif ext in [".tif", ".tiff", ".png"]:
86130
Image.fromarray(output_array).save(output_filename)
87131
else:

raidionicsval/Validation/kfold_model_validation.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,23 @@ def __compute_metrics_for_fold(self, data_list, fold_number):
152152
continue
153153
return 0
154154

155-
def __identify_patient_files(self, patient_metrics, folder_index, fold_number):
155+
def __identify_patient_files(self, patient_metrics: PatientMetrics, folder_index: int, fold_number: int) -> bool:
156156
"""
157157
Asserts the existence of the raw files on disk for computing the metrics for the current patient.
158-
:return:
158+
159+
Parameters
160+
----------
161+
patient_metrics: PatientMetrics
162+
Object holding all computed metrics for the current patient
163+
folder_index: int
164+
Index value for the folder on disk to investigate
165+
fold_number: int
166+
Current fold number for looking into the correct folder on disk
167+
168+
Returns
169+
----------
170+
bool
171+
Boolean indicating whether all patient files were correctly identified or not.
159172
"""
160173
use_internal_convention = SharedResources.getInstance().validation_use_index_naming_convention
161174
uid = patient_metrics.patient_id

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
install_requires=required,
3030
include_package_data=True,
3131
python_requires=">=3.8",
32-
version='1.0.0',
32+
version='1.0.1',
3333
author='David Bouget (david.bouget@sintef.no)',
3434
license='BSD 2-Clause',
3535
description='Raidionics backend for running validation and metrics computation',

0 commit comments

Comments
 (0)