Slicer加载DICOM性能优化初探索

Posted inter_peng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Slicer加载DICOM性能优化初探索相关的知识,希望对你有一定的参考价值。

本文由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中的一些源码。

以上是关于Slicer加载DICOM性能优化初探索的主要内容,如果未能解决你的问题,请参考以下文章

Slicer加载DICOM性能优化初探索

3d Slicer-DICOM模块之Query/Retrieve功能介绍

3d Slicer-DICOM模块之Query/Retrieve功能介绍

怎么用医学影像分析软件3D Slicer打开DICOM文件

Nginx 初探

初探性能优化!从2个月到4小时的性能提升!