简体   繁体   English

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

[英]How to get Meta data of Dicom image in SimpleITK using Python

I recently started using SimpleITK to modify some Dicom images. 我最近开始使用SimpleITK修改一些Dicom图像。 I am however unable to modify the meta data. 但是,我无法修改元数据。 As a matter of fact I can't even access it. 事实上,我什至无法访问它。

I know thanks to a script i found here: https://github.com/SimpleITK/SimpleITK/pull/262/files?diff=split that metadata is by default not loaded because it slows the process down. 我知道要感谢在这里找到的脚本: https : //github.com/SimpleITK/SimpleITK/pull/262/files?diff= split默认情况下未加载元数据,因为它会减慢处理速度。 I also know that to load the metadata I should use the following method of the reader: ".LoadPrivateTagsOn()". 我也知道要加载元数据,我应该使用阅读器的以下方法:“。LoadPrivateTagsOn()”。

However whenever i use the '.GetMetaDataKeys()' method on my image object it returns an empty tuple. 但是,每当我在图像对象上使用'.GetMetaDataKeys()'方法时,它都会返回一个空的元组。 I expected the code below to give me some keys, but it didn't. 我希望下面的代码能给我一些钥匙,但事实并非如此。

  #========================================================================= # # 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 ) 

Any help is greatly appreciated! 任何帮助是极大的赞赏!

EDIT: It seems that i also need to run the '.MetaDataDictionaryArrayUpdateOn()' module on my reader. 编辑:似乎我还需要在阅读器上运行'.MetaDataDictionaryArrayUpdateOn()'模块。 However if I try to do that he always tells me that there is no such method for the 'ImageSeriesReaderClass' even though it is mentioned in the documentation. 但是,如果我尝试这样做,他总是告诉我'ImageSeriesReaderClass'没有这样的方法,即使在文档中提到了它。 Any suggestions? 有什么建议么?

i'm gonna answer my own question here. 我要在这里回答我自己的问题。 Thanks to a post I made on github I found the answer. 感谢我在github上发表的一篇文章,我找到了答案。 It turns out that the method '.MetaDataDictionaryArrayUpdateOn()' is not implemented in this build (1.0.1). 事实证明,此版本(1.0.1)中未实现方法'.MetaDataDictionaryArrayUpdateOn()'。

There are 2 workarounds credits go to the SimpleITK github community. 有2个变通办法,请转到SimpleITK github社区。

You can find the post here: https://github.com/SimpleITK/SimpleITK/issues/331 您可以在这里找到该帖子: https : //github.com/SimpleITK/SimpleITK/issues/331

At the next release (somewhere in January) this problem will be resolved. 在下一个版本(一月份的某个时间),此问题将得到解决。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM