Как правильно извлечь помеченные маски в формате PNG из массива? - PullRequest
1 голос
/ 27 мая 2020

У меня есть следующий файл в формате Nifti, который содержит маски, я написал следующий код для извлечения изображений внутри как PNG изображений, проблема в том, что:

Это мультиклассовые маски с меткой [0. 1. 2. 3.], после сохранения маски как PNG значения внутри изображения маски распределяются по диапазону [0 -> 255], а не просто 4 метки, как раньше!

Как Могу я решить эту проблему, пожалуйста?

Главное, чтобы внутри было 4 уникальных метки .

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

import nibabel as nib
import os
import glob
import numpy as np
from skimage.io import imread, imsave
#-------------------------------------------
# Multi Class Masks
path = 'Masks'
Dataset = glob.glob( os.path.join(path, '*.gz') )
ctr = 0
for image in Dataset:
    # Load masks voxel
    images = nib.load(image).get_fdata()
    print(np.unique(images))
    # Save it as PNG
    ctr+=1
    if(not os.path.exists('Dataset/masks/Case_'+str(ctr))):
        os.mkdir('Dataset/masks/Case_'+str(ctr))
    for _id in range(images.shape[2]):
        imsave(os.path.join('Dataset/masks','Case_'+
            str(ctr),str(ctr)+'_'+str(_id+1)+'.png'),
             resize(images[:,:,_id],(256,256)))
#-------------------------------------------
        imag = imread(os.path.join('Dataset/masks','Case_'+
             str(ctr),str(ctr)+'_'+str(_id+1)+'.png'))
        print(np.unique(imag))

1 Ответ

2 голосов
/ 27 мая 2020

Просто хочу вас предупредить, я ничего не знаю о данных Nifti и могу здесь ошибаться ... но, я думаю, проблема в том, что когда вы делаете:

fdata = nib.load(image).get_fdata()

, вы на самом деле получаете float64 тип данных:

print(fdata.dtype)

и формат PNG обрабатывает только uint8 или uint16, но не float64.

Я предполагаю, что, поскольку форма data равна ( 630, 630, 45), то есть 45 кусочков чего-то размером 630x630 каждый - но опять же, я могу ошибаться. Итак, я взял довольно центральный срез на основании того, что более вероятно, что что-то находится посередине, и я преобразовал его в uint8 и сохранил как PNG.

imsave('result.png', fdata[...,22].astype(np.uint8))

PNG имеет низкий контраст, потому что все значения меньше 4 по шкале 0..255, поэтому я увеличил контраст с помощью ImageMagick , чтобы вы могли его видеть. :

magick result.png -auto-level visible.png

enter image description here

Вы можете получить гистограмму и увидеть частоту встречаемости каждой из 4 меток классов с помощью ImageMagick в Терминале:

magick result.png -format "%c" histogram:info

Пример вывода

335942: (0,0,0) #000000 gray(0)      <--- there are 335,942 pixels=0
 26367: (1,1,1) #010101 gray(1)      <--- there are  26,367 pixels=1
 29419: (2,2,2) #020202 gray(2)
  5172: (3,3,3) #030303 gray(3)
...