[3DUNetMRI图像预处理2]综合4个模态+truth和设置的background像素值获取foreground,并裁剪

    xiaoxiao2021-04-15  375

    import numpy as np import os import nibabel as nib import matplotlib.pyplot as plt from nilearn.image.image import _crop_img_to as crop_img_to from nilearn.image.image import check_niimg from nilearn.image import new_img_like NII_DIR='./nii_dir' #显示其中的一个slice def read_nii_file(nii_path): nii_image=nib.load(nii_path) return nii_image #需要将data数组的前两个维度转置以便正常显示 def nii_one_slice(image): #W,H,C image_arr=image.get_data() print(type(image_arr)) #print(image_arr[125,160]) print(image_arr.shape) image_2d=image_arr[:,:,85].transpose((1,0)) plt.imshow(image_2d, cmap = 'gray') plt.show() nii_image=read_nii_file(os.path.join(NII_DIR,'Brats18_2013_2_1','Brats18_2013_2_1_flair.nii.gz')) #最大像素值和最小像素值 #0:background像素值 nii_arr=nii_image.get_data() print(np.max(nii_arr),np.min(nii_arr)) nii_one_slice(nii_image)

    输出:

    1252 0 <class 'numpy.ndarray'> (240, 240, 155)

    根据设定的background像素值,综合所有模态和truth,得到前景区域

    def get_foreground_from_set_of_files(set_of_files, background_value=0, tolerance=0.00001, return_image=False): #set_of_files:('sub1-T1.nii.gz', 'sub1-T2.nii.gz', 'sub1-flair.nii.gz','sub1-t1ce.nii.gz','sub1-truth.nii.gz') #image_file:sub1-T1.nii.gz for i, image_file in enumerate(set_of_files): #读取image无裁剪,无resize print(image_file) image = read_nii_file(image_file) #根据设置的background值,综合所有模态和truth将image data数组中foreground位置设为True is_foreground = np.logical_or(image.get_data() < (background_value - tolerance), image.get_data() > (background_value + tolerance)) if i == 0: foreground = np.zeros(is_foreground.shape, dtype=np.uint8) #将is_foreground位置像素值设置为1 foreground[is_foreground] = 1 #返回image if return_image: return new_img_like(image, foreground) #返回数组 else: return foreground set_of_files=(os.path.join(NII_DIR,'Brats18_2013_2_1',item) for item in ('Brats18_2013_2_1_flair.nii.gz','Brats18_2013_2_1_t1.nii.gz','Brats18_2013_2_1_t2.nii.gz','Brats18_2013_2_1_t1ce.nii.gz','Brats18_2013_2_1_seg.nii.gz')) nii_foreground=get_foreground_from_set_of_files(set_of_files,return_image=True) nii_one_slice(nii_foreground)

    输出:

    ./nii_dir\Brats18_2013_2_1\Brats18_2013_2_1_flair.nii.gz ./nii_dir\Brats18_2013_2_1\Brats18_2013_2_1_t1.nii.gz ./nii_dir\Brats18_2013_2_1\Brats18_2013_2_1_t2.nii.gz ./nii_dir\Brats18_2013_2_1\Brats18_2013_2_1_t1ce.nii.gz ./nii_dir\Brats18_2013_2_1\Brats18_2013_2_1_seg.nii.gz <class 'numpy.ndarray'> (240, 240, 155)

     得到裁剪的空间位置坐标范围

    def get_slice_index(img,rtol=1e-8): img = check_niimg(img) data = img.get_data() infinity_norm = max(-data.min(), data.max()) passes_threshold = np.logical_or(data < -rtol * infinity_norm, data > rtol * infinity_norm) ## if data.ndim == 4: #any:对数组axis=-1上做或运算 passes_threshold = np.any(passes_threshold, axis=-1) #np.where(condition):返回condition为Ture的索引,即坐标 coords = np.array(np.where(passes_threshold)) print(coords) #每个维度起始位置,终止位置 start = coords.min(axis=1) end = coords.max(axis=1) + 1 print(start,end) # start和end不超过image start = np.maximum(start - 1, 0) end = np.minimum(end + 1, data.shape[:3]) #每个维度裁剪的slice切片对象:class slice(start, stop[, step])裁剪范围 slices = [slice(s, e) for s, e in zip(start, end)] return slices #W,H,C crop = get_slice_index(nii_foreground) print(crop)

    输出:

    [[ 49 49 49 ... 190 190 190] [131 131 131 ... 153 153 153] [ 47 48 49 ... 42 43 44]] [49 41 14] [191 220 143] [slice(48, 192, None), slice(40, 221, None), slice(13, 144, None)]

     根据crop([slice(48, 192, None), slice(41, 221, None), slice(13, 143, None)])裁剪

    图像

    #根据每个维度裁剪的slice切片对象裁剪 nii_image_croped=crop_img_to(nii_image,crop,copy=True) #放射矩阵4*4 print(nii_image_croped.affine) nii_one_slice(nii_image_croped)

     输出:

    [[ -1. 0. 0. -48.] [ 0. -1. 0. 199.] [ 0. 0. 1. 13.] [ 0. 0. 0. 1.]] <class 'numpy.ndarray'> (144, 181, 131)


    最新回复(0)