如何使用Python中的Simple ITK更改Dicom文件的唯一数组

问题描述

我在dicom中有一堆医学图像,我想使用Python中的SimpleITK来校正偏置场的不均匀性。工作流程非常简单:我要(1)打开dicom图像,(2)在图像中创建对象的二进制蒙版,(3)将N4偏置场校正应用于蒙版图像,(4)写回校正后的图像dicom格式的图像。请注意,没有对图像应用任何空间变换,而仅对强度进行了变换,因此我可以将所有空间信息和所有元数据(创建日期/小时和实例编号除外)从原始图像复制到校正后的图像。>

我已经编写了此功能来实现我的目标:

def n4_dcm_correction(dcm_in_file):
    Metadata_to_set = ["0008|0012","0008|0013","0020|0013"]
    filepath = PurePath(dcm_in_file)
    root_dir = str(filepath.parent)
    file_name = filepath.stem
    dcm_reader = sitk.ImageFileReader()
    dcm_reader.SetFileName(dcm_in_file)
    dcm_reader.LoadPrivateTagsOn()
    inputimage = dcm_reader.Execute()
    Metadata_to_copy = [k for k in inputimage.GetMetaDataKeys() if k not in Metadata_to_set]
    maskImage = sitk.OtsuThreshold(inputimage,1,200)
    filledImage = sitk.BinaryFillhole(maskImage)
    floatimage = sitk.Cast(inputimage,sitk.sitkFloat32)
    corrector = sitk.N4BiasFieldCorrectionImageFilter();
    output = corrector.Execute(floatimage,filledImage)
    output.copyinformation(inputimage)
    for k in Metadata_to_copy:
        print("key is: {}; value is {}".format(k,inputimage.GetMetaData(k)))
        output.SetMetaData(k,inputimage.GetMetaData(k))
     output.SetMetaData("0008|0012",time.strftime("%Y%m%d"))
     output.SetMetaData("0008|0013",time.strftime("%H%M%s"))
     output.SetMetaData("0008|0013",str(float(inputimage.GetMetaData("0008|0013")) + randint(1,999)))
    out_file = "{}/{}_biascorrected.dcm".format(root_dir,file_name)
    writer = sitk.ImageFileWriter()
    writer.KeepOriginalImageUIDOn()
    writer.SetFileName(out_file)
    writer.Execute(sitk.Cast(output,sitk.sitkUInt16))
    return

n4_dcm_correction("/path/to/my/dcm/image.dcm")

尽管偏差校正部分有效(消除了偏差),但书写部分却是一团糟。我希望我的输出dicom具有与原始dicom完全相同的元数据,但是它们都丢失了,特别是患者名称,协议名称和制造商。 Similalry,空间信息有些错误,因为如果我尝试使用dcm2niix将dicom转换为nifti格式,则方向相反:上级向下,下级向上,前向后退,前向后退。我错过了哪一步?

解决方法

我怀疑您正在使用MRI系列,而不是单个文件。 this example可能会做您想要的事情,以读取-修改-写入存储在一组文件中的卷。

如果该示例不能解决您的问题,请张贴到ITK discourse,这是与ITK / SimpleITK相关的讨论的主要位置。