Извлечь патч и реконструировать изображение - PullRequest
0 голосов
/ 07 июня 2019

Я пытаюсь выполнить задачу сегментации, изображения являются трехмерными томами, поскольку я не могу обработать их сразу из-за ограничений памяти 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-е измерение.

Итак, мой вопрос, как мне восстановить изображение? или есть просто лучший способ извлечь и восстановить патчи.

Заранее спасибо.

1 Ответ

0 голосов
/ 07 июня 2019

Если все достаточно просто (не скользящее окно), тогда вы можете использовать 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))

Но, если у вас есть проблемы с ограничением памяти, это может быть не лучшим способом, так как вы собираетесь дублировать исходные данные несколько раз (данные, блоки, новые_данные) и т. Д.и вам, возможно, придется взглянуть на это немного умнее, чем в моем примере.

Если у вас проблемы с памятью, другая вещь, которую вы можете сделать очень осторожно, это изменить базовый тип данных ваших данных,Например, когда я делал данные МРТ, большинство исходных данных были целочисленными, но 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 раза больше оперативной памяти.

Но внесение изменений такого типа накладывает допущения на данные и алгоритм (возможные проблемы с округлением и т. Д.).).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...