>

세그멘테이션 작업을 시도하고 있는데, gpu 메모리 제약으로 인해 이미지를 한 번에 처리 할 수 ​​없기 때문에 이미지가 3d 볼륨입니다. 이미지의 패치를 추출하여 작업을 수행하고 있습니다.

내가 패치를 추출하기 위해

   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

    사물이 적당하지 않으면 (슬라이딩 창 아님) 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))
    
    
    그러나 메모리 제약 문제가있는 경우 원본 데이터를 여러 번 복제 할 때 가장 좋은 방법이 아닐 수 있습니다 (data, blocks, 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)
    
    

    vs 첫 번째 버전 :

    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  RAM에서 4를 절약 할 수 있습니다.

    그러나 이러한 유형의 변경은 데이터 및 알고리즘 (반올림 문제 등)을 가정합니다.

  • 이전 Windows 10의 Windows 용 Docker에서 DOCKER_CERT_PATH는 무엇입니까?
  • 다음 r - if 문이있는 조건부 필터