使用pydicom添加新的DICOM标签

6
我正在尝试使用freesurfer的dcm2nii工具将一系列DTI西门子DICOM转换为NifTi格式,但是在某些文件上失败了,因为它们缺少DiffusionGradientDirection标签(0x19,0x100E),这是生成.bvec和.bval文件所必需的。不是标签没有值,而是似乎根本不存在。我尝试添加该标签,但出现以下错误:ds [0x19、0x100E] .value ='yes'。 有没有办法我可以手动插入此标签?

您确定标签是正确的吗?0x19组是奇数,因此它是一个私有标签,不是标准字典的一部分。在DICOM标准中,“Diffusion Gradient Direction”似乎是一个序列,而不是具有单个值的数据元素。 - darcymason
@darcymason 我敢打赌OP需要添加私有所有者。 - malat
@darcymason 我相当确定那是正确的标签。我已经在来自各种西门子机器的几千个DTI运行中尝试过这个标签,每个具有(0x19,0x100e)的运行都成功生成了.bval/.bvec文件,而每个缺少该标签的运行都无法生成.bval/.bvec文件。我相信所有扩散数据都存储在私有标签中(http://mri-imaging.blogspot.com/2011/04/how-to-find-dti-information-from-dicom.html)。 - G Warner
啊,我在pydicom的私有标签信息中找到了它——请查看完整答案。 - darcymason
2个回答

6

要在数据集 ds 中添加一个新的私有数据元素到 pydicom 中,可以使用 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',即使数据集中尚不存在该项。


-1

我需要运用我的智慧来回答这个问题,因为我无法访问您的DICOM数据集,但我敢打赌,这是因为您对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仍然存在于数据集中,但是由于某种原因gdcmdump无法告诉我们这是'RealDwellTime'。

我猜想你也遇到了同样的问题,你缺少用于私有标签间接寻址的关键字(SIEMENS MR HEADER)。


顺便提一下,您是否检查了扩散信息是否直接存储在CSA头中,例如:

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

在这种情况下,我会向pydicom报告一个bug,以便他们也解析这个DICOM属性来获取扩散信息。

抱歉,我有点困惑。因为我是按标签号而不是标签名查询数据,所以 ds[0x19,0x100E] 仍然会返回一个值吗?此外,当我只打印整个头时,我看不到标签。最后,即使扩散信息存储在CSA头中也无关紧要,因为问题在于dcm2nii在我提到的标签中查找它,无法重定向到其他位置查找。问题不是我找不到扩散信息,而是dcm2nii找不到它。 - G Warner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接