您的位置:首页 > 编程语言 > Python开发

[Python] Python 旋转、flip Nifti三维数据 (Python Rotate and Flip Nifti volume)

2017-01-18 23:08 951 查看
__author__ = 'xin yang'

import os
import nibabel as nib
import numpy as np
import math

src_us_folder = 'G:/Temp/Data/src/us'
src_seg_folder = 'G:/Temp/Data/src/seg'

aug_us_folder = 'G:/Temp/Data/aug/us'
aug_seg_folder = 'G:/Temp/Data/aug/seg'

img_n= 10
rotate_theta = np.array([0, math.pi/2])

# augmentation
aug_cnt = 0
for k in range(img_n):
src_us_file = os.path.join(src_us_folder, (str(k) + '.nii'))
src_seg_file = os.path.join(src_seg_folder, (str(k) + '_seg.nii'))
# load .nii files
src_us_vol = nib.load(src_us_file)
src_seg_vol = nib.load(src_seg_file)
# volume data
us_vol_data = src_us_vol.get_data()
us_vol_data = (np.array(us_vol_data)).astype('uint8')
seg_vol_data = src_seg_vol.get_data()
seg_vol_data = (np.array(seg_vol_data)).astype('uint8')
# get refer affine matrix
ref_affine = src_us_vol.affine

############### flip volume ###############
flip_us_vol = np.fliplr(us_vol_data)
flip_seg_vol = np.fliplr(seg_vol_data)
# construct new volumes
new_us_vol = nib.Nifti1Image(flip_us_vol, ref_affine)
new_seg_vol = nib.Nifti1Image(flip_seg_vol, ref_affine)
# save
aug_us_file = os.path.join(aug_us_folder, (str(aug_cnt) + '.nii'))
aug_seg_file = os.path.join(aug_seg_folder, (str(aug_cnt) + '_seg.nii'))
nib.save(new_us_vol, aug_us_file)
nib.save(new_seg_vol, aug_seg_file)

aug_cnt = aug_cnt + 1

############### rotate volume ###############
for t in range(len(rotate_theta)):
print 'rotating %d theta of %d volume...' % (t, k)
cos_gamma = np.cos(t)
sin_gamma = np.sin(t)
rot_affine = np.array([[1, 0, 0, 0],
[0, cos_gamma, -sin_gamma, 0],
[0, sin_gamma, cos_gamma, 0],
[0, 0, 0, 1]])
new_affine = rot_affine.dot(ref_affine)
# construct new volumes
new_us_vol = nib.Nifti1Image(us_vol_data, new_affine)
new_seg_vol = nib.Nifti1Image(seg_vol_data, new_affine)
# save
aug_us_file = os.path.join(aug_us_folder, (str(aug_cnt) + '.nii'))
aug_seg_file = os.path.join(aug_seg_folder, (str(aug_cnt) + '_seg.nii'))
nib.save(new_us_vol, aug_us_file)
nib.save(new_seg_vol, aug_seg_file)

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:

rot_nii_path = 'G:\Temp\Data\aug\0.nii';
res_rot_nii_path = 'G:\Temp\Data\aug\0_res.nii';
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.

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: