医学DICOM文件解析(笔记整理)

简介:
之前做超声的时候第一次接触带dicom后缀的图像文件,于是记录一下有关医学影像的学习笔记。
DICOM(Digital Imaging and Communications in Medicine)即医学数字成像和通信,是医学图像和相关信息的国际标准(ISO 12052)。它被广泛应用于放射医疗,心血管成像以及放射诊疗诊断设备(X射线,CT,核磁共振,超声等),并且在眼科和牙科等其它医学领域得到越来越深入广泛的应用。

DICOM文件:

医学图像设备生成 DICOM 文件,医生使用 DICOM 阅读器来阅读并对图像中发现的问题进行诊断。所有患者的医学图像都以 DICOM 文件格式进行存储。这个格式包含关于患者的 PHI(protected health information)信息,例如姓名,性别,年龄,以及其他图像相关信息比如捕获并生成图像的设备信息,医疗的一些上下文相关信息等。
这些信息具体可以分为以下四类:(a)Patient(b)Study(c)Series(d)Image。
每一个DICOM Tag都是由两个十六进制数的组合来确定的,分别为Group和Element。如(0010,0010)这个Tag表示的是Patient’s Name,它存储着这张DICOM图像的患者姓名。
如下图所示,每个DICOM文件由一个DICOM文件头和一个DICOM数据集合组成:
医学DICOM文件解析(笔记整理)_第1张图片
DICOM前缀——可根据这长为4个字节的字符串是否等于“DICM”来判断该文件是不是DICOM文件。
而DICOM文件的主要组成部分是数据集,数据元素按照标签tag从小到大顺序排列。
最基本的单元是数据元,数据元主要由4个部分组成:
1、DICOM TAG: 存储该项信息的标识;
2、VR(value representation) :存储描述该项信息的数据类型;
3、value length : 存储描述该项信息的数据长度;
4、value: 存储描述该项信息的数据值。
而TAG的分类为:
1、Patient Tag:
医学DICOM文件解析(笔记整理)_第2张图片
2、Study Tag:
医学DICOM文件解析(笔记整理)_第3张图片
3、Series Tag:
医学DICOM文件解析(笔记整理)_第4张图片
4、Image Tag:
医学DICOM文件解析(笔记整理)_第5张图片

Pydicom库解析:

目前有基于C++的DCMTK、基于Java的dcm4che和基于python的pydicom,都是非常优秀的解释DICOM标准的第三方库,下面有Pydicom库解析的示例代码:

#提取单张 dicom 图像
import pydicom
from matplotlib import pyplot

ds = pydicom.read_file('./001.dcm')# DICOM文件的位置
print(ds.dir()) # 打印所有 DICOM TAG 名
print(ds.dir('Pixe')) # 打印包含 'pat' 的 DICOM TAG
print(ds.PatientName, ds.PatientSex, ds.PatientID, ds.PatientBirthDate, ds.PatientAge) # 打印 DICOM TAG 相应的属性值
print(ds.data_element('PatientName')) # 打印一个完整的数据元素,包括 DICOMTAG编码值(Group, Element), VR, Value
print(ds.data_element('PatientID').VR, ds.data_element('PatientID').value)
pixel_bytes = ds.PixelData # 原始二进制文件

pix = ds.pixel_array       # 像素值矩阵
print(pix.shape) # 打印矩阵维度
pyplot.imshow(pix, cmap=pylab.cm.bone)
pyplot.show() # cmap 表示 colormap,可以是设置成不同值获得不同显示效果,打印dicom图片
#提取序列 dicom 图像
import pydicom
import numpy
from matplotlib import pyplot

# 用lstFilesDCM作为存放DICOM files的列表
PathDicom = "D:/dicom_image/V"  # 与python文件同一个目录下的文件夹
lstFilesDCM = []

# 将所有dicom文件读入
for diName, subdirList, fileList in os.walk(PathDicom):
    for filename in fileList:
        if ".dcm" in filename.lower():  # 判断文件是否为dicom文件
            print(filename)
            lstFilesDCM.append(os.path.join(diName, filename))  # 加入到列表中

## 将第一张图片作为参考图
RefDs = pydicom.read_file(lstFilesDCM[10])  # 读取第一张dicom图片
# print(RefDs)
# print(RefDs.pixel_array)
# print(RefDs.PatientPosition)
pyplot.imshow(RefDs.pixel_array, cmap=pyplot.cm.bone)
pyplot.show()

# 建立三维数组,分别记录长、宽、层数(也就是dicom数据个数)
ConstPixelDims = (int(RefDs.Rows), int(RefDs.Columns), len(lstFilesDCM))
print(ConstPixelDims)

# 得到spacing值 (mm为单位)
# PixelSpacing - 每个像素点实际的长度与宽度,单位(mm)
# SliceThickness - 每层切片的厚度,单位(mm)
ConstPixelSpacing = (float(RefDs.PixelSpacing[0]), float(RefDs.PixelSpacing[1]), float(RefDs.SliceThickness))

# 三维数据
x = numpy.arange(0.0, (ConstPixelDims[0] + 1) * ConstPixelSpacing[0], ConstPixelSpacing[0])  # 0到(第一个维数加一*像素间的间隔),步长为constpixelSpacing
y = numpy.arange(0.0, (ConstPixelDims[1] + 1) * ConstPixelSpacing[1], ConstPixelSpacing[1])  #
z = numpy.arange(0.0, (ConstPixelDims[2] + 1) * ConstPixelSpacing[2], ConstPixelSpacing[2])  #
print(len(x),"xxxx")

ArrayDicom = numpy.zeros(ConstPixelDims, dtype=RefDs.pixel_array.dtype)

# 遍历所有的dicom文件,读取图像数据,存放在numpy数组中
for filenameDCM in lstFilesDCM:
    ds = pydicom.read_file(filenameDCM)
    ArrayDicom[:, :, lstFilesDCM.index(filenameDCM)] = ds.pixel_array


# 轴状面显示
# dpi是指每英寸的像素数,dpi越大,表示打印出来的图片越清晰。不是指图片的大小.
# 像素用在显示领域 分辨率用在打印领域 也就是你的图像是用来打印的时候才去考虑分辨率的问题
pyplot.figure(dpi=1000)
# 将坐标轴都变为同等长度
# pyplot.axes().set_aspect('equal', 'datalim')
pyplot.axes().set_aspect('equal')
# 将图片变为gray颜色
pyplot.set_cmap(pyplot.gray())

pyplot.imshow(ArrayDicom[:, :, 360])# 第三个维度表示现在展示的是第几层
pyplot.show()
56 # 冠状面显示
pyplot.figure(dpi=100)
pyplot.axes().set_aspect('equal', 'datalim')
pyplot.set_cmap(pyplot.gray())
pyplot.imshow(ArrayDicom[:, 90, :])
pyplot.show()

你可能感兴趣的:(学习笔记整理,python,医学影像,DICOM,pydicom,图像处理)