Search code examples
pythonpython-3.xrgbniftinibabel

How to correctly convert RGB images into nifty format?


I have RGB images which I'm loading as a numpy array. I would like to convert these images into the nifty format, which I can open using ITK-SNAP (http://www.itksnap.org/pmwiki/pmwiki.php).

Here is what I have tried to do:

import nibabel as nib 
import numpy as np

x = load_jpg_image(filename='input.jpg')  # --> x is a numpy array containing the RGB image with shape (128, 128, 3) 
img = nib.Nifti1Image(x, eye(4)) 
nib.save(img, filename='output.nii')

However, ITK-SNAP interprets output.nii as a 3D grayscale volume rather than an RGB image. To me, it seems that ITK-SNAP should be able to handle RGB data (see this); however, I don't understand how I should save img to make this possible. I'm using ITK-SNAP 3.6.0.


Solution

  • It seems you can create RGB images by casting them in a custom dtype:

    import nibabel as nib 
    import numpy as np
    
    RGB_DTYPE = np.dtype([('R', 'u1'), ('G', 'u1'), ('B', 'u1')])
    
    x = load_jpg_image(filename='input.jpg')  # --> x is a numpy array containing the RGB image with shape (128, 128, 3) 
    
    # cast to custom type:
    x = x.copy().view(dtype=RGB_DTYPE)  # copy used to force fresh internal structure
    
    img = nib.Nifti1Image(x, eye(4)) 
    nib.save(img, filename='output.nii')
    

    ITK-SNAP can handle this type of image by right-clicking the image name on the left panel and selecting the option: Multi-Component Display -> RGB.