Slicer加载DICOM性能优化初探索
本文由Markdown语法编辑器编辑完成.1. 需求背景近期遇到一个实际的问题, 就是当使用Slicer加载一个序列的DICOM数据时, 性能比较慢. 特别是配置比较低的服务器上, 加载时间更是非常长. 而且由于这些DICOM数据不是本地加载, 而是必须连接一个服务器将DICOM首先下载到本地, 然后再进行加载.在一家省级机构中, 经过测试, 一个约300张的序列, 经过下载和本地加载, 约需要6
本文由Markdown语法编辑器编辑完成.
1. 需求背景
近期遇到一个实际的问题, 就是当使用Slicer加载一个序列的DICOM数据时, 性能比较慢. 特别是配置比较低的服务器上, 加载时间更是非常长. 而且由于这些DICOM数据不是本地加载, 而是必须连接一个服务器将DICOM首先下载到本地, 然后再进行加载.
在一家省级机构中, 经过测试, 一个约300张的序列, 经过下载和本地加载, 约需要60s的时间. 这对于时间珍贵的用户来说, 就是不可原谅的. 所以, 如何优化下载和加载DICOM的性能, 就成了重中之重.
先说结果, 经过我们的优化和实际测试, 加载时间从原来的60s, 减少到了15s, 优化了75%的性能. 那么是怎么优化的呢, 以下是一个简要的介绍.
2. 优化思路
思路1:
第一种思路,主要是优化下载的速度。因为原来是一个线程,去依次请求服务器端,获取DICOM的图像。如果一个序列有300张图像,那么就需要发送300个request请求。
能够想到的是,采用多线程的方式下载。这样,可以并行地下载,但是并没有解决一个序列多次请求地问题。
而且经过测试,下载和加载序列的时间相当。如果加载序列没办法优化,最后还是无法达到整体优化的目的。
思路2:
第二种思路的核心就是,化整为零。这个思想,是借鉴于3d Slicer的官方开发者的一段描述。这段描述的主要意思就是,如果能够把一个DICOM的序列转化成一个nrrd格式的文件,那么在加载时就可以获得1~2个数量级的性能提升。

根据红色框内的文字,我们一下子就感觉看到了希望。因为如果这个方案是可行的化,那么我们既优化了下载的性能,又优化了加载的性能。
优化下载的性能,是因为我们不再需要每下载一张文件都发一个http的请求了;
加载优化,则是不再需要使用DICOM模块来逐张分析dicom, 而是以一个体数据的方式,直接加载到内存中。
剩下的,主要就是根据一个DICOM的序列,生成一个三维体数据了。
这里要注意,在医学影像中,三维体数据有很多不同的格式或后缀名。nrrd, nii.gz, …
以下是根据DICOM序列的路径,生成nii.gz文件的参考代码:
import numpy as np
reader = sitk.ImageSeriesReader()
dicomReader = reader.GetGDCMSeriesFileNames(series_path) #input is the DCM file path
reader.SetFileNames(dicomReader)
dicoms = reader.Execute()
sitk.WriteImage(dicoms, fileName) #fileName like "brain.nrrd/brain.nii.gz"
当生成类似brain.nii.gz的三维体数据时,在Slicer中,可以直接利用:
slicer.util.loadVolume(brain.nii.gz)
来实现加载体数据的目的。
但是这个会引起一个问题,就是直接加载体数据,会使Slicer的三个视图中的四角信息无法正常显示。
如果对于四角信息没有太多的需求,到这里就结束了。
但是,如果对于四角信息有强制显示的需求时,还需要做一些额外的工作才可以。主要就是,需要修改四角信息依赖的模块DataProbe中的一些源码。
更多推荐
所有评论(0)