####################################### Making and saving new images in nibabel ####################################### We often want to do some processing on an image, then save the processed image back to an image file on disk. When we load an image from disk, we get back an image object. When we load a NIfTI ``.nii`` image, we get an image object of type ``Nifti1Image``. .. nbplot:: >>> import numpy as np .. nbplot:: >>> import nibabel as nib >>> img = nib.load('ds114_sub009_highres.nii') >>> type(img) Maybe we were worried about some very high values in the image, and we wanted to clip them down to a more reasonable number: .. nbplot:: >>> data = img.get_data() >>> data.max() # doctest: +SKIP 3237.0 .. nbplot:: :include-source: false >>> assert data.max() == 3237.0 We might consider clipping the top 5 percent of voxel values: .. nbplot:: >>> data = img.get_data() >>> top_95_thresh = np.percentile(data, 95) >>> top_95_thresh 722.0 .. nbplot:: >>> new_data = data.copy() >>> new_data[new_data > top_95_thresh] = top_95_thresh >>> new_data.max() # doctest: +SKIP 722.0 .. nbplot:: :include-source: false >>> assert new_data.max() == 722.0 We can make a new ``Nifti1Image`` by constructing it directly. We pass the new data, the image affine, and (optionally) a template :doc:`header ` for the image: .. nbplot:: >>> clipped_img = nib.Nifti1Image(new_data, img.affine, img.header) >>> type(clipped_img) The ``nib.Nifti1Image`` call copies and adapts the passed header to the new image data shape, and affine. .. nbplot:: >>> # Show the original data array shape from the original header >>> img.header.get_data_shape() (256, 156, 256) .. nbplot:: >>> # Here we construct a new empty header >>> empty_header = nib.Nifti1Header() >>> empty_header.get_data_shape() (0,) If we make a new image with this header, the constructor routine fixes the header to have the correct shape for the data array: .. nbplot:: >>> another_img = nib.Nifti1Image(new_data, img.affine, empty_header) >>> another_img.header.get_data_shape() (256, 156, 256) We can save the new image with ``nib.save``: .. nbplot:: >>> nib.save(clipped_img, 'clipped_image.nii') This image has the clipped data: .. nbplot:: >>> clipped_back = nib.load('clipped_image.nii') >>> clipped_back.get_data().max() # doctest: +SKIP 722.0 .. nbplot:: :include-source: false >>> assert clipped_back.get_data().max() == 722.0