MIC-DKFZ / nnUNet

Apache License 2.0
5.9k stars 1.76k forks source link

How to convert preprocessed images into the nii.gz format for display? #1954

Closed TSbme closed 6 months ago

TSbme commented 9 months ago

How to convert preprocessed images into the nii.gz format for display?

Lars-Kraemer commented 9 months ago

Hey @tangqishi,

something like this should work:

import nibabel as nib
import numpy as np

# Input
npz_file = 'XXX.npz'
# Output
nii_img_file = 'YYYY.nii.gz'
nii_seg_file = 'YYYY_seg.nii.gz'

data = np.load(npz_file)
array = data["data"][0]
array_seg = data["seg"][0]

affine = np.eye(4)
nifti_img = nib.Nifti1Image(array, affine)
nifti_seg = nib.Nifti1Image(array_seg, affine)

nib.save(nifti_img, nii_img_file)
nib.save(nifti_seg, nii_seg_file)

Best Lars

TSbme commented 9 months ago

Thanks Lars!

TSbme commented 9 months ago

What's the difference between "nnUNetData_plans_v2.1_2D_stage0" and "nnUNetData_plans_v2.1_stage0"? Also, I revised some contents according to your answer, but the direction of the results looks terrible, how to solve the problems?

Here is the code: import numpy as np import nibabel as nib import os import pickle

def process_and_save(npz_folder, pkl_folder, output_folder):

if not os.path.exists(output_folder):
    os.makedirs(output_folder)

for npz_file in os.listdir(npz_folder):
    if npz_file.endswith('.npz'):
        base_name = npz_file[:-4]  
        npz_file_path = os.path.join(npz_folder, npz_file)
        pkl_file_path = os.path.join(pkl_folder, base_name + '.pkl')

        data = np.load(npz_file_path)
        image_data = data['data']
        seg_data = image_data[-1,:,:,:]  
        modalities_data = image_data[:-1,:,:,:]  

        if os.path.exists(pkl_file_path):
            with open(pkl_file_path, 'rb') as f:
                extra_info = pickle.load(f)
            affine = np.eye(4) 
        else:
            affine = np.eye(4)

        modalities = ['FLAIR', 'T1w', 't1gd', 'T2w']

        for i, modality in enumerate(modalities):
            if i < modalities_data.shape[0]:  
                nifti_img = nib.Nifti1Image(modalities_data[i], affine)
                nii_img_file = os.path.join(output_folder, f"{base_name}_{modality}.nii.gz")
                nib.save(nifti_img, nii_img_file)

        nifti_seg = nib.Nifti1Image(seg_data, affine)
        nii_seg_file = os.path.join(output_folder, f"{base_name}_seg.nii.gz")
        nib.save(nifti_seg, nii_seg_file)

folders = [ ("./Task001_BrainTumour/nnUNetData_plans_v2.1_2D_stage0", "./out1"), ("./Task001_BrainTumour/nnUNetData_plans_v2.1_stage0", "./out2") ]

for npz_folder, output_folder in folders: pkl_folder = npz_folder
process_and_save(npz_folder, pkl_folder, output_folder)

Here is the original image:

2001765cdb95080421cc8bd290f38da

Here is the image after preprocessing:

cbf9f57ee9b0d02929b608b95e3938c
TSbme commented 9 months ago

@Lars-Kraemer

Lars-Kraemer commented 8 months ago

Hey @tangqishi,

nibabel saves the data in a different axes ordering, you can use sitk instead:

import SimpleITK as sitk
...
nifti_img = sitk.GetImageFromArray(modalities_data[i])
sitk.WriteImage(nifti_img, nii_img_file)
...
nifti_seg = sitk.GetImageFromArray(seg_data.astype(np.uint8))
sitk.WriteImage(nifti_seg, nii_seg_file)

Regarding your second question: "nnUNetData_plans_v2.1_2D_stage0" -> preprocessed data for training a 2d model "nnUNetData_plans_v2.1_stage0" -> preprocessed data for training a 3d model

Best, Lars