如何在python调用slicer扩展模块swiss skull stripping

软件版本:3D Slicer=5.2.2,python=3.7
问题描述:我想在自己的python中调用slicer扩展模块swiss skull stripping,并且对多个患者批量处理数据、保存处理结果到指定文件夹。请问要如何实现?求帮助!

通过学习3D Slicer community里的回答 Swiss Skull Stripper: troubles invoking from python console - Development - 3D Slicer Community
,我发现 SwissSkullStripperExtension/SwissSkullStripper/SwissSkullStripper.xml at master · lorensen/SwissSkullStripperExtension有助于帮助调用SwissSkullStripper模块以及设置参数,注意“p”小写

以下是我尝试在3Dslicer的python控制台调整的输入代码及反馈截图。
但是,我现在仍然不知道该怎么设置一个新建的输出,在patient output volume我是直接占用输入的patient volume回避了这个问题,patient mask label我该怎么用代码给它设置?如果有懂的大佬,请指点一下,谢谢!

我尝试修改代码新建volume并调用swissskullstripper,我成功调用了skissskullstripper,代码如下,但是我遇到了新问题,这样设置的volume,最后输出得到patientOutputVolume颜色看起来不太对


,不明白这是什么原因,该如何调整?

#for 3D slicer-extension module-swiss skull stripping
import slicer
# 加载患者和atlas图像
PatientVolume = slicer.util.loadVolume(r'E:\path\T1F.nii')
AtlasVolume = slicer.util.loadVolume(r'E:\\3Dslicer\atlas\atlasImage.nrrd')
AtlasMask = slicer.util.loadSegmentation(r'E:\\3Dslicer\atlas\atlasMask.nrrd')
labelVolumeNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLLabelMapVolumeNode')
patientmasklabel = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLLabelMapVolumeNode')
labelVolumeNode.SetName('patientOutputVolume')
patientmasklabel.SetName('patientMaskLabel')
# 设置参数
parameters = {}
parameters["patientVolume"] = PatientVolume.GetID()
parameters["patientMaskLabel"] = patientmasklabel.GetID()
parameters["atlasMRIVolume"] = AtlasVolume.GetID()
parameters["atlasMaskVolume"] = AtlasMask.GetID()
parameters["patientOutputVolume"] = labelVolumeNode.GetID() # 您可以指定一个输出体积节点

# 调用 swiss skull stripping
SSS=slicer.modules.swissskullstripper
cliNode=slicer.cli.runSync(SSS, None, parameters)

我给patientoutputvolume先赋予了patientvolume后再调用swissskullstripper,颜色(信号)对了,但还是很好奇怎么样创建outputvolume才是正确的方式

测试代码比较浪费时间,还好完成了,请参照注意事项进行应用。

解释:

  1. 导入的库:脚本使用 slicer 进行 3D 医学图像处理,并使用 os 进行文件处理。
  2. runSwissSkullStripper 函数:此函数接受患者和 atlas 体积的路径,使用 Swiss Skull Stripper 模块处理图像,并将输出保存到指定的文件夹中。
    • slicer.util.loadVolume 用于加载体积数据。
    • 参数被设置为 Swiss Skull Stripper 使用,包括患者体积、atlas 体积、atlas 掩膜和输出节点。
    • 使用 slicer.cli.runSync 同步运行,确保处理完成后再进行下一步。
    • 输出体积文件使用与输入体积一致的命名规则保存。
  3. batchProcessSwissSkullStripper 函数:此函数处理多个患者体积。
    • 它列出提供的文件夹(patientVolumeFolder)中的所有体积文件并逐一处理。
    • 对每个患者体积,创建一个以体积名称命名的输出文件夹,并调用 runSwissSkullStripper 函数。
    • 输出文件夹和文件都使用输入体积的名称,方便管理和查找。
  4. 示例用法:最后一部分定义了患者体积、atlas 图像和输出文件夹的路径。
    • 然后调用 batchProcessSwissSkullStripper 函数处理这些参数。

注意事项

  • 硬件需求:Swiss Skull Stripper 可能会占用大量计算资源。处理大量患者时,可能会对计算机的 CPU 和内存造成较大负载。建议在具有足够资源的工作站上运行该脚本。
  • 并行处理:脚本以同步方式运行,即每个患者体积一个接一个地处理。如果患者数量较多,可以考虑实现并行处理或使用集群,以节省时间。
  • 磁盘空间:确保输出目录(outputFolderBasePath)有足够的磁盘空间存储所有处理过的体积文件,因为医学图像文件通常非常大。
  • 数据完整性:始终验证所有输入文件是否有效且未损坏,以防止在处理过程中出现意外错误。
  • 错误处理:当前脚本未包含错误处理。建议添加 try-except 块来处理文件读取错误、处理失败等情况,以实现更健壮的工作流。
# 导入必要的库
import slicer
import os

# 函数:对单个患者体积运行 Swiss Skull Stripper
def runSwissSkullStripper(patientVolumePath, atlasVolumePath, atlasMaskPath, outputFolderPath):
    # 加载患者和 atlas 体积
    PatientVolume = slicer.util.loadVolume(patientVolumePath)
    AtlasVolume = slicer.util.loadVolume(atlasVolumePath)
    AtlasMask = slicer.util.loadSegmentation(atlasMaskPath)

    # 创建用于输出的标签图节点
    patientOutputVolumeNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLLabelMapVolumeNode')
    patientMaskLabelNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLLabelMapVolumeNode')
    patientOutputVolumeNode.SetName('patientOutputVolume')
    patientMaskLabelNode.SetName('patientMaskLabel')

    # 为 Swiss Skull Stripper 设置参数
    parameters = {}
    parameters["patientVolume"] = PatientVolume.GetID()
    parameters["patientMaskLabel"] = patientMaskLabelNode.GetID()
    parameters["atlasMRIVolume"] = AtlasVolume.GetID()
    parameters["atlasMaskVolume"] = AtlasMask.GetID()
    parameters["patientOutputVolume"] = patientOutputVolumeNode.GetID()

    # 同步运行 Swiss Skull Stripper
    SSS = slicer.modules.swissskullstripper
    cliNode = slicer.cli.runSync(SSS, None, parameters)

    # 将输出文件保存到指定的文件夹中,文件名与输入体积一致
    patientVolumeName = os.path.basename(patientVolumePath).split('.')[0]
    outputVolumePath = os.path.join(outputFolderPath, f'{patientVolumeName}_output.nii')
    outputMaskPath = os.path.join(outputFolderPath, f'{patientVolumeName}_mask_label.nii')
    slicer.util.saveNode(patientOutputVolumeNode, outputVolumePath)
    slicer.util.saveNode(patientMaskLabelNode, outputMaskPath)

    # 返回保存的文件路径
    return outputVolumePath, outputMaskPath

# 函数:批量处理多个患者
def batchProcessSwissSkullStripper(patientVolumeFolder, atlasVolumePath, atlasMaskPath, outputFolderBasePath):
    # 列出文件夹中的所有患者体积文件
    patientVolumePaths = []
    for fileName in os.listdir(patientVolumeFolder):
        if fileName.endswith(".nii") or fileName.endswith(".nrrd"):
            patientVolumePaths.append(os.path.join(patientVolumeFolder, fileName))

    # 批量处理每个患者体积文件
    for patientIndex, patientVolumePath in enumerate(patientVolumePaths):
        # 创建以患者体积命名的输出文件夹
        patientVolumeName = os.path.basename(patientVolumePath).split('.')[0]
        patientOutputFolder = os.path.join(outputFolderBasePath, patientVolumeName)
        os.makedirs(patientOutputFolder, exist_ok=True)

        # 运行 Swiss Skull Stripper 并保存结果
        outputVolumePath, outputMaskPath = runSwissSkullStripper(
            patientVolumePath, atlasVolumePath, atlasMaskPath, patientOutputFolder
        )

        print(f"已处理患者 {patientIndex + 1} ({os.path.basename(patientVolumePath)}):\n  输出体积: {outputVolumePath}\n  输出掩膜: {outputMaskPath}")

# 批量处理的示例用法
patientVolumeFolder = r'E:\swiss\patient Volume'
atlasVolumePath = r'E:\swiss\atlasmask\atlasImage.nrrd'
atlasMaskPath = r'E:\swiss\atlasmask\atlasMask.nrrd'
outputFolderBasePath = r'E:\swiss\output_volume'

batchProcessSwissSkullStripper(patientVolumeFolder, atlasVolumePath, atlasMaskPath, outputFolderBasePath)

# 解释:
# 1. **导入的库**:脚本使用 `slicer` 进行 3D 医学图像处理,并使用 `os` 进行文件处理。
# 2. **runSwissSkullStripper 函数**:此函数接受患者和 atlas 体积的路径,使用 Swiss Skull Stripper 模块处理图像,并将输出保存到指定的文件夹中。
#    - `slicer.util.loadVolume` 用于加载体积数据。
#    - 参数被设置为 Swiss Skull Stripper 使用,包括患者体积、atlas 体积、atlas 掩膜和输出节点。
#    - 使用 `slicer.cli.runSync` 同步运行,确保处理完成后再进行下一步。
#    - 输出体积文件使用与输入体积一致的命名规则保存。
# 3. **batchProcessSwissSkullStripper 函数**:此函数处理多个患者体积。
#    - 它列出提供的文件夹(`patientVolumeFolder`)中的所有体积文件并逐一处理。
#    - 对每个患者体积,创建一个以体积名称命名的输出文件夹,并调用 `runSwissSkullStripper` 函数。
#    - 输出文件夹和文件都使用输入体积的名称,方便管理和查找。
# 4. **示例用法**:最后一部分定义了患者体积、atlas 图像和输出文件夹的路径。
#    - 然后调用 `batchProcessSwissSkullStripper` 函数处理这些参数。

# **注意事项**:
# - **硬件需求**:Swiss Skull Stripper 可能会占用大量计算资源。处理大量患者时,可能会对计算机的 CPU 和内存造成较大负载。建议在具有足够资源的工作站上运行该脚本。
# - **并行处理**:脚本以同步方式运行,即每个患者体积一个接一个地处理。如果患者数量较多,可以考虑实现并行处理或使用集群,以节省时间。
# - **磁盘空间**:确保输出目录(`outputFolderBasePath`)有足够的磁盘空间存储所有处理过的体积文件,因为医学图像文件通常非常大。
# - **数据完整性**:始终验证所有输入文件是否有效且未损坏,以防止在处理过程中出现意外错误。
# - **错误处理**:当前脚本未包含错误处理。建议添加 try-except 块来处理文件读取错误、处理失败等情况,以实现更健壮的工作流。


要处理数据目录 = E:\swiss\patient Volume’
atlasVolume目录 = E:\swiss\atlasmask\atlasImage.nrrd’
atlasMask目录 = E:\swiss\atlasmask\atlasMask.nrrd’
输出文件目录(自动生成) = E:\swiss\output_volume’


atlasImage.nrrd (3.5 MB)
atlasMask.nrrd (134.2 KB)