1. 程式人生 > >[Python] Python 旋轉、flip Nifti三維資料 (Python Rotate and Flip Nifti volume)

[Python] Python 旋轉、flip Nifti三維資料 (Python Rotate and Flip Nifti volume)

  1. __author__ = 'xin yang'
  2. import os  
  3. import nibabel as nib  
  4. import numpy as np  
  5. import math  
  6. src_us_folder = 'G:/Temp/Data/src/us'
  7. src_seg_folder = 'G:/Temp/Data/src/seg'
  8. aug_us_folder = 'G:/Temp/Data/aug/us'
  9. aug_seg_folder = 'G:/Temp/Data/aug/seg'
  10. img_n= 10
  11. rotate_theta = np.array([0, math.pi/2])  
  12. # augmentation
  13. aug_cnt = 0
  14. for
     k in range(img_n):  
  15.     src_us_file = os.path.join(src_us_folder, (str(k) + '.nii'))  
  16.     src_seg_file = os.path.join(src_seg_folder, (str(k) + '_seg.nii'))  
  17.     # load .nii files
  18.     src_us_vol = nib.load(src_us_file)  
  19.     src_seg_vol = nib.load(src_seg_file)  
  20.     # volume data
  21.     us_vol_data = src_us_vol.get_data()  
  22.     us_vol_data = (np.array(us_vol_data)).astype('uint8')  
  23.     seg_vol_data = src_seg_vol.get_data()  
  24.     seg_vol_data = (np.array(seg_vol_data)).astype('uint8')  
  25.     # get refer affine matrix
  26.     ref_affine = src_us_vol.affine  
  27.     ############### flip volume ###############
  28.     flip_us_vol = np.fliplr(us_vol_data)  
  29.     flip_seg_vol = np.fliplr(seg_vol_data)  
  30.     # construct new volumes
  31.     new_us_vol = nib.Nifti1Image(flip_us_vol, ref_affine)  
  32.     new_seg_vol = nib.Nifti1Image(flip_seg_vol, ref_affine)  
  33.     # save
  34.     aug_us_file = os.path.join(aug_us_folder, (str(aug_cnt) + '.nii'))  
  35.     aug_seg_file = os.path.join(aug_seg_folder, (str(aug_cnt) + '_seg.nii'))  
  36.     nib.save(new_us_vol, aug_us_file)  
  37.     nib.save(new_seg_vol, aug_seg_file)  
  38.     aug_cnt = aug_cnt + 1
  39.     ############### rotate volume ###############
  40.     for t in range(len(rotate_theta)):  
  41.         print'rotating %d theta of %d volume...' % (t, k)  
  42.         cos_gamma = np.cos(t)  
  43.         sin_gamma = np.sin(t)  
  44.         rot_affine = np.array([[1000],  
  45.                                [0, cos_gamma, -sin_gamma, 0],  
  46.                                [0, sin_gamma, cos_gamma, 0],  
  47.                                [0001]])  
  48.         new_affine = rot_affine.dot(ref_affine)  
  49.         # construct new volumes
  50.         new_us_vol = nib.Nifti1Image(us_vol_data, new_affine)  
  51.         new_seg_vol = nib.Nifti1Image(seg_vol_data, new_affine)  
  52.         # save
  53.         aug_us_file = os.path.join(aug_us_folder, (str(aug_cnt) + '.nii'))  
  54.         aug_seg_file = os.path.join(aug_seg_folder, (str(aug_cnt) + '_seg.nii'))  
  55.         nib.save(new_us_vol, aug_us_file)  
  56.         nib.save(new_seg_vol, aug_seg_file)  
  57.         aug_cnt = aug_cnt + 1

[Note]

This NiBabel toolbox based rotation only changes the affine matrix information in the header, that is, the volume data is not affected. When you use ITK-Snap to load the .nii file, the data will be transformed according to the affine matrix. That means, the transformation is done by the ITK-Snap software.

This kind of transformation can't be recognised by Nifti toolbox in Matlab, when you use 'load_nii' function to load the file generated above. You will encounter the problem like:

'Non-orthogonal rotation or shearing found inside the affine matrix in this NIfTI file.'

You need to really 'reslice' the volume data under the affine matrix, as the following code shows:

  1. rot_nii_path = 'G:\Temp\Data\aug\0.nii';  
  2. res_rot_nii_path = 'G:\Temp\Data\aug\0_res.nii';  
  3. reslice_nii(rot_nii_path, res_rot_nii_path, [], [], [], 2);  
You can refer to the source file of Nifti toolbox in Matlab for the parameter setting of 'reslice_nii' function. You should pay attention to the last parameter for interpolation. 'Nearest' and 'Linear' will generate different data types.