【问题标题】:Extract patch and reconstruct image提取补丁并重建图像
【发布时间】:2019-10-22 21:33:18
【问题描述】:

我正在尝试分割任务,图像是 3d 体积,因为由于 gpu 内存限制我无法立即处理它们,我正在提取图像的补丁并对它们执行操作。

用于提取我的补丁

    def cutup(data, blck, strd):
        sh = np.array(data.shape)
        blck = np.asanyarray(blck)
        strd = np.asanyarray(strd)
        nbl = (sh - blck) // strd + 1
        strides = np.r_[data.strides * strd, data.strides]
        dims = np.r_[nbl, blck]
        data6 = stride_tricks.as_strided(data, strides=strides, shape=dims)
        return data6.reshape(-1, *blck)

    def make_patches(image_folder, mask_folder):
        '''
        Given niigz image and mask files will create numpy files 
        '''
        for image, mask in tqdm.tqdm(zip(os.listdir(image_folder), os.listdir(mask_folder))):
            mask_ = mask
            mask = mask.split('_')
            image = mask[0]
            image_name = mask[0]
            mask_name = mask[0]
            image, mask = read_image_and_seg(os.path.join(image_folder, image), os.path.join(mask_folder,mask_))
            if image.shape[1] > 600:
                image = image[:,:600,:]
            desired_size_w = 896
            desired_size_h = 600
            desired_size_z = 600
            delta_w = desired_size_w - image.shape[0]
            delta_h = desired_size_h - image.shape[1]
            delta_z = desired_size_z - image.shape[2]

            padded_image =np.pad(image, ((0,delta_w), (0,delta_h), (0, delta_z)), 'constant')
            padded_mask  =np.pad(mask, ((0,delta_w), (0,delta_h), (0, delta_z)), 'constant')
            y  = cutup(padded_image, (128,128,128),(128,128,128))#Actually extract more patches by changing stride size
            y_ = cutup(padded_mask,  (128,128,128),(128,128,128))
            print(image_name)
            for index, (im , label) in enumerate(zip(y , y_)):
                if len(np.unique(im)) ==1:
                    continue
                else:
                    if not os.path.exists(os.path.join('../data/patches/images/',image_name.split('.')[0]+str(index))):
                        np.save(os.path.join('../data/patches/images/',image_name.split('.')[0]+str(index)), im)
                        np.save(os.path.join('../data/patches/masks/', image_name.split('.')[0]+str(index)), label)

现在这将提取非重叠补丁并给我 numpy 数组中的补丁,就像我正在将图像转换为形状(填充 0)896,640,640 这样我可以提取所有补丁

问题是我不知道上面的代码是否有效!为了测试它想要提取补丁然后获取这些补丁并重建图像,现在我不确定如何去做,

现在这就是我所拥有的

    def reconstruct_image(folder_path_of_npy_files):
        slice_shape = len(os.listdir(folder_path_of_npy_files))
        recon_image = np.array([])
        for index, file in enumerate(os.listdir(folder_path_of_npy_files)):
            read_image = np.load(os.path.join(folder_path_of_npy_files, file))
            recon_image = np.append(recon_image, read_image)
        return recon_image

但这不起作用,因为它创建了一个 (x, 128,128,128) 数组并不断填充第 0 维。

所以我的问题是,我如何重建图像?还是有一种更好的方法来提取和重建补丁。

提前致谢。

【问题讨论】:

    标签: python numpy deep-learning medical


    【解决方案1】:

    如果事情相当简单(不是滑动窗口),那么您可以使用skimage.util.shape.view_as_blocks。例如:

    import numpy as np
    import skimage
    
    # Create example
    data = np.random.random((200,200,200))
    
    blocks = skimage.util.shape.view_as_blocks(data, (10, 10, 10))
    
    # Do the processing on the blocks here.
    processed_blocks = blocks
    
    new_data = np.reshape(process_blocks, (200, 200, 200))
    

    但是,如果您遇到内存限制问题,这可能不是最好的方法,因为您将多次复制原始数据(数据、块、new_data)等,您可能需要考虑这样做比我这里的例子聪明一点。

    如果您遇到内存问题,您可以非常小心地做的另一件事是更改数据的基础数据类型。例如,当我在做 MRI 数据时,大多数原始数据都是整数,但 Python 会将其表示为 float64。如果您可以接受对数据进行一些舍入,那么您可以执行以下操作:

    import numpy as np
    import skimage
    
    # Create example
    data = 200*np.random.random((200,200,200)).astype(np.float16)  # 2 byte float
    
    blocks = skimage.util.shape.view_as_blocks(data, (10, 10, 10))
    
    # Do the processing on the blocks here.
    
    new_data = np.reshape(blocks, (200, 200, 200))
    

    此版本使用:

    In [2]: whos
    Variable   Type       Data/Info
    -------------------------------
    blocks     ndarray    20x20x20x10x10x10: 8000000 elems, type `float16`, 16000000 bytes (15.2587890625 Mb)                                                                                              
    data       ndarray    200x200x200: 8000000 elems, type `float16`, 16000000 bytes (15.2587890625 Mb)
    new_data   ndarray    200x200x200: 8000000 elems, type `float16`, 16000000 bytes (15.2587890625 Mb)
    

    与第一个版本相比:

    In [2]: whos
    Variable   Type       Data/Info
    -------------------------------
    blocks     ndarray    20x20x20x10x10x10: 8000000 elems, type `float64`, 64000000 bytes (61.03515625 Mb)                                                                                                
    data       ndarray    200x200x200: 8000000 elems, type `float64`, 64000000 bytes (61.03515625 Mb)
    new_data   ndarray    200x200x200: 8000000 elems, type `float64`, 64000000 bytes (61.03515625 Mb)
    

    因此,执行np.float16 可以节省大约 4 倍的 RAM。

    但是,进行此类更改会对数据和算法进行假设(可能的舍入问题等)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-11
      • 2021-01-20
      • 2013-05-22
      • 2019-06-17
      • 2018-11-06
      • 1970-01-01
      • 2017-04-05
      • 1970-01-01
      相关资源
      最近更新 更多