Search code examples
pythonmachine-learningimage-processingdeep-learningunet-neural-network

convert .nii to .tif using imwrite, it saves black image insted of the image


I want to convert .nii images to .tif to train my model using U-Net.

1-I looped through all images in the folder. 2-I looped through all slices within each image. 3-I saved each slice as .tif.

The training images are converted successfully. However, the labels (masks) are all saved as black images. I want to successfully convert those masks from .nii to .tif, but I don't know how. I read that it could be something with brightness, but I didn't get the idea clearly, so I couldn't solve the problem until now.

The only reason for this conversion is to be able to train my model. Feel free to suggest a better idea, if anyone can share a way to feed the network with the .nii format directly.

import nibabel as nib
import matplotlib.pyplot as plt    
import imageio
import numpy as np
import glob
import os
import nibabel as nib
import numpy as np
from tifffile import imsave
import tifffile as tiff

for filepath in glob.iglob('data/Task04_Hippocampus/labelsTr/*.nii.gz'):
    a = nib.load(filepath).get_fdata()  
    a = a.astype('int8')
    base = Path(filepath).stem
    base = re.sub('.nii', '', base)
    x,y,z = a.shape
    for i in range(0,z):
        newimage = a[:, :, i]
        imageio.imwrite('data/Task04_Hippocampus/masks/'+base+'_'+str(i)+'.tif', newimage)
    

Solution

  • Unless you absolutely have to use TIFF, I would strongly suggest using the NiFTI format for a number of important reasons:

    1. Image values are often not arbitrary. For example, in CT images the values correspond to x-ray attenuation (check out this Wikipedia page). TIFF, which is likely to scale the values in some way, is not suitable for this.

    2. NIfTI also contains a header which has crucial geometric information needed to correctly interpret the image, such as the resolution, slice thickness, and direction.

    You can directly extract a numpy.ndarray from NIfTI images using SimpleITK. Here is a code snippet:

    import SimpleITK as sitk
    import numpy as np
    
    img = sitk.ReadImage("your_image.nii")
    
    arr = sitk.GetArrayFromImage(img)
    
    slice_0 = arr[0,:,:] # this is a 2D axial slice as a np.ndarray
    

    As an aside: the reason the images where you stored your masks look black is because in NIfTI format labels have a value of 1 (and background is 0). If you directly convert to TIFF, a value of 1 is very close to black when interpreted as an RGB value - another reason to avoid TIFF!