对医学3d图像进行小块切割

from scipy import ndimage
import numpy as np
import SimpleITK as sitk
import nibabel as nib
import matplotlib.pyplot as plt
import os


MIN_BOUND = -1000.0
MAX_BOUND = -500

def norm_img_func(image): # 归一化像素值到(0,1)之间,且将溢出值取边界值
    image = (image - MIN_BOUND) / (MAX_BOUND - MIN_BOUND)
    image[image > 1] = 1.
    image[image < 0] = 0.
    return image

class Resize3D:
    def __init__(self, target_size=[32,256,256], model='constant',order=1):
        self.model = model
        self.order=order

        if isinstance(target_size, list) or isinstance(target_size, tuple):
            if len(target_size) != 3:
                raise ValueError(
                    '`target_size` should include 3 elements, but it is {}'.
                    format(target_size))

        else:
            raise TypeError(
                "Type of `target_size` is invalid. It should be list or tuple, but it is {}"
                .format(type(target_size)))

        self.target_size = target_size

    def __call__(self, im, label=None):
        if not isinstance(im, np.ndarray):
            raise TypeError("Resize: image type is not numpy.")
        if len(im.shape) != 3:
            raise ValueError('Resize: image is not 3-dimensional.')
        if im.ndim == 3:
            desired_depth = depth = self.target_size[2] # 深度
            desired_width = width = self.target_size[1]
            desired_height = height = self.target_size[0]

            current_depth = im.shape[2] # 深度
            current_width = im.shape[1]
            current_height = im.shape[0]

            depth = current_depth / desired_depth
            width = current_width / desired_width
            height = current_height / desired_height
            depth_factor = 1 / depth
            width_factor = 1 / width
            height_factor = 1 / height

            im = ndimage.zoom(im, (height_factor,width_factor,depth_factor), order=self.order,mode=self.model)
            if label is not None:
                label = ndimage.zoom(label, (depth_factor,width_factor, height_factor), order=0,mode='nearest', cval=0.0)

        else:
            # 通道方面错误,需要修改
            channels = [ndimage.zoom(im[c], (depth_factor,width_factor, height_factor), order=self.order,mode=self.model) for c
                        in range(im.shape[0])]
            im = np.stack(channels, axis=0)
            if label is not None:
                channels = [ndimage.zoom(label[c], label, (depth_factor,width_factor, height_factor), order=0,mode='nearest', cval=0.0) for c
                        in range(label.shape[0])]
                label = np.stack(channels, axis=0)

        if label is None:
            return im
        else:
            return (im, label)


if __name__ == '__main__':
    image_path = "D:/airway_datasets/train_image_nii/CASE01.nii.gz"
    filename = os.path.basename(image_path).split('.')[0]
    print(filename) # CASE01

    func = nib.load(image_path)
    img2 = np.array(func.get_fdata())
    print(f'原始图像的shape: {img2.shape}')

    h,w,d = img2.shape
    maxiter = np.max([h,w,d]) // 128
    resolution = (maxiter+1)*128
    print(resolution)
    # print(f'd维还剩{d-maxiter*128}')
    # img0 = img2[0:128,0:128,0:128]
    # print(img0.shape)

    # plt.imshow(img2[:,:,0],cmap='gray')
    # plt.show()

    # 1. 先将三维图像resize到resolution
    img_resize = Resize3D([resolution,resolution,resolution])(img2)
    print(f'resize之后的shape: ',img_resize.shape)

    # # 2. 保存看一下
    # new_image = nib.Nifti1Image(img_resize,func.affine)
    # nib.save(new_image,'out_01.nii')

    # 2. 对resize之后的图像进行切割
    cnt = 0
    for i in range(maxiter+1):
        for j in range(maxiter+1):
            for k in range(maxiter+1):
        # 0-128,0-128,0-128
        # 128-256
        # ...
        # 512-640
                imgt = img_resize[i*128:(i+1)*128,j*128:(j+1)*128,k*128:(k+1)*128]
                new_image = nib.Nifti1Image(imgt,func.affine)
                nib.save(new_image,f'case01/{filename}_{cnt:03}.nii')
                print(f'save {cnt:03} done.')
                cnt +=1

CASE01
原始图像的shape: (512, 512, 587)
640
resize之后的shape:  (640, 640, 640)
save 000 done.
save 001 done.
save 002 done.
save 003 done.
save 004 done.
save 005 done.
save 006 done.
save 007 done.
save 008 done.
save 009 done.
save 010 done.
save 011 done.
save 012 done.
save 013 done.
save 014 done.
save 015 done.
save 016 done.
save 017 done.
save 018 done.
save 019 done.
save 020 done.
save 021 done.
save 022 done.
save 023 done.
save 024 done.
save 025 done.
save 026 done.
save 027 done.
save 028 done.
save 029 done.
save 030 done.
save 031 done.
save 032 done.
save 033 done.
save 034 done.
save 035 done.
save 036 done.
save 037 done.
save 038 done.
save 039 done.
save 040 done.
save 041 done.
save 042 done.
save 043 done.
save 044 done.
save 045 done.
save 046 done.
save 047 done.
save 048 done.
save 049 done.
save 050 done.
save 051 done.
save 052 done.
save 053 done.
save 054 done.
save 055 done.
save 056 done.
save 057 done.
save 058 done.
save 059 done.
save 060 done.
save 061 done.
save 062 done.
save 063 done.
save 064 done.
save 065 done.
save 066 done.
save 067 done.
save 068 done.
save 069 done.
save 070 done.
save 071 done.
save 072 done.
save 073 done.
save 074 done.
save 075 done.
save 076 done.
save 077 done.
save 078 done.
save 079 done.
save 080 done.
save 081 done.
save 082 done.
save 083 done.
save 084 done.
save 085 done.
save 086 done.
save 087 done.
save 088 done.
save 089 done.
save 090 done.
save 091 done.
save 092 done.
save 093 done.
save 094 done.
save 095 done.
save 096 done.
save 097 done.
save 098 done.
save 099 done.
save 100 done.
save 101 done.
save 102 done.
save 103 done.
save 104 done.
save 105 done.
save 106 done.
save 107 done.
save 108 done.
save 109 done.
save 110 done.
save 111 done.
save 112 done.
save 113 done.
save 114 done.
save 115 done.
save 116 done.
save 117 done.
save 118 done.
save 119 done.
save 120 done.
save 121 done.
save 122 done.
save 123 done.
save 124 done.

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值