我正在使用SimpleITK来分析动态PET数据。我有一个148 * N图像的文件夹(N是我的动态PET的帧数),我想分开每个帧的图像。 首先,我为每个帧创建了一个带有相应图像的子文件夹。
>folder #Folder of dynamic data
>subfolder1 #Subfolder with images of Frame 1
>image1, image2, ..., image148
>subfolder2 #Subfolder with images of Frame 2
>image149 image 150, ..., image296
我正在阅读我的图片如下:
series_reader = sitk.ImageSeriesReader()
image = sitk.ReadImage(series_reader.GDCMSeriesFileNames(path_subfolder1))
创建所有这些子文件夹不是非常用户友好,所以我尝试将所有图像路径存储在列表中:
frame1 = [image1, ..., image148]
frame2 = [image149, ..., image296]
...
frame_list = [frame1, frame2, ..., frameN]
阅读这样的图像:
image = sitk.ReadImage(frame_list[0])
问题在于,当我查看位于相同坐标(x,y,z)中的体素的值时,我不会使用2种方法获得相同的值。
似乎用series_reader.GDCMSeriesFileNames()
SimpleITK检索有关DICOM图像的一些信息,如Origin。
SimpleITK检索哪些信息以series_reader.GDCMSeriesFileNames()
创建他需要具有完全相同图像的图像?或者是否有另一种方法可以使用路径列表来获得相同的图像?
P.S。 :在这篇文章中,所有以'image'命名的变量都是图像的路径,而不是SimpleITK Image对象。
编辑:在我的情况下,我的所有帧都有相同的序列号,因此我无法使用series_reader.GDCMSeriesFileNames(path_folder, series_ID)
答案 0 :(得分:0)
据我所知,您有一个包含所有Dicom切片的文件夹,并且您希望将它们作为单个卷读取,以便您可以访问任何给定坐标的体素值。 请尝试通过以下代码片段阅读您的Dicom图片:
reader = sitk.ImageSeriesReader()
dicom_names = reader.GetGDCMSeriesFileNames(path_subfolder1)
reader.SetFileNames(dicom_names)
image = reader.Execute()
现在,image
是包含path_subfolder1
中所有切片的3D卷,您可以访问体素值,间距,方向,原点等。
我希望这有帮助,如果不随意在下面发表评论。
答案 1 :(得分:0)
无需将系列拆分为单独的目录。您可以使用itk::simple::ImageSeriesReader::GetGDCMSeriesIDs方法获取目录中的seriesID列表。
您可以使用以下一个内容轻松地为seriesID创建一个map到文件列表的地图:
series_dic = { series_id: reader.GetGDCMSeriesFileNames(path, series_id) for series_id in reader.GetGDCMSeriesIDs(path) }
通过使用GetGDCMSeriesFileNames方法,您应该获得所有文件是按其物理位置排序的正确顺序,而您手动方法则不是。
如果此自动方法不适用于您的特定扫描仪或采集过程,则必须手动加载DICOMS词典,通过series_id将它们分开,然后根据您采集的正确DICOM标记对它们进行正确排序。
答案 2 :(得分:0)
我找到的临时解决方案是以下解决方案:
1)使用sitk.ImageFileReader()
创建包含每个切片作为图像对象的列表:
frame1 = [Image1, ..., Image148]
frame2 = [Image149, ..., Image296]
...
frame_list = [frame1, frame2, ..., frameN]
NB:在这里,我们处理sitk Image Object而不是像我的第一篇文章中所述的images path
2)修改DICOM标头中的每个图像seriesID:
count = 1
for frames in frame_list:
for images in frames:
newID = images.GetMetaData('0020|000e') + str(count)
images.SetMetaData('0020|000e', newID)
count += 1
3)使用writer = sitk.ImageFileWriter()
和writer.KeepOriginalImageUIDOn()
将图像及其新的seriesID写入缓冲区文件夹中
4)使用@blowekamp方法将所有不同的系列ID及其相关的图像路径存储在字典中:
series_dic = { series_id: reader.GetGDCMSeriesFileNames(path, series_id) for series_id in reader.GetGDCMSeriesIDs(path) }
5)阅读该系列并将其存储在列表中:
for keys in series_dic:
Img_list.append(sitk.ReadImage(series_dic[keys]))
6)最后,我使用shutil.rmtree(path, ignore_errors=True)
这不是很优化,因为我必须写新图像然后删除它。如果您有更好的答案,请随时发表评论!
答案 3 :(得分:0)
GDCM可以处理简单的情况,例如一系列中的单个3D体积,但不准备处理时间序列。如果需要加载动态数据集,则需要使用更复杂的工具。
3D Slicer的DICOM导入器为整个文件夹结构建立索引,并确定可以从中加载的内容,包括具有无轴对齐,倾斜机架,可变切片间距的2D / 3D / 4D数据集;图像,细分,转换,结构化报告,RT计划/图像/结构集/剂量以及许多其他信息对象类型。然后,您可以将结果另存为nrrd,并使用SimpleITK对其进行进一步处理。
DCM2NIIX工具还可以将一些动态图像转换为nrrd或nifti。