SimpleITK、pydicom的安装使用——踏上python生物医学图像处理的初学之路_Kerkoporta-CSDN博客
SimpleITK、pydicom的安装使用——踏上python生物医学图像处理的初学之路
前言:19年4月份的时候已经被录取了,有幸被贾博士收入麾下。那段时间不打算放过那个假期,正好导师联系我说有一个医学图像处理的项目来做,于是一面做项目一面在读tf1.0的实战。7月中旬的时候第一次去了实验室,见识了团队的朋友们。还有我们的八卡服务器。现在回想起来那时候真的是非常的幸福。
这一篇来总结之前做过的一些初步的工作,主要包括SimpleITK和pydicom的安装和使用。预计下一期会分析一下对应数据的文件头,里面包含了很多信息,对于处理和分析医学CT很有帮助。
一、两个库的安装
pip均可直接安装。这里说说conda怎么安装SimpleITK。首先这个库是不在默认的channel里面的所以不能够直接安装。因此需使用:
anaccnda search SimpleITK
来寻找SimpleITK库的channel。应该会在结果当中找到SimpleITK/SimpleITK这个"channel/package"的项目。然后:
anaconda show SimpleITK/SimpleITK
这样会显示如何安装这个包的代码,在命令行里复制它并运行即可安装。
需要多说的一点是,这些库的安装往往要从外网上获取。因此需要修改conda和pip的安装源,或者在pip安装时使用-i选项来临时选择安装网站。这里推荐清华和阿里云的网站,速度很快很舒服:
pip install $package -i https://pypi.tuna.tsinghua.edu.cn/simple
"所有的扫描数据无论是二维还是三维都需要转化为numpy数组再行处理,因此以下入门部分只涉及到读取"
二、SimpleITK的初步使用
SimpleITK使用的是.mhd为后缀的立体CT扫描文件。这个文件在一些竞赛当中非常常见,而我们在实验中获取到的所有的数据都是.dcm格式的。以上发言可能带有很大的偏见,还是想建议大家要以dicom文件处理为主。我搜索了一些网页,发现有关mhd文件的介绍非常匮乏,因此对它我也没有非常深入的认识。如果以后还有机会学到相关内容的话,我会重新写这一段。
整个使用到的文件包含两个部分:mhd文件和同名raw文件。mhd文件本身非常小,包含了dicom的文件头信息。类似于摄影中的raw文件的概念,raw文件应该保存了所有扫描的图像数据,因此它的体积也非常大。两个文件具有相同的文件名,这个文件名是全球唯一的CT扫描文件定位码。
读取:
SimpleITK读取mhd文件相对简单。只需要导入simpleitk库并读取mhd文件即可,注意不是raw文件:
import SimpleITK as sitk$inputImage =sitk.ReadImage($filePath)
一般来讲这样的数据是三维的数据,也就是将连续的数个二维扫描图像打包。读出的数据有三个维度,"与常识不同,这三个维度是反着排列的inputimage[z,y,x]"。然后需要使用函数将三维图像转化为numpy数组:
$numpyImage = sitk.GetArrayFromImage($inputImage)
如此一来就读取完成了。一般来讲这两个过程一气呵成,所以为了方便可以直接封装成函数:
"""读取mhd文件"""def read_MHD(filePath):RdImage =sitk.ReadImage(filePath)xSize, ySize, zSize = RdImage.GetSpacing() #使用.GetSpacing()函数来获取图像的三个维度MHDImage = sitk.GetArrayFromImage(RdImage)return RdImage,MHDImage,xSize,ySize,zSize
查看:
当拿到这个三维的矩阵以后,就可以非常方便的便利、查看。通常的CT扫描是横切面断层成像,使用获取到的三位数据,不仅可以获取到横切面的图像,还可以是冠状面以及矢状面。关于每个面需要展示那个维度是高中立体几何知识的推理,这里不做讨论。下面举个展示的例子,如果想要展示冠状面的某个面,冠状面的横纵坐标分别是x和z,那意味着我们需要抽取某张y轴的一张截面中的所有x和z轴信息:
plt.imshow(image3d[:,330, :])
当然,展示的这张图片是经过了H.U.和阈值处理的,提取了CT的骨组织,并且经过了标注。
三、Pydicom的初步使用
Pydicom使用的是一系列单张的.dcm文件,需要注意的是,当我们获取到这些数据的时候需要做审查,查看所有的dcm图像是否连续具有因果联系。这是因为医院为了缓解诊断和存储的压力,很有可能会提供只含有部分切片、含有病理表现的的信息,其余的部分有可能会被删除。当然,这样的数据也是能够使用的,只是需要在研究之前明确自己的数据是否有缺失以免造成虚假的成分。
Pydicom文件的读取相对繁琐很多,因为需要遍历几个目录并且一张张的来读取.dcm文件。这一部分需要我们自行进行构建,所以这里主要是抛砖引玉,展示一下这边处理读取dcm文件所使用的代码:
import pydicom as dicom"""读取文件夹下的dicom文件"""def read_dicoms(filePath):os.chdir(filePath)xScl, yScl, zScl =0,0,0path_file_number=glob.glob(pathname='*.DCM') #获取当前文件夹下个数if path_file_number==0:path_file_number=glob.glob(pathname='*.dcm')RdImage=[]for dcmCnt in range(len(path_file_number)):if os.path.exists(filePath+str(dcmCnt)+'.DCM'):readDCM = dicom.read_file(filePath+str(dcmCnt)+'.DCM')xScl, yScl = readDCM.PixelSpacingzScl = readDCM.SliceThicknessRdImage.append(readDCM.pixel_array)elif os.path.exists(filePath+str(dcmCnt)+'.dcm'):readDCM = dicom.read_file(filePath+str(dcmCnt)+'.dcm')xScl, yScl = readDCM.PixelSpacingzScl = readDCM.SliceThicknessRdImage.append(readDCM.pixel_array)Image3D = np.array(RdImage)return Image3D, RdImage, xScl, yScl, zScl
函数的输入与simpleik不同,后者输入一个文件名,而前者需要一个具体的路径。那么细心的朋友可能已经发现了程序对不同大小写的文件后缀做了区分,并且返回了numpy数据以及原始读入数据。三维矩阵的操作与simpleitk是一样的。
到此结束。