66import nibabel as nib
77from typing import Tuple , List
88from PIL import Image
9+ import SimpleITK as sitk
910
1011
1112def 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
6061def 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 :
0 commit comments