Метаданные DICOM в Nifti не передаются - PullRequest
0 голосов
/ 05 августа 2020

Я пытаюсь взять несколько стеков DICOM и преобразовать их в файлы Nifti. Когда я выполняю преобразование и открываю новый файл Nifti в средстве трехмерного просмотра, объем сжимается в направлении оси z. Файлы Nifti не знают, каков интервал между срезами. Насколько я понимаю, imageio.volread() не читает метаданные. Я пробовал использовать pydicom.filereader.dcmread(), но он читает только один файл. Как я могу скопировать метаданные из стека DICOM в файл Nifti при преобразовании форматов?

import nibabel as nib
import imageio
import numpy as np
import os, sys

DIR = '\\all scans\\'
savefold = '\\nifti\\'

for root, dirs, files in os.walk(DIR):
    for directory in dirs:
        vol = imageio.volread(DIR + directory).astype(int)
        vol = np.transpose(vol, (2,1,0)).astype(int)
        niftisave = nib.Nifti1Image(vol, affine=np.eye(4))
        nib.save(niftisave, os.path.join(savefold + directory) + '.nii')

ОБНОВЛЕНИЕ:

Я использую Nifti1Header и устанавливаю интервал между вокселями, но интервал вокселей все еще 1x1x1, когда я сохраняю и открываю файл в других программах. Когда я печатаю заголовок прямо перед сохранением, pixdim показывает [1. 0.09 0.09 0.09 1. 1. 1. 1. ].

header = nib.Nifti1Header()
OM = np.eye(4)
header.set_data_shape((224,352,224))
voxel_spacing = ((.09,.09,.09))
header.set_zooms(voxel_spacing)
header.set_sform(OM)
header.set_dim_info(slice = 2)

vol=imageio.volread(source) 

ROI_save = nib.Nifti1Image(vol, OM, header=header)
print(ROI_save.header)

ЗАГОЛОВОК:

<class 'nibabel.nifti1.Nifti1Header'> object, endian='<'
sizeof_hdr      : 348
data_type       : b''
db_name         : b''
extents         : 0
session_error   : 0
regular         : b''
dim_info        : 48
dim             : [  3 224 352 224   1   1   1   1]
intent_p1       : 0.0
intent_p2       : 0.0
intent_p3       : 0.0
intent_code     : none
datatype        : float32
bitpix          : 32
slice_start     : 0
pixdim          : [1.   0.09 0.09 0.09 1.   1.   1.   1.  ]
vox_offset      : 0.0
scl_slope       : nan
scl_inter       : nan
slice_end       : 0
slice_code      : unknown
xyzt_units      : 0
cal_max         : 0.0
cal_min         : 0.0
slice_duration  : 0.0
toffset         : 0.0
glmax           : 0
glmin           : 0
descrip         : b''
aux_file        : b''
qform_code      : unknown
sform_code      : aligned
quatern_b       : 0.0
quatern_c       : 0.0
quatern_d       : 0.0
qoffset_x       : 0.0
qoffset_y       : 0.0
qoffset_z       : 0.0
srow_x          : [1. 0. 0. 0.]
srow_y          : [0. 1. 0. 0.]
srow_z          : [0. 0. 1. 0.]
intent_name     : b''
magic           : b'n+1'

AFFINE:

np.eye(4)
--->[[1. 0. 0. 0.]
     [0. 1. 0. 0.]
     [0. 0. 1. 0.]
     [0. 0. 0. 1.]]

DESIRED AFFINE:

[[-0.09  0.    0.   -0.  ]
 [ 0.   -0.09  0.   -0.  ]
 [ 0.    0.    0.09  0.  ]
 [ 0.    0.    0.    1.  ]]

Ответы [ 2 ]

1 голос
/ 13 августа 2020

Вам необходимо напрямую указать расстояние между пикселями и форму массива, учитывая, что у вас есть 3D-объем 512x512x128, с интервалом вокселей 0,5 x 0,5 x 2,5 мм и идентичная матрица ориентации, см. Пример ниже:

from nibabel import Nifti1Header, Nifti1Image

img_array = np.zeros((512, 512, 128))

voxel_spacing = [0.5, 0.5, 2.5, 1]
OM = np.eye(4)
OM = OM * np.diag(voxel_spacing)

header = Nifti1Header()
header.set_data_shape((512, 512, 128))
header.set_dim_info(slice=2)
header.set_xyzt_units('mm')

nifti =  Nifti1Image(img_array, OM, header=header)

upd. Сохраните файл с помощью nibabel.save (или img.to_filename) и откройте его в MRIcron https://people.cas.sc.edu/rorden/mricron/index.html, даст следующий результат:

введите описание изображения здесь

0 голосов
/ 05 августа 2020

Если вы используете SimpleITK для чтения серии изображений Dicom, он будет правильно читать метаданные Dicom.

Вот пример того, как читать серию изображений Dicom:

https://simpleitk.readthedocs.io/en/master/link_DicomSeriesReader_docs.html

Если имя выходного файла имеет суффикс '.nii', он запишет том как файл Nifti.

...