Dicom
简介
DICOM(Digital Imaging and Communications in Medicine)医疗数字影像传输协定
https://blog.csdn.net/qq_39071305/article/details/101880158
用于医学影像处理、储存、打印、传输的一组通用的标准协定。它包含了文件格式的定义以及网络通信协议。DICOM是以TCP/IP为基础的应用协定,并以TCP/IP联系各个系统。两个能接受DICOM格式的医疗仪器间,可通过DICOM格式的文件,来接收与交换影像及病人资料。
重要性
https://www.dicomstandard.org/docs/librariesprovider2/dicomdocuments/wp-cotent/uploads/2018/10/day1_s2-odonnell-dicom-overview-cn.pdf?sfvrsn=15770eab_2
几乎所有的东西出来都是DICOM,如CT、MR、X光、超声
DICOM不止存储了图像数据,还有重要的元数据,比如病人信息
格式
https://dicom.nema.org/medical/dicom/current/output/html/part05.html
https://dicom.nema.org/medical/dicom/current/output/html/part06.html
dicom的格式主要分为4类,分别是:
- Patient Tag (病人信息)
- Study Tag(检查信息)
- Series Tag(序列信息)
- Image Tag(图像信息)
文件前言:128字节
DICOM前缀:DICM
文件元信息:格式上与数据元素一样,长度不定
数据元素格式:
- 小端隐式语法
- 小端显式语法
- 大端显式语法
大端和小端的区别与操作系统的大端小端一样
显示和隐式区别在于有没有值类型(VR)
隐式语法:
显示语法:
VR为OB、OW、OF、UT、UN、SQ时如下
VR为其他情况时如下
Patient Tag
Group(组号) | Element(元素号) | Tag Description | 中文解释 | VR |
---|---|---|---|---|
0010 | 0010 | Patient’s Name | 患者姓名 | PN |
0010 | 0020 | Patient’s ID | 患者ID | LO |
0010 | 0030 | Patient’s Birth Date | 患者出生日期 | DA |
0010 | 0032 | Patient’s Birth Time | 患者出生时间 | TM |
0010 | 0040 | Patient’s Sex | 患者性别 | CS |
0010 | 1030 | Patient’s Weight | 患者体重 | DS |
0010 | 21C0 | Pregnancy Status | 怀孕状态 | US |
Study Tag
Group(组号) | Element(元素号) | Tag Description | 中文解释 | VR |
---|---|---|---|---|
0008 | 0050 | Accession Number:A RIS generated number that identifies the order for the Study. | 检查号:RIS的生成序号,用以标识做检查的次序. | SH |
0020 | 0010 | Study ID | 检查ID. | SH |
0020 | 000D | Study Instance UID: Unique identifier for the Study. | 检查实例号:唯一标记不同检查的号码. | UI |
0008 | 0020 | Study Date: Date the Study started. | 检查日期:检查开始的日期. | DA |
0008 | 0030 | Study Time:Time the Study started. | 检查时间:检查开始的时间. | TM |
0008 | 0061 | Modalities in Study | 一个检查中含有的不同检查类型. | CS |
0008 | 0015 | Body Part Examined | 检查的部位. | CS |
0008 | 1030 | Study Description | 检查的描述. | LO |
0010 | 1010 | Patient’s Age | 做检查时刻的患者年龄,而不是此刻患者的真实年龄. | AS |
Series Tag
Group(组号) | Element(元素号) | Tag Description | 中文解释 | VR |
---|---|---|---|---|
0020 | 0011 | Series Number:A number that identifies this Series. | 序列号:识别不同检查的号. | IS |
0020 | 000E | Series Instance UID:Unique identifier for the Series. | 序列实例号:唯一标记不同序列的号码. | UI |
0020 | 0013 | Instance Number | 实例号 | IS |
0008 | 0060 | Modality | 检查模态(MRI/CT/CR/DR) | CS |
0008 | 103E | Series Description | 检查描述和说明 | LO |
0008 | 0021 | Series Date | 检查日期 | DA |
0008 | 0031 | Series Time | 检查时间 | TM |
0020 | 0032 | Image Position (Patient):The x, y and z coordinates of the upper left hand corner of the image, in mm. | 图像位置:图像的左上角在空间坐标系中的x,y,z坐标,单位是毫米.如果在检查中,则指该序列中第一张影像左上角的坐标. | DS |
0020 | 0037 | Image Orientation (Patient):The direction cosines of the first row and the first column with respect to the patient. | 图像方位 | DS |
0018 | 0050 | Slice Thickness:Nominal slice thickness, in mm. | 层厚. | DS |
0018 | 0088 | Spacing Between Slices | 层与层之间的间距,单位为mm | DS |
0020 | 1041 | Slice Location:Relative position of exposure expressed in mm. | 实际的相对位置,单位为mm. | DS |
0018 | 0023 | MR Acquisition | 收购者 | CS |
0018 | 0015 | Body Part Examined | 身体部位. | CS |
其中有2个重要的tag
tag:7fe0,0010,像素数据开始处
tag:0002,0010,决定普通tag的读取方式 little字节序还是big字节序,隐式VR还是显示VR。
代码
pydicom读取一张图
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import pydicom
if __name__ == '__main__':
# 读一张图片
ds = pydicom.read_file('series-00000/image-00000.dcm')
print(ds)
print()
print(ds.file_meta.get("TransferSyntaxUID"))
print(ds[0x20, 0xd])
print(ds[0x20, 0xe])
print(ds[0x20, 0x11])
print(ds[0x20, 0x13])
print(ds[0x0028, 0x1050])
print(ds[0x0028, 0x1051])
print()
# ds = pydicom.read_file('series-00000/image-00001.dcm')
# print(ds.file_meta.get("TransferSyntaxUID"))
# print(ds[0x20, 0xd])
# print(ds[0x20, 0xe])
# print(ds[0x20, 0x11])
# print(ds[0x20, 0x13])
# print(ds[0x0028, 0x1050])
# print(ds[0x0028, 0x1051])
simpleitk读取一系列图
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import SimpleITK as sitk
# Dicom序列所在文件夹路径(在我们的实验中,该文件夹下有多个dcm序列,混合在一起)
file_path = "series-00000"
# 获取该文件下的所有序列ID,每个序列对应一个ID, 返回的series_IDs为一个列表
series_IDs = sitk.ImageSeriesReader.GetGDCMSeriesIDs(file_path)
# 查看该文件夹下的序列数量
nb_series = len(series_IDs)
print(nb_series)
# 通过ID获取该ID对应的序列所有切片的完整路径, series_IDs[0]代表的是第一个序列的ID
# 如果不添加series_IDs[0]这个参数,则默认获取第一个序列的所有切片路径
series_file_names = sitk.ImageSeriesReader.GetGDCMSeriesFileNames(file_path, series_IDs[0])
# 新建一个ImageSeriesReader对象
series_reader = sitk.ImageSeriesReader()
series_reader.MetaDataDictionaryArrayUpdateOn() # 这一步是加载公开的元信息
# 通过之前获取到的序列的切片路径来读取该序列
series_reader.SetFileNames(series_file_names)
reader = sitk.ImageFileReader()
reader.SetFileName(series_file_names[0])
reader.LoadPrivateTagsOn()
reader.ReadImageInformation()
for k in reader.GetMetaDataKeys(): # 获取 key
print(k, reader.GetMetaData(k)) # 获取 key 对应的 MetaData
# 获取该序列对应的3D图像
image3D = series_reader.Execute()
print(image3D.GetMetaDataKeys())
# 查看该3D图像的尺寸
print(image3D.GetSize())
print(image3D.GetDirection())
image_array = sitk.GetArrayFromImage(image3D) # z, y, x
sitk.WriteImage(image3D, 'img3D.nii.gz')
NRRD
官网http://teem.sourceforge.net/nrrd/format.html
简介
NRRD(nearly raw raster data)不仅是一种库,也是一种文件格式,
旨在支持涉及 N 维栅格数据的科学可视化和图像处理
格式
NRRD000X
<field>: <desc>
<field>: <desc>
#<comment>
…
<field>: <desc>
<key>:=<value>
<key>:=<value>
<key>:=<value>
# <comment>
<data><data><data><data>…
开头固定NRRD,然后跟着000X,其中X代表版本号
前面是元数据
例如
type:后面data的数据类型
dimension:维度
space:物理空间坐标系,有冠状位,矢状位,水平位等
sizes:大小
后面是图像数据
代码
用pynrrd读
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import nrrd
# nrrd图片读取
nrrd_filename = 'average_template_25.nrrd'
nrrd_data, nrrd_options = nrrd.read(nrrd_filename)
print(nrrd_data)
print()
print(nrrd_options)
用simpleitk
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import SimpleITK as sitk
reader = sitk.ImageFileReader()
reader.SetFileName('average_template_25.nrrd')
reader.LoadPrivateTagsOn()
reader.ReadImageInformation()
for k in reader.GetMetaDataKeys(): # 获取 key
print(k, reader.GetMetaData(k)) # 获取 key 对应的 MetaData
print()
# image = sitk.ReadImage('average_template_25.nrrd', imageIO="NrrdImageIO")
image = sitk.ReadImage('average_template_25.nrrd')
image_array = sitk.GetArrayFromImage(image) # z, y, x
print(image_array)
Analyze7.5
官网:http://eeg.sourceforge.net/ANALYZE75.pdf
简介
由 Mayo Clinic 的 Biomedical Imaging Resource 团队开发的三维生物医学图像可视化和分析产品
后缀为.hdr/.img
成对出现,.hdr是头文件,.img是图像文件
头文件:
- 头文件信息(比如头文件大小)
- 图像信息(比如图片的维度)
- 其他信息(比如病人id)
NIFTI
简介
https://brainder.org/2012/09/23/the-nifti-file-format/
NIFTI格式是为了替代Analyze格式而产生的
因为Analyze缺少一些信息(如一些空间信息)
NIFTI兼容Analyze格式,并拥有更多的信息
后缀.nii、、.img/.hdr、.nii.gz、.img/.hdr.gz
- 因为兼容,所以有.img/.hdr
- 也可以合成一个文件.nii
- 因为有大量的0,所以有了后面的.gz
代码
nibabel
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import matplotlib
matplotlib.use('TkAgg')
from matplotlib import pylab as plt
import nibabel as nib
from nibabel.viewers import OrthoSlicer3D
example_filename = 'RibFrac1-image.nii.gz'
img = nib.load(example_filename)
print(img)
print(img.header['db_name']) # 输出头信息
# 由文件本身维度确定,可能是3维,也可能是4维
width, height, queue = img.dataobj.shape
OrthoSlicer3D(img.dataobj).show()
num = 1
for i in range(0, queue, 10):
img_arr = img.dataobj[:, :, i]
plt.subplot(5, 4, num)
plt.imshow(img_arr, cmap='gray')
num += 1
plt.show()
simpleitk
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import SimpleITK as sitk
from matplotlib import pyplot as plt
def showNii(img):
for i in range(img.shape[0]):
plt.imshow(img[i, :, :], cmap='gray')
plt.show()
itk_img = sitk.ReadImage('RibFrac1-image.nii.gz')
img = sitk.GetArrayFromImage(itk_img)
print(img.shape) # (155, 240, 240) 表示各个维度的切片数量
showNii(img)
simpleitk
这是一个库,不是格式
SimpleITK.ReadImage可以读这些格式
• BMPImageIO ( *.bmp, *.BMP )
• BioRadImageIO ( *.PIC, *.pic )
• Bruker2dseqImageIO
• GDCMImageIO
• GE4ImageIO
• GE5ImageIO
• GiplImageIO ( *.gipl *.gipl.gz)
• HDF5ImageIO
• JPEGImageIO ( *.jpg, *.JPG, *.jpeg, *.JPEG )
• LSMImageIO ( *.tif, *.TIF, *.tiff, *.TIFF, *.lsm, *.LSM )
• MINCImageIO ( *.mnc, *.MNC )
• MRCImageIO ( *.mrc, *.rec )
• MetaImageIO ( *.mha, *.mhd )
• NiftiImageIO ( *.nia, *.nii, *.nii.gz, *.hdr, *.img, *.img.gz )
• NrrdImageIO ( *.nrrd, *.nhdr )
• PNGImageIO ( *.png, *.PNG )
• StimulateImageIO
• TIFFImageIO ( *.tif, *.TIF, *.tiff, *.TIFF )
• VTKImageIO ( *.vtk )