【问题标题】:Adding new DICOM tag with pydicom使用 pydicom 添加新的 DICOM 标签
【发布时间】:2017-01-20 16:04:26
【问题描述】:

我正在尝试使用 freesurfer 的 dcm2nii 实用程序将大量 DTI siemens DICOM 转换为 NifTi,但在某些文件上失败,因为它们缺少生成 .bvec 和 @987654325 所必需的 DiffusionGradientDirection tag (0x19,0x100E) @ 文件。并不是标签没有值,它们似乎根本不存在。

ds[0x19,0x100E] 回溯(最近一次通话最后): 文件“”,第 1 行,在 文件“/space/jazz/1/users/gwarner/anaconda/lib/python2.7/site-packages/pydicom-0.9.9-py2.7.egg/dicom/dataset.py”,第 277 行,在 getitem data_elem = dict.getitem(self, tag) KeyError: (0019, 100e)

我尝试添加它,但收到以下错误:

ds[0x19,0x100E].value = '是' 回溯(最近一次通话最后): 文件“”,第 1 行,在 文件“/space/jazz/1/users/gwarner/anaconda/lib/python2.7/site-packages/pydicom-0.9.9-py2.7.egg/dicom/dataset.py”,第 277 行,在 getitem data_elem = dict.getitem(self, tag) KeyError: (0019, 100e)

有没有办法手动插入这个标签?

【问题讨论】:

  • 您确定标签正确吗?组 0x19 是奇数,因此它是私有标签,而不是标准字典的一部分。而在 dicom 标准中,Diffusion Gradient Direction 似乎是一个序列,而不是具有单个值的数据元素。
  • @darcymason 我打赌操作需要添加私人所有者
  • @darcymason 我相当肯定这是正确的标签。我已经在各种西门子机器的几千个 dti 运行上尝试过这个,每个具有 (0x19,0x100e) 的机器都成功生成 .bval/.bvec 文件,而每次缺少该标签的运行都无法生成 .bval/.bvec文件。我相信所有的传播数据都存储在私有标签中(mri-imaging.blogspot.com/2011/04/…
  • 啊,我在 pydicom 的私有标签信息中找到了它——查看完整答案。

标签: python dicom pydicom


【解决方案1】:

要将 pydicom 中的新私有数据元素添加到数据集 ds,可以使用 add_new 方法:

ds.add_new(tag, VR, value)

对于这种情况,在 pydicom 的 _private_dict.py 文件中查找私有标签(源自 gdcm 的私有标签信息):

 'SIEMENS MR HEADER': {
    ...
    '0019xx0e': ('FD', '3', 'DiffusionGradientDirection', ''),

它是一种重复组类型的标记,其中 xx 可以更改以允许同一类型的多个数据元素。这里 FD 是一个双浮点数,3 是多重性(期望三个值)。

所以在这种情况下,添加您需要的数据元素应该类似于:

ds.add_new(0x19100e, 'FD', [0,1,0]) # I have no idea what this last vector should actually be

但是,正如 malat 指出的那样,还需要一个私有创建者标签来引入块,以使文件成为有效的 DICOM。如果它不存在,您可能还必须添加它。由于您要将文件转换为另一种格式,因此您可能不在乎仅添加单个标记是否有效。

添加数据元素后,您可以使用 ds[0x19100e].value = ... 更改值,就像您原来的问题一样。

顺便说一句,标准字典中的关键字不需要add_new;对于那些可以直接按名称设置项目的人,例如ds.OtherPatientIDs='test',即使它在数据集中尚不存在。

【讨论】:

    【解决方案2】:

    我需要在这里用我的水晶球来回答这个问题,因为我无法访问你的 DICOM 数据集,但我敢打赌这对你来说是失败的,因为你对 Privates Tags在 DICOM 中工作。

    我找到了一个写得很好的页面(仅在web.archive 中可用)总结了这种情况。总之,您需要仔细检查 dcmdump 和/或 gdcmdump 之类的输出以指导您。

    让我们使用著名的 GDCMData 示例文件之一来综合这里发生的事情(但它应该对您同样有效)。

    $ gdcmdump SIEMENS_CSA2.dcm | grep 0019
    (0019,0010) LO [SIEMENS MR HEADER ]                               # 18,1 Private Creator
    (0019,1008) CS [IMAGE NUM 4 ]                                     # 12,1 CSA Image Header Type
    (0019,1009) LO [1.0 ]                                             # 4,1 CSA Image Header Version ??
    (0019,100b) DS [10632.5 ]                                         # 8,1 SliceMeasurementDuration
    (0019,100f) SH [Fast]                                             # 4,1 GradientMode
    (0019,1011) SH [No]                                               # 2,1 FlowCompensation
    (0019,1012) SL 0\0\-2134                                          # 12,3 TablePositionOrigin
    (0019,1013) SL 0\0\-2134                                          # 12,3 ImaAbsTablePosition
    (0019,1014) IS [0\0\0 ]                                           # 6,3 ImaRelTablePosition
    (0019,1015) FD -162.438\-61.4092\254.003                          # 24,3 SlicePosition_PCS
    (0019,1017) DS [0.642857]                                         # 8,1 SliceResolution
    (0019,1018) IS [7800]                                             # 4,1 RealDwellTime
    

    正如您在上面看到的,gdcmdump 能够判断 0019,1018 是 RealDwellTime

    如果我们天真地删除私有创建者标签,现在会发生什么:

    $ gdcmanon --dumb --remove 0019,0010 SIEMENS_CSA2.dcm /tmp/hack.dcm
    $ gdcmdump /tmp/hack.dcm | grep 0019
    (0019,1008) CS [IMAGE NUM 4 ]                                     # 12,? (1)  Private Element With Empty Private Creator
    (0019,1009) LO [1.0 ]                                             # 4,? (1)  Private Element With Empty Private Creator
    (0019,100b) DS [10632.5 ]                                         # 8,? (1)  Private Element With Empty Private Creator
    (0019,100f) SH [Fast]                                             # 4,? (1)  Private Element With Empty Private Creator
    (0019,1011) SH [No]                                               # 2,? (1)  Private Element With Empty Private Creator
    (0019,1012) SL 0\0\-2134                                          # 12,? (3)  Private Element With Empty Private Creator
    (0019,1013) SL 0\0\-2134                                          # 12,? (3)  Private Element With Empty Private Creator
    (0019,1014) IS [0\0\0 ]                                           # 6,? (3)  Private Element With Empty Private Creator
    (0019,1015) FD -162.438\-61.4092\254.003                          # 24,? (3)  Private Element With Empty Private Creator
    (0019,1017) DS [0.642857]                                         # 8,? (1)  Private Element With Empty Private Creator
    (0019,1018) IS [7800]                                             # 4,? (1)  Private Element With Empty Private Creator
    

    突然我们遇到了一个奇怪的情况,即 DICOM 属性 0019,1018 仍然存在于 DataSet 中,但由于“某些”原因 gdcmdump 无法告诉我们这是“RealDwellTime”。

    我猜这对你来说也是同样的问题,你缺少用于私有标签间接的密钥 (SIEMENS MR HEADER)。


    作为旁注,您是否检查过扩散信息没有直接存储在 CSA 标头中,例如:

    $ gdcmdump --csa my_input.dcm | grep -i diffusion
    

    在这种情况下,我会向 pydicom 报告一个错误,以便他们也解析此 DICOM 属性以检索扩散信息。

    【讨论】:

    • 对不起,我有点困惑。当我通过标签号而不是标签名称查询数据时,ds[0x19,0x100E] 是否仍会返回一个值?另外,当我打印出整个标题时,我看不到标签。最后,扩散信息是否存储在 CSA 标头中并不重要,因为问题是 dcm2nii 在我提到的标签中查找它,并且无法重定向到其他地方。问题不在于我无法找到扩散信息,而是 dcm2nii 无法找到它
    猜你喜欢
    • 1970-01-01
    • 2022-01-08
    • 2011-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多