Slicer渲染Dicom到nrrd
工作中遇到一些处理Dicom数据的需求,个人通过网络上的一些教程
对于原始数据尝试转换到nrrd时,发现部分的窗体数据的渲染方向不一致
进一步发现这些很多定义的方向是跟设备厂家强相关的,不同厂家对于同一段的Dicom参数都有不同的实现方式,所以这个模块个人调整了一段时间还是不够满意
现阶段打算借助这些渲染医学影像的工具代码进行辅助处理,以减少这些繁琐的数据转换步骤
文章目录
- Slicer渲染Dicom到nrrd
- 一、Slicer源码跟踪
- 二、功能块封装
- 2.1 初级逻辑校验
- 2.2 开始逻辑封装
- 2.3 使用Slicer进行调用
- 三、写在末尾
一、Slicer源码跟踪
Slicer是一个相当大的工程,对于这种工程的探索感觉只能用好全局搜索+凭直觉猜测的方式进行
- 搜索DICOM database相关的组件
- Slicer的插件通常分为一组定义、一组UI、一组逻辑
- 所以按照上诉逻辑开始进行搜索
- 在相关源码中出现了一些browser相关的字眼,我们猜测相关的逻辑代码应该在进一步跳转的DICOMLib中
2. 猜测SlicerDICOMBrowser的调用函数
- 主要使用load相关的字眼去搜索找到了一个类似的实现类
3. 探索DICOMUtils
- 出现了读取序列的类似方法,猜测链猜测应该正确继续
4. 寻找操作实现插件
- 函数读取了一个外部插件,作为最终执行函数
5. 使用常见的现象对源码进行重定向
- 通常来说读取到Slicer内的数据会被封装成一个Scalar数据
- 所以我们去追踪DICOMScalarVolumePlugin,并查看其是否存在Load函数
- 最终找到了参数的封装loadFilesWithSeriesReader
- 找到目标封装
二、功能块封装
2.1 初级逻辑校验
- 在Slicer的交互式控制台中输入下方图示的代码
- 对象可以被正常创建,函数也可以正常调用,说明之前的探索逻辑可行
- (这里有数据的人可以按照函数所需的参数填写进去,是可以创建节点并渲染数据的)
2.2 开始逻辑封装
Slicer是可以执行外部用户脚本的,参数可以使用类c风格进行传递,也可以直接内部写死,直接调用即可
- 逻辑封装就是按照2.1的部分创建一个py脚本
- 初始化相关的类,并填写相关的参数
核心封装部分
plugins = slicer.modules.dicomPlugins['DICOMScalarVolumePlugin']()
...........
try:node = plugins.loadFilesWithSeriesReader(format, files, "reader")slicer.util.saveNode(node, output)slicer.mrmlScene.RemoveNode(node)slicer.app.processEvents() # 让UI临时更新一下,非ui模式注释掉
except Exception as e:logging.error(str(e))
...........
2.3 使用Slicer进行调用
- 这部分比较简单,相关参数可以去slicer论坛进行查询
- 但需要注意的是,slicer的相关执行只能通过返回值进行判断(😐 主要是没找到slicer脚本输出内容的重定向相关)
def run_slicer_script():command = [slicer_exe,"--python-script",script_path,自定义脚本参数1]result = subprocess.run(command)print(result.returncode)
三、写在末尾
- 示例封装压缩包: https://download.csdn.net/download/qq_34524246/91359684
- Slicer执行外部脚本论坛: https://discourse.slicer.org/t/how-to-run-python-script-in-slicer/12352
- 最后放一张脚本通过二次封装让CPU 100%工作的图