【问题标题】:How do I fix pydicom's dcmread() preamble error?如何修复 pydicom 的 dcmread() 前导错误?
【发布时间】:2020-08-18 07:14:28
【问题描述】:

在给定路径上确实存在的 DICOM 文件上,dcmread() 出现问题。我不确定出了什么问题。这是我的代码:

import pydicom

f = "/exact/path/hi.dcm"
fn = get_testdata_file(f)
ds = pydicom.dcmread(fn)

ds.SOPClassUID = ds.MediaStorageSOPClassUID

我遇到以下错误:

Traceback (most recent call last):
  File "addfields.py", line 14, in <module>
    ds = pydicom.dcmread(fn)
  File "/Users/user/opt/anaconda3/lib/python3.7/site-packages/pydicom/filereader.py", line 871, in dcmread
    force=force, specific_tags=specific_tags)
  File "/Users/user/opt/anaconda3/lib/python3.7/site-packages/pydicom/filereader.py", line 668, in read_partial
    preamble = read_preamble(fileobj, force)
  File "/Users/user/opt/anaconda3/lib/python3.7/site-packages/pydicom/filereader.py", line 605, in read_preamble
    preamble = fp.read(128)
AttributeError: 'NoneType' object has no attribute 'read'

但我不知道为什么,因为“hi.dcm”是一个存在的文件(路径正确)并且里面有元数据。我不知道什么是序言以及它是否出现在我正在处理的图像中。

【问题讨论】:

  • 一些工具包不处理没有前导的实例;不确定 pydicom 是否是其中之一。即使存在元数据,前导也可能不存在。许多查看器和转储实用程序也会在没有前导码的情况下正确加载数据集;这并不意味着一切都很好。进一步阅读here
  • 关于您的问题: 1) 确保 pydicom 是否可以读取没有序言的实例。 2)如果是,请尝试弄清楚如何配置它来做到这一点。可能是某些初始配置或某些方法的某些参数或设置某些属性。 3)如果不是,你必须自己插入序言;请参阅上述评论中的链接。
  • @AmitJoshi - 我在答案中添加了一些注释以澄清混淆。错误处理可能会在 pydicom 中更改。

标签: python-3.x dicom pydicom


【解决方案1】:

免责声明:我是 pydicom 的贡献者。

发生错误是因为get_testdata_file 返回None,然后将其用作文件名。错误消息本身有点误导 - 在这种情况下,最好提高 FileNotFoundValueError更新:它在当前 pydicom 中引发 TypeError)。相反,首先读取的是序言(DICOM 图像的标记,由 128 个零字节组成,后跟“DICM”),在尝试读取它时,由于文件指针 @987654327 而崩溃@。

这里是documentation for get_testdata_file

返回带有文件名的第一个匹配数据集的绝对路径。

首先搜索本地 pydicom 数据存储,然后搜索任何本地可用的外部资源,最后搜索 pydicom/pydicom-data 存储库中可用的文件。

所以这是一个方便的功能,主要是查找pydicom测试数据文件。
如果你已经有了文件路径,你可以直接使用它:

import pydicom

fn = "/exact/path/hi.dcm"
ds = pydicom.dcmread(fn)

至于序言,如果 DICOM 文件没有序言(旧的 ACR-NEMA 格式),您可以使用 force=True 参数读取此类文件:

ds = pydicom.dcmread(fn, force=True)

虽然我只会在你真的有这样的文件时才使用它,因为它也会尝试将非 DICOM 文件作为 DICOM 处理,这可能会导致一些意外的异常。如前所述,这种情况下的错误与缺少前导码无关,而是与不正确的文件路径有关。

更新:
pydicom 的 2.1 版以来,此行为已更改。如果通过 Nonedcmread 现在将通过有意义的消息引发 TypeError

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-30
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 2016-06-22
    相关资源
    最近更新 更多