def __call__(self, filename): """ Args: filename (str, list, tuple, file): path file or file-like object or a list of files. """ filename = ensure_tuple(filename) img_array = list() compatible_meta = dict() for name in filename: img = nib.load(name) img = correct_nifti_header_if_necessary(img) header = dict(img.header) header["filename_or_obj"] = name header["affine"] = img.affine header["original_affine"] = img.affine.copy() header["as_closest_canonical"] = self.as_closest_canonical ndim = img.header["dim"][0] spatial_rank = min(ndim, 3) header["spatial_shape"] = img.header["dim"][1:spatial_rank + 1] if self.as_closest_canonical: img = nib.as_closest_canonical(img) header["affine"] = img.affine img_array.append(np.array(img.get_fdata(dtype=self.dtype))) img.uncache() if self.image_only: continue if not compatible_meta: for meta_key in header: meta_datum = header[meta_key] # pytype: disable=attribute-error if (type(meta_datum).__name__ == "ndarray" and np_str_obj_array_pattern.search( meta_datum.dtype.str) is not None): continue # pytype: enable=attribute-error compatible_meta[meta_key] = meta_datum else: assert np.allclose( header["affine"], compatible_meta["affine"] ), "affine data of all images should be same." img_array = np.stack(img_array, axis=0) if len(img_array) > 1 else img_array[0] if self.image_only: return img_array return img_array, compatible_meta
def load_nifti(filename_or_obj, as_closest_canonical=False, image_only=True, dtype=None): """ Loads a Nifti file from the given path or file-like object. Args: filename_or_obj (str or file): path to file or file-like object as_closest_canonical (bool): if True, load the image as closest to canonical axis format image_only (bool): if True return only the image volume, other return image volume and header dict dtype (np.dtype, optional): if not None convert the loaded image to this data type Returns: The loaded image volume if `image_only` is True, or a tuple containing the volume and the Nifti header in dict format otherwise Note: header['original_affine'] stores the original affine loaded from `filename_or_obj`. header['affine'] stores the affine after the optional `as_closest_canonical` transform. """ img = nib.load(filename_or_obj) img = correct_nifti_header_if_necessary(img) header = dict(img.header) header['filename_or_obj'] = filename_or_obj header['original_affine'] = img.affine header['affine'] = img.affine header['as_closest_canonical'] = as_closest_canonical if as_closest_canonical: img = nib.as_closest_canonical(img) header['affine'] = img.affine if dtype is not None: dat = img.get_fdata(dtype=dtype) else: dat = np.asanyarray(img.dataobj) if image_only: return dat return dat, header
def read(self, data: Union[Sequence[str], str, Any]): """ Read image data from specified file or files, or set a Nibabel Image object. Note that the returned object is Nibabel image object or list of Nibabel image objects. `self._img` is always a list, even only has 1 image. Args: data: file name or a list of file names to read. """ self._img = list() if isinstance(data, Nifti1Image): self._img.append(data) return data filenames: Sequence[str] = ensure_tuple(data) for name in filenames: img = nib.load(name, **self.kwargs) img = correct_nifti_header_if_necessary(img) self._img.append(img) return self._img if len(filenames) > 1 else self._img[0]
def read(self, data: Union[Sequence[str], str], **kwargs): """ Read image data from specified file or files. Note that the returned object is Nibabel image object or list of Nibabel image objects. Args: data: file name or a list of file names to read. kwargs: additional args for `nibabel.load` API, will override `self.kwargs` for existing keys. More details about available args: https://github.com/nipy/nibabel/blob/master/nibabel/loadsave.py """ img_: List[Nifti1Image] = list() filenames: Sequence[str] = ensure_tuple(data) kwargs_ = self.kwargs.copy() kwargs_.update(kwargs) for name in filenames: img = nib.load(name, **kwargs_) img = correct_nifti_header_if_necessary(img) img_.append(img) return img_ if len(filenames) > 1 else img_[0]
def read(self, data: Union[Sequence[str], str, Nifti1Image], **kwargs): """ Read image data from specified file or files, or set a Nibabel Image object. Note that the returned object is Nibabel image object or list of Nibabel image objects. `self._img` is always a list, even only has 1 image. Args: data: file name or a list of file names to read. kwargs: additional args for `nibabel.load` API. more details about available args: https://github.com/nipy/nibabel/blob/master/nibabel/loadsave.py """ self._img = list() if isinstance(data, Nifti1Image): self._img.append(data) return data filenames: Sequence[str] = ensure_tuple(data) for name in filenames: img = nib.load(name, **kwargs) img = correct_nifti_header_if_necessary(img) self._img.append(img) return self._img if len(filenames) > 1 else self._img[0]
def test_affine(self): test_img = nib.Nifti1Image(np.zeros((1, 2, 3)), np.eye(4) * 20.) test_img = correct_nifti_header_if_necessary(test_img) np.testing.assert_allclose( test_img.affine, np.array([[20., 0., 0., 0.], [0., 20., 0., 0.], [0., 0., 20., 0.], [0., 0., 0., 20.]]))
def test_correct(self): test_img = nib.Nifti1Image(np.zeros((1, 2, 3)), np.eye(4)) test_img.header.set_zooms((100, 100, 100)) test_img = correct_nifti_header_if_necessary(test_img) np.testing.assert_allclose( test_img.affine, np.array([[100., 0., 0., 0.], [0., 100., 0., 0.], [0., 0., 100., 0.], [0., 0., 0., 1.]]))