【问题标题】:How to decode and visualize DICOM curve data in Python 3?如何在 Python 3 中解码和可视化 DICOM 曲线数据?
【发布时间】:2020-11-12 04:45:16
【问题描述】:

我正在尝试使用 Python 3 和 pyDicom 可视化一个 DICOM 文件,该文件应该包含一个黑色的 100x100 图像,其中绘制了一些曲线。像素数据是从标题 (7fe0,0010) 中提取的,打印时显示 b'\x00\x00\x00...'。这我可以轻松转换为 100x100 的 numpy 数组。

但是,(5000,3000) 中的曲线数据显示 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0H@\x00\x00\x00\x00\x00\xc0X@\x00\x00\x00\x00\x00\xc0H@',我无法将其转换为 100x100 像素图像中的 x,y 坐标。在 DICOM 文件中它说

  • 曲线尺寸:2
  • 点数:2
  • 数据类型:poly
  • 数据值表示:3
  • 曲线标签:横轴
  • 曲线数据:32 个元素

主要问题是:如何解码在我的 100x100 图像中回溯曲线所需的坐标?我主要关心的是应该有 32 个元素,但只有 26 个十六进制值输出。我也不知道如何处理\xc0H@\xc0X@。当我打印这些时,它会产生192 72 64192 88 64。 python如何将这2个十六进制代码解码为6个数字?这些数字代表什么?

编辑: 显然数据值表示 3 意味着数据表示为浮点双精度。另一方面,数据中应该有两个点,那么每个点用16个元素表示?我看不出这两个语句是如何兼容的。有趣的是,如前所述,第一个\xc0H@ 转换为 3 个数字,并通过这样做完成了曲线数据的前 16 个元素。如何将其转换为 2D 图像中的点?

【问题讨论】:

  • 曲线数据自 2004 年起已在 DICOM 中停用,因此您必须查看 2004 年或更早的 DICOM 标准才能找到相关信息。其他人可能知道在哪里可以找到它...
  • 大多数旧版本的 DICOM 标准仍在 NEMA 站点上维护。 2004 年:dicom.nema.org/dicom/2004
  • 我确实找到了 2004 年的 DICOM 标准并且我已经阅读了它,但我的问题在于曲线数据的解释。

标签: python python-3.x hex pydicom medical-imaging


【解决方案1】:

曲线数据自 2004 年起已在 DICOM 中停用,因此您可以在 DICOM standard from 2004 中找到相关信息(感谢 @kritzel_sw 提供的链接)。

正如您已经发现的那样,Data Value Representation 3 表示数据条目是双重格式,并且使用多边形的Type of Data,您的数据中有 x/y 元组。由于双精度值保存在 8 个字节中,因此每个点有 16 个字节 - 在您的情况下(32 个字节的数据)总共 2 个点。

Pydicom 不(也可能不会)直接支持已退役的 Curve 模块(尽管在 pydicom 2.1 中添加了对 Waveform 模块的支持,当前等效模块),因此您必须自己解码数据。你可以这样做(给定双数):

from struct import unpack
from pydicom import dcm_read

ds = dcm_read(filename)
data = ds[0x50003000].value

# unpack('d') unpacks 8 bytes into a double
numbers = [unpack('d', data[i:i+8])[0] for i in range(0, len(data), 8)]
# I'm sure there is a nicer way for this...
coords = [(numbers[i], numbers[i+1]) for i in range(0, len(numbers), 2)]

在您的示例数据中,这将返回:

[(0.0, 49.5), (99.0, 49.5)]

例如x/y 坐标 (0, 49.9) 和 (99.0, 49.5),对应于图像中间的水平线。

关于 26 个十六进制元素与 32 个字节的不匹配:一个字节串表示只显示了十六进制字符串表示法中不能转换为 ASCII 的字节,其余的只是显示为对应的 ASCII 字符的表示。因此,例如,您的字节字符串的这一部分:\x00\xc0H@ 有 4 个字节长,也可以用十六进制字符串表示法表示为 \x00\xc0\x48\x40

【讨论】:

  • 感谢您的回答!我设法实现了它。只是为了完整性:我建议更改为 data = ds[0x5000,0x3000].value 并将 b 替换为 data
猜你喜欢
  • 2019-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多