赞
踩
近日做医疗影像处理相关的内容,感慨于这方面资料不全、散碎,遂记录自己获得的一些资料以供日后查阅。
DICOM 是医学图像和相关信息的国际标准,它定义了满足临床需要的可用于数据交换的医学图像格式,被广泛用于放射、成像的诊疗诊断设备。也就是说,在医院放射科使用的设备上读取的影像基本都是DICOM格式,包括CT、MRI、超声等。
DICOM格式的图像,每一张都带有除像素(体素)信息之外的大量信息。其信息组成主要有以下几部分:
此处涉及矢状面、冠状面、横断面
简单的记忆方式是:矢状面即一支箭射中人所形成的面,正中二分人体。
冠状面可想象古代官帽,从头顶向地面的切面。
横断面即腰斩平面。
在下图中,红色切面为矢状面,紫色切面为冠状面,绿色切面为横断面。
六元组所表示的,即是与这三个面的夹角关系,以余弦值呈现。
影像上,正方向为L、S、P。
用(x1,x2,x3,y1,y2,y3)来表示的话,x1、x2、x3分别表示x轴与L、P、S间的夹角余弦值,y1、y2、y3则表示y轴与L、P、S间的夹角余弦值。
使用这个六元组可以判断图像区域是否为矩形(两向量点乘为0),以及与解剖学坐标的关系。当这个六元组只含有0、1、-1时,代表切片一定与某解剖学平面平行。
更多内容可以参见此博客,讲解得很详细。
https://blog.csdn.net/zssureqh/article/details/61636150
除了上述四个部分 tag 信息外,就是 PixelData 信息。此处存储的既是该张切片的像素信息。
DICOM 文件可以使用 pydicom 库来进行读写,该库提供了非常全面的操作。
在 vscode 中搜索 dicom 有一个插件可以用来看 dicom 文件信息。
segmentatiom 是对 DICOM 序列文件进行器官分割、靶区勾画后的结果,以 nifti 格式给出(也可以为其他格式,但存储形式基本都是裸数据,直接给出分割结果的数组)。其中的信息为三维数组形式,每个体素点存储该点对应图像的分割结果:
- 0:代表此点为background,或此次标注中不关注的区域
- 1~n:代表此点为对应的区域。
- 其中 1~n 所代表的器官、区域由分割程序定义
RT structure 文件是导入到放疗系统中所需的 DICOM 文件,其中存储了每个结构区域的组成,以及相对应的原始 DICOM 序列标识和部分病人信息。其主要结构分为三个部分:
若要解析 RT structure 文件可以从以上三部分入手
近期所做的工作主要是将已经生成的分割、勾画信息结合原始的 DICOM 序列文件,生成 RT structure 文件(后简称 RTs ),以供医生后续使用。
主要思路为:nifti->mha->RTs
mha 是一种 metadata 格式,其中存储了头部信息和像素信息。与 mha 格式类似的是 mhd 格式,区别在于 mhd 将头部信息存储于一个单独的 .raw 文件中,本身只存储数据信息。
上图即为一个 mha 文件所存储的头部信息,可以看到,它存储了维度、原点、方向、像素间距等信息,这部分信息在后续构建 RTs 时是非常重要的。
那么,在初步了解 mha 文件的构成后,要将 nii 文件转换为 mha 文件就比较简单了。
思路为:
一个简单的可执行示例代码如下:
- import SimpleITK as sitk
- import pydicom
- reader=sitk.ReadImage("labels.nii")
- referencect=pydicom.read_file("file_path.dcm")##输入参考的 dicom 文件,一个即可
-
- ConstPixelSpacing =(float(referencect.PixelSpacing[0]), float(referencect.PixelSpacing[1]), float(referencect.SliceThickness))
-
- Origin = referencect.ImagePositionPatient
-
- img=sitk.GetArrayFromImage(reader) #z y x
- img2=sitk.GetImageFromArray(img) #z y x
- img2.SetSpacing(ConstPixelSpacing)
- img2.SetOrigin(Origin)
- sitk.WriteImage(img2,"testmha.mha")
上例代码仅显示如何构建一个 mha 文件,在 nii 转化 mha 中还有很多细节需要主要:
offset
项,该项将影响到构建 RTs 时切片的走向。例如若你选择的 DICOM 文件为切片中最顶部的一张,则你的整个结构由于层厚大于0,将向上生长,与真实结构相反。因此选择哪张切片作为参考,要结合层厚来确定。通常层厚大于0,因此选择最底部的切片作为参考。将 mha 转换为 RTs 文件是一个比较棘手的问题,一开始我预备在了解 RTs 文件的结构后,手动构造 RTs 文件,但考虑到可靠性(有可能信息转换不完全或兼容性不够好,毕竟医学的东西谨慎一点更好),最终没有采用手动构造的方法,而是使用了 plastimatch 这个比较成熟的软件来进行。但不排除后续使用自己写的代码来完成这个步骤的可能性。
plastimatch 提供了 DICOM RT 导出功能,支持从 mha 文件导出 RTs,同时也支持 nii 导出 RTs。
在我成功从 mha 导出 RTs 后,试图简化步骤直接从 nii 到 RTs,但经过尝试后发现 nii 到 RTs 的结果与 mha 到 RTs 并不相同(很奇怪),且并不正确,同时,从 nii 到 RTs 所需的时间非常久,在五分钟以上,而使用 nii->mha->RTs 耗时不到 30s
这个结果令人费解,mha 文件的信息都是从 nii 中解析得到,导出 RTs 所使用的参考 dicom 序列也都相同,却导向了不同的结果。我最初猜测是由于 nii 中数组方向可能有问题,但在我修改方向重写 nii 后结果依然不对。
那么在安装 plastimatch 后,使用如下三条指令即可使用 mha 生成 RTs:
- plastimatch adjust --input testmha.mha --pw-linear "0,0,1,1,2,2,3,4,4,8,5,16" --output TEMP-1.mha
- plastimatch convert --input TEMP-1.mha --output-img TEMP-2.mha --output-type uint32
- plastimatch convert --input-ss-img TEMP-2.mha input-ss-list structure_ref.txt --referenced-ct renference_files/ --output-dicom DICOM-OUT
接下来解释一下上述三条指令:
input-ss-list structure_ref.txt
后续阐述。referenced-ct renference_files/
指定要参考的 DICOM 序列所在的文件夹,最终将在 DICOM-OUT
目录下生成 RTs 文件。该文件遵循下述格式:
- 0|0 255 0|Bladder
- 1|0 0 255|Femoral_Head-L
- 2|255 0 255|Femoral_Head-R
- 3|0 255 255|Femur-L
- 4|255 255 0|Femur-R
- 5|122 122 122|Rectum
在未指定该文件时,生成的 RTs 文件中结构名是没有指定的,将以 unknown structure 的名字呈现,这对后续医生的操作是不利的,因此需要指定上述文件,以形成 value-color-structure_name 的对应关系。此处的 value,即 0、1、2...等值,是指对应 bit 位为 1。因此前述第一条指令的转换操作就是不可缺少的,将普通的值转换为对应的 bit 位为 1 的值,才能正确标识结构名字。
此处列出一些可能有用的库:
SimpleITK:支持较多格式的文件,提供了一些处理图像内容的操作。
pydicom:提供对 DICOM 文件读写、修改的操作。
itk、vtk:前者提供处理,后者提供显示,是医学影像处理中常用的库。
dicom2nifti:dicom 文件转 nii 文件等操作。
gdcm2vtk:提供 vtk 支持的格式文件转换 dicom 文件等操作。
此外还有 gdcm、dcmtk 等库尚未详看。
plastimatch 这个软件也提供了很丰富的功能,最重要的是在它的 mail list 中,开发者会回复使用相关问题。
后续可能会调研图像显示相关的资料并更新。
不过没搞明白一通操作下来是什么目的,既然已有勾画信息,再弄rts有什么其他用途
因为勾画信息不是医生做的,是用AI做的。AI做的勾画信息不是RTs结构的,医生没办法在现在的放疗系统上使用,所以要转一下。
mha可以转回nii吗?要怎么转?
从mha文件里面提取像素信息,然后保存为nii就可以了,nii本质上就是裸数据
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。