在原生Python中解析DICOM文件

时间:2020-03-06 14:35:06  来源:igfitidea点击:

解析DICOM文件的最简单,最方便的方法是什么?

不使用非Python库的本机Python实现将是更可取的。 DICOM是数字医学成像中的标准文件格式(有关更多信息,请参见此处)。

有一些C / C ++库支持读取DICOM文件(子集)。其中的两个或者三个甚至具有Python绑定。本机Python解析器将为我提供两个目的:

  • 无需构建任何外部C / C ++库。
  • 了解有关DICOM文件格式的信息。

解决方案

我不知道原始的海报尝试了什么,哪种方法对他有用而无效。我从未与DICOM合作过,但是谷歌快速搜索" DICOM python"给出了一些有趣的结果。看来这个项目:http://www.creatis.univ-lyon1.fr/Public/Gdcm/应该可以提供我们想要的东西。它具有python绑定和一个非常活跃的邮件列表。

有一些带有Python绑定的库(最常在C / C ++中实现),例如:

  • pydicomlib
  • gdcmPython

但是,我正在寻找本机Python实现,以了解有关DICOM文件格式的更多信息。

几年前,我在寻找相同的东西,发现了这一点:

Python DICOM库

我对代码没有太大的印象,但是它是读取DICOM文件的本机Python。

到今天为止,还有另一个可读取DICOM文件的纯Python包:pydicom

如果我们想了解DICOM格式,Oleg Pianykh撰写的"医学数字成像和通信(DICOM):实用入门和生存指南"是一本可读性强的文章,它很好地介绍了DICOM的关键概念。 Springer-Verlag是这本书的出版商。当然,完整的DICOM标准是最终参考,尽管有些令人生畏。可从NEMA(http://medical.nema.org)获得。

文件格式实际上不像我们想象的那么深奥,它由一个序言和一个数据元素序列组成。前导包含ASCII文本" DICM"和几个未使用的保留字节。序言之后是一系列数据元素。每个数据元素由元素的大小,指示值表示形式的两个字符的ASCII码,DICOM标签和值组成。文件中的数据元素按其DICOM标记号排序。图像本身只是具有大小,值表示等的另一个数据元素。

值表示精确指定了如何解释值。是数字吗?它是一个字符串吗?如果是字符串,它是短字符串还是长字符串,并且允许使用哪些字符?值表示代码告诉我们这一点。

DICOM标签是一个4字节的十六进制代码,由2字节的"组"编号和2字节的"元素"编号组成。组号是一个标识符,告诉我们标签适用于哪个信息实体(例如,组0010指患者,组0020指研究)。元素编号标识值的解释(例如患者的ID号,系列说明等项目)。为了找出应该如何解释该值,代码在字典文件中查找DICOM标记。

还有其他一些细节,但这就是本质。要了解文件格式,最有启发性的事情是举一个DICOM文件示例,使用十六进制编辑器查看该文件,然后从心理上进行解析。我建议不要尝试至少从一开始就着眼于现有的开源实现来学习DICOM。它更容易混淆而不是启发。全面了解更为重要。一旦有了大局,就可以陷入微妙的境地。

现在,发生新的gdcm开发:

http://gdcm.sourceforge.net/

它支持Java和python的Con top。

当我们可以集中一个C ++实现并使它可以被许多不同的语言访问时,为什么还要编写另一个dicom实现

import dicom,numpy
dose = dicom.ReadFile("RTDOSE.dcm")
d = numpy.fromstring(dose.PixelData,dtype=numpy.int16)
d = d.reshape((dose.NumberofFrames,dose.Columns,dose.Rows))

上面提到的pydicom库似乎是用于访问DICOM数据结构的出色库。要使用它来访问例如RT DOSE数据,我想有人会做这样的事情

from enthought.mayavi import mlab
mlab.pipeline.scalar_field(d)

然后,如果我们在mayavi中,

这给出了错误的坐标和剂量比例,但是原理应该是正确的。

CT数据应该非常相似。

这些天,我大量使用pydicom,而且效果还不错。

import dicom 
data = dicom.read_file("yourdicomfile.dcm")

开始使用它很容易:

for key in data.dir():        
    value = getattr(data, key, '')
    if type(value) is dicom.UID.UID or key == "PixelData":
        continue

    print "%s: %s" % (key, value)

为了从"数据"对象中获得有趣的东西,某种程度上类似于dcmdump输出:

我认为了解dicom格式的一种好方法是打开相似的文件并编写代码以根据各个方面进行比较:研究描述,窗口宽度和中心,像素表示等。

段落数量不匹配