如何使用Python在SimpleITK中获取Dicom图像的元数据

时间:2017-10-27 22:26:37

标签: python metadata dicom simpleitk

我最近开始使用SimpleITK修改一些Dicom图像。但是我无法修改元数据。事实上,我甚至无法访问它。

我知道感谢我在这里找到的脚本:https://github.com/SimpleITK/SimpleITK/pull/262/files?diff=split默认情况下不会加载元数据,因为它会降低进程的速度。我也知道要加载元数据我应该使用读者的以下方法:" .LoadPrivateTagsOn()"。

然而,每当我使用' .GetMetaDataKeys()'我的图像对象上的方法返回一个空元组。我希望下面的代码能给我一些密钥,但它并没有。



    #=========================================================================
#
#  Copyright Insight Software Consortium
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0.txt
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.
#
#=========================================================================

from __future__ import print_function

import SimpleITK as sitk

import sys, time, os
import numpy as np

# if len( sys.argv ) < 2:
#     print( "Usage: python " + __file__ + "<output_directory>" )
#     sys.exit ( 1 )


# Create a new series from a numpy array
new_arr = np.random.uniform(-10, 10, size = (3,4,5)).astype(np.int16)
new_img = sitk.GetImageFromArray(new_arr)
new_img.SetSpacing([2.5,3.5,4.5])

directory = r"C:\Users\jeroen\Documents\2eMaster\Reconstruction3D\Projet Femur\Dicom\test"


# Write the 3D image as a series
# IMPORTANT: There are many DICOM tags that need to be updated when you modify an
#            original image. This is a delicate opration and requires knowlege of
#            the DICOM standard. This example only modifies some. For a more complete
#            list of tags that need to be modified see:
#                           http://gdcm.sourceforge.net/wiki/index.php/Writing_DICOM

writer = sitk.ImageFileWriter()
# Use the study/series/frame of reference information given in the meta-data
# dictionary and not the automatically generated information from the file IO
writer.KeepOriginalImageUIDOn()

# Copy relevant tags from the original meta-data dictionary (private tags are also
# accessible).
tags_to_copy = ["0010|0010", # Patient Name
                "0010|0020", # Patient ID
                "0010|0030", # Patient Birth Date
                "0020|000D", # Study Instance UID, for machine consumption
                "0020|0010", # Study ID, for human consumption
                "0008|0020", # Study Date
                "0008|0030", # Study Time
                "0008|0050", # Accession Number
                "0008|0060"  # Modality
]

modification_time = time.strftime("%H%M%S")
modification_date = time.strftime("%Y%m%d")

# Copy some of the tags and add the relevant tags indicating the change.
# For the series instance UID (0020|000e), each of the components is a number, cannot start
# with zero, and separated by a '.' We create a unique series ID using the date and time.
# tags of interest:
direction = new_img.GetDirection()
print(new_img.HasMetaDataKey("0008|0021"))
series_tag_values = [(k, new_img.GetMetaData(k)) for k in tags_to_copy if new_img.HasMetaDataKey(k)] + \
                  [("0008|0031",modification_time), # Series Time
                  ("0008|0021",modification_date), # Series Date
                  ("0008|0008","DERIVED\\SECONDARY"), # Image Type
                  ("0020|000e", "1.2.826.0.1.3680043.2.1125."+modification_date+".1"+modification_time), # Series Instance UID
                  ("0020|0037", '\\'.join(map(str, (direction[0], direction[3], direction[6],# Image Orientation (Patient)
                                                    direction[1],direction[4],direction[7])))),
                  ("0008|103e", "Created-SimpleITK")] # Series Description
print(new_img.GetMetaDataKeys())
for i in range(new_img.GetDepth()):
    image_slice = new_img[:,:,i]
    # Tags shared by the series.
    for tag, value in series_tag_values:
        image_slice.SetMetaData(tag, value)
    # Slice specific tags.
    image_slice.SetMetaData("0008|0012", time.strftime("%Y%m%d")) # Instance Creation Date
    image_slice.SetMetaData("0008|0013", time.strftime("%H%M%S")) # Instance Creation Time
    image_slice.SetMetaData("0008|0060", "CT")  # set the type to CT so the thickness is carried over
    image_slice.SetMetaData("0020|0032", '\\'.join(map(str,new_img.TransformIndexToPhysicalPoint((0,0,i))))) # Image Position (Patient)
    image_slice.SetMetaData("0020,0013", str(i)) # Instance Number

    # Write to the output directory and add the extension dcm, to force writing in DICOM format.
    writer.SetFileName(os.path.join(directory,str(i)+'.dcm'))
    writer.Execute(image_slice)
print(new_img.GetMetaDataKeys())
# Re-read the series
# Read the original series. First obtain the series file names using the
# image series reader.
data_directory = directory
series_IDs = sitk.ImageSeriesReader.GetGDCMSeriesIDs(data_directory)
if not series_IDs:
    print("ERROR: given directory \""+data_directory+"\" does not contain a DICOM series.")
    sys.exit(1)
series_file_names = sitk.ImageSeriesReader.GetGDCMSeriesFileNames(data_directory, series_IDs[0])

series_reader = sitk.ImageSeriesReader()
series_reader.SetFileNames(series_file_names)

# Configure the reader to load all of the DICOM tags (publicprivate):
# By default tags are not loaded (saves time).
# By default if tags are loaded, the private tags are not loaded.
# We explicitly configure the reader to load tags, including the
# private ones.
series_reader.LoadPrivateTagsOn()
image3D = series_reader.Execute()
print(image3D.GetMetaDataKeys())
sys.exit( 0 )
&#13;
&#13;
&#13;

非常感谢任何帮助!

编辑:似乎我还需要运行&#39; .MetaDataDictionaryArrayUpdateOn()&#39;我的读者的模块。但是,如果我尝试这样做,他总是告诉我,对于&#39; ImageSeriesReaderClass&#39;即使它在文档中提到。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

我要在这里回答我自己的问题。感谢我在github上发布的帖子,我找到了答案。事实证明,在此版本(1.0.1)中未实现方法'.MetaDataDictionaryArrayUpdateOn()'。

SimpleITK github社区有2个解决方法。

您可以在此处找到帖子:https://github.com/SimpleITK/SimpleITK/issues/331

在下一个版本(1月的某个地方),这个问题将得到解决。