- 医疗健康
- 图像处理
- 数据可视化
- 桌面应用
- 3D渲染
【免费下载链接】Slicer
Multi-platform, free open source software for visualization and image computing.
导读
Segmentations(分割)模块是 Slicer 中管理医学图像分割数据的核心模块。它基于“多表示(polymorph representation)”架构:一个分割可包含多个节段(segment),每个节段可同时持有体数据(binary/fractional labelmap)与表面网格(closed surface)等多种表示,并支持自动转换、精细的显示控制和完整的导入/导出能力。读完本文,你将掌握如何在 2D/3D 视图中查看分割、从 NRRD/NIfTI/STL/OBJ 等文件导入既有分割、将分割导出为模型文件与 labelmap 体数据、配置表示转换参数(如过采样因子)以及完成 DICOM 导出。
模块概览:分割、节段与多表示架构
Segmentations 模块负责管理“分割(segmentation)”这一数据对象。每个分割可以包含多个节段(segment),每个节段对应一个解剖结构或感兴趣区域(ROI)。核心特点是:同一结构可以同时拥有多种数据表示(representation),模块支持这些表示之间的自动转换。默认的表示类型包括:平面轮廓(Planar contour)、二值标签图(Binary labelmap)和闭合表面模型(Closed surface)。
这一架构带来的典型用途包括:
- 在 2D 切片视图和 3D 视图中可视化解剖结构;
- 将 ROI 定义为后续分析的输入(如体积测量、用于影像组学特征计算的掩膜等);
- 从图像生成表面网格,用于 3D 打印;
- 编辑 3D 闭合表面。
该基础设施的动机、特性与细节可参考论文Cs. Pinter, A. Lasso, G. Fichtinger, "Polymorph segmentation representation for medical image computing", Computer Methods and Programs in Biomedicine, Volume 171, p19-26, 2019(DOI: 10.1016/j.cmpb.2019.02.011)及相关博士论文。
数据容器结构:从源码理解“分段-多表示”模型
仓库中Libs/vtkSegmentationCore库的 vtkSegmentation.h 对此有非常清晰的示意:一个 Patient(vtkSegmentation)容器内包含多个节段(如 Brain、Tumor 两个vtkSegment),每个节段内部再按表示类型存放不同的 VTK 数据对象:
| 表示类型 | 底层 VTK 数据类型 | 说明 |
|---|---|---|
| Binary labelmap | vtkOrientedImageData | 二值体数据,体素值 >0 为前景(内部),≤0 为背景(外部) |
| Fractional labelmap | vtkOrientedImageData | 分数标签图,保存部分体积/概率信息 |
| Closed surface | vtkPolyData | 闭合表面网格 |
| 自定义表示 | vtkDataObject子类 | 可由扩展模块注册,如 SlicerRT 增加了 Planar contour、Ribbon model |
vtkSegment中保存的是同一结构的多种表示,vtkSegmentation则提供分段层面的通用操作:按指定表示转换、提取几何信息、复制/移动节段等。需要注意的是,同一分割内所有节段拥有相同的表示集合:当节段被复制/移动到另一个分割时,若目标分割无法提供相应表示,转换会尽量自动完成,否则复制会失败。
转换图与转换规则工厂
表示之间的转换由“转换图(conversion graph)”驱动:图中节点是表示类型,边是转换规则(conversion rule)。转换规则在 vtkSegmentationConverterFactory.h 中说明:这是一个单例类,是所有分割转换规则的仓库,通过RegisterConverterRule注册规则,通过CopyConverterRules取得全部规则副本。
vtkSegmentationConverter(见 vtkSegmentationConverter.h)负责具体转换:GetPossibleConversions列出两个表示间所有可行路径,GetConversionParametersForPath获取某条路径使用的全部转换参数;每条规则带有GetConversionCost成本估计(vtkSegmentationConverterRule.h)。使用默认方法转换时,选择成本最低的路径;表示类型可以通过注册指定源/目标表示与估计成本的新规则来扩展。
仓库内置的主要转换规则包括:
vtkClosedSurfaceToBinaryLabelmapConversionRule:闭合表面 → 二值标签图(基于图像 stencil 算法);vtkBinaryLabelmapToClosedSurfaceConversionRule:二值标签图 → 闭合表面(对图像数据执行 marching cubes,随后可选抽稀/平滑);vtkClosedSurfaceToFractionalLabelmapConversionRule、vtkFractionalLabelmapToClosedSurfaceConversionRule:闭合表面与分数标签图之间的双向转换;vtkPolyDataToFractionalLabelmapFilter等辅助过滤器。
源表示(Source representation)的特殊地位
源表示是分割中被“优待”的表示类型,它通常是数据的原始表示(编辑用二值标签图、DICOM SEG 用二值或分数标签图、DICOM RT 用平面轮廓等)。根据 vtkSegmentation.h 的说明,源表示具有以下性质:
- 所有转换都以它为源(转换路径上已有的最新表示会被优先复用);
- 源表示被修改时,其他所有表示会被作废(invalidated),之后从源重新转换;
- 它是保存到磁盘的表示,也是在 Segment Editor 等模块中可编辑的表示。
在模块界面中,已存在的表示标记为绿色对勾,源表示标记为金色星标。恰当选择源表示可确保不丢失信息,避免因转换造成的数据永久丢失。
典型使用场景
1. 编辑分割
分割的节段内容需要使用 Segment Editor 模块 进行编辑,Segmentations 模块本身不提供笔刷等编辑工具,只负责管理、转换、显示与导入导出。点击节段表格中的“Edit selected”按钮即可跳转到 Segment Editor。
2. 从体数据文件导入既有分割
方式一:直接加载为分割(推荐)。NRRD(.nrrd/.nhdr)与 NIfTI(.nii/.nii.gz)格式的 3D 体数据可直接作为分割加载:
- 将体数据文件拖入应用程序窗口(或通过菜单
File→Add Data选择文件); - 在
Description列选择Segmentation; - (可选)若存在指定每个标签值的名称与颜色的颜色表,可先将其载入应用,再在
Options区域将其选为Color node。颜色表文本文件格式见 颜色表文档; - 点击
OK。
实用技巧:为避免每次手动选择Segmentation,可将.nrrd文件以.seg.nrrd扩展名保存,这样 Slicer 会默认将其作为分割加载。
限制提示:4D 标签图像(例如将电影 MRI 每个时间点的分割存放在单个 NIfTI 文件中的情况)无法作为分割加载,默认会被加载为体序列(volume sequence),详见 Sequences 模块文档。
方式二:先加载为 labelmap 再转换。其他图像格式可按以下步骤加载为标签图体数据,再转换为分割节点:
- 拖入文件(或
File→Add Data); - 点击
Show Options,在Options列勾选LabelMap复选框(告知 Slicer 该体数据是标签图而非灰度图像); - 点击
OK; - 进入
Data模块的Subject hierarchy选项卡; - 右键点击导入的体数据名称,选择
Convert labelmap to segmentation node。
在 3D 中显示分割:进入Segmentations模块点击Show 3D;或在Data模块将分割节点拖入各个视图——拖入 3D 视图即以 3D 形式显示。
3. 从模型(表面网格)文件导入既有分割
STL 与 OBJ 格式的 3D 模型可直接加载为分割:
- 拖入文件(或
File→Add Data); - 在
Description列选择Segmentation; - 点击
OK。
若模型包含非常薄且精细的结构,则二值标签图表示的默认分辨率可能不足以满足编辑需要。默认分辨率按标签图总体积约 256×256×256 体素计算(源码实现中偏好体素总量约为 250³,见 vtkClosedSurfaceToBinaryLabelmapConversionRule.cxx,该尺寸对常见计算硬件而言不算过大,且对许多应用足够精细)。要获得更精细的分辨率:
- 进入
Segmentations模块; - 在
Representations区域点击Binary labelmap行的Create,然后点击Update; - 在弹出的对话框中:
- 在
Conversion path区域选择Closed surface -> Binary labelmap; - 在
Conversion parameters区域将Oversampling factor(过采样因子)设为 2(若还不够可依次尝试 2.5、3、4……)。注意:取值越大,内存占用与计算时间越多——过采样因子 2 会将体素总量放大 2³ = 8 倍,内存占用相应增加约 8 倍; - 点击
Convert。
- 在
从源码看,Oversampling factor是vtkClosedSurfaceToBinaryLabelmapConversionRule的正式转换参数:数值 1 表示不过采样,若设为字符串"A"则启用自动过采样计算(见 vtkClosedSurfaceToBinaryLabelmapConversionRule.h)。自动过采样由 vtkCalculateOversamplingFactor.cxx 实现,它根据结构的相对尺寸与复杂度测量值,通过模糊规则(fuzzy rules)推算合适的过采样因子。
其他网格文件格式可按以下方式加载为模型节点后转换为分割:
- 拖入文件(或
File→Add Data),点击OK; - 进入
Data模块的Subject hierarchy选项卡; - 右键点击导入的模型名称,选择
Convert model to segmentation node。
值得注意的是,从 STL/OBJ 导入的分割,其源表示会被设为闭合表面(SetSourceRepresentationToClosedSurface,见 vtkSlicerSegmentationsReader.cxx),这与后续“编辑模型导入的分割”一节中的操作直接相关。
4. 编辑从模型(表面网格)导入的分割
编辑分割需要选择source volume(源体数据)。源体数据指定编辑时使用的体素网格几何(origin 原点、spacing 间距、轴方向与 extents 范围)。
若当前场景没有合适的体数据,可按以下步骤创建:
- 进入
Segment editor模块; - 点击
Source volume节点选择器右侧的Specify geometry按钮; - 将
Source geometry选择为分割本身(这样 extents 即包围盒会完整包含目标对象); - 按需调整
Spacing值,建议三个轴取相同值;值越小保留细节越多,但内存与计算开销越大; - 点击
OK; - 开始编辑操作时,Segment Editor 会询问是否将源表示改为 binary labelmap,应回答
Yes——因为二值标签图是编辑所需的表示。从源码看,vtkSlicerSegmentEditorLogic::SetSourceRepresentationToBinaryLabelMap正是执行此切换的实现(vtkSlicerSegmentEditorLogic.cxx)。
提示:某些编辑操作可直接作用于模型,无需转换为分割。例如 Surface Toolbox 与 Dynamic Modeler 模块。
5. 导出分割为模型(表面网格)文件
节段可导出为 STL 或 OBJ 文件,用于 3D 打印或在外部软件中可视化/处理:
- 打开
Segmentations模块的Export to files区域(或在Segment editor模块中:点击Segmentations按钮的下拉菜单,选择Export to files); - 选择目标文件夹、文件格式等选项;
- 点击
Export。
其他格式的导出方式:
- 进入
Data模块,右键点击分割节点,选择Export visible segments to models(也可使用Segmentations模块的Export/import models and labelmaps区域); - 在应用菜单选择
File→Save; - 选择
File format; - 点击
Save。
6. 导出分割为 labelmap 体数据
若分割内的节段互不重叠,则场景保存时(应用菜单File→Save)默认将分割保存为 3D 体数据节点;若存在重叠节段,则保存为4D 体数据(每个 3D 体数据包含一组互不重叠的节段)。
要强制将分割保存为 3D 体数据,可在Data模块右键点击分割,选择导出为 labelmap 体数据。
如需高级导出选项,可使用Segmentations模块的Export/import models and labelmaps区域。若导出分割的几何(origin、spacing、轴方向、extents)必须与另一个体数据完全一致,请在Advanced区域将该体数据选为Reference volume。注意:使用参考体数据导出 labelmap 时,若部分区域位于新几何之外,分割可能被裁剪;裁剪前会弹出确认对话框。
7. 导出分割为 labelmap 体数据文件
若分割节点的源表示为二值标签图,分割将以标准 NRRD 文件格式保存。这是保存分割体数据的推荐方式:NRRD 会把附加元数据(节段名称、颜色、DICOM 术语)写入图像文件的自定义字段中,并且支持保存重叠节段。
若要为使用“3D labelmap 体数据文件 + 颜色表文件”存储分割的外部软件导出 NRRD 或 NIFTI 文件:
- 打开
Segmentations模块的Export to files区域(或在Segment editor模块:Segmentations按钮下拉菜单 →Export to files); - 在
File format选择器中选择NRRD或NIFTI。推荐 NRRD:它简单且通用;神经影像领域则更适合 NIFTI,因为它是该领域最常用的研究文件格式; - (可选)选择
Reference volume,使导出文件匹配所选体数据的几何(origin、spacing、轴方向)而非当前分割几何; - (可选)勾选
Use color table values并选择颜色表,使导出文件中的体素值取自颜色表。体素值取与节段名称同名的颜色表条目的索引;若未指定颜色表,则体素值按节段在节段列表中的顺序确定(所有节段之外的体素为 0,第一个节段为 1,第二个为 2,依此类推); - 设置其余选项(目标文件夹、压缩等);
- 点击
Export。
其他格式的 labelmap 体数据可通过 导出分割为 labelmap 体数据 一节所述方法先导出,再在应用菜单File→Save中选择格式保存。同样,使用参考体数据可能导致分割被裁剪,裁剪前会有确认弹窗。
8. 创建新表示(表示转换)
Representations区域列出受支持的表示类型。已存在的表示标记绿色对勾,源表示标记金色星标。源表示是唯一可编辑(例如在 Segment Editor 中)且作为所有转换来源的表示。
- 创建表示:点击对应行的
Create按钮。若要指定自定义转换路径或参数(如 labelmap 的参考几何、表面的平滑度等),点击Create按钮上的下拉箭头,选择Advanced create...,然后从顶部列表选择转换路径,并在底部区域调整转换参数; - 更新表示:点击对应行的
Update按钮,可从源表示以自定义转换路径或参数重新生成该表示; - 移除表示:点击
Update按钮的下拉箭头,选择Remove。
从源码角度,labelmap→表面方向的转换参数包括Decimation factor(抽稀因子)、Smoothing factor(平滑因子)、Conversion method(转换方法:flying edges 或 surface nets)、SurfaceNets smoothing、Compute surface normals(计算表面法向)以及Joint smoothing(联合平滑)(见 vtkBinaryLabelmapToClosedSurfaceConversionRule.h)。其中 Joint smoothing 会把所有节段作为一个整体创建并平滑表面,可减少节段交界处的平滑伪影。
9. 调整节段的显示方式
- 右键点击节段表格中的眼睛图标,可弹出显示选项并开关不同显示模式;
- 更高级的显示选项位于
Segmentations模块的Display区域。
10. 使用 Python 脚本管理分割
分割的创建、节段操作、表示转换等均可通过 Python 脚本完成,示例见 Script repository 的分割章节。
11. DICOM 导出
将分割导出到 DICOM 的步骤如下:
- 确保源表示为
binary labelmap(DICOM 导出使用源表示,目前仅支持二值标签图)。源表示可在Segmentations模块的Representations区域设置:若金色星标已在binary labelmap行,则无需操作;若星标在其他行,点击binary labelmap行的Make source按钮(若该按钮未显示,先点击Create创建该表示); - 选择导出类型:推荐使用 DICOM Segmentation Object(
DICOMSegmentation导出类型)存储分割。若分割将用于放射治疗,则可能需要导出为 DICOM RT Structure Set——安装SlicerRT扩展后即可使用 RT Structure Set 导出类型。一般而言不推荐用 RT Structure Set 存储分割,因为它无法存储任意复杂的 3D 形状; - 确保分割关联到 DICOM 图像:若被分割的图像并非从 DICOM 数据库加载(例如来自 NRRD 或 NIFTI 文件),则需在数据库中创建 DICOM 图像并让分割引用它(DICOM 要求分割必须与某幅 DICOM 图像关联):
- 将源体数据导出到 DICOM 数据库(按提示同意创建 patient 和 study);
- 从 DICOM 数据库加载导出的体数据;
- 在
Segment Editor模块点击Specify geometry,将加载的体数据选为Source geometry,点击OK;
- 进入
Data模块,右键点击分割,选择Export to DICOM,并遵循 DICOM 导出说明 完成操作。
面板功能详解
Segments table(节段表格)
- 添加/移除节段;
Edit selected:跳转到 Segment Editor 模块;- 设置可见性与逐节段显示设置、不透明度、颜色与节段名称。
Display(显示)
- 分割级显示设置(注意不是逐节段):可见性、不透明度(显示时会与逐节段不透明度相乘);
Views:选择在哪些独立视图中显示当前分割;Slice intersection thickness:切片交线厚度;Representation in 3D/2D views:在 3D 与 2D 视图中显示的表示。当存在多种表示时很有用,例如 3D 视图显示闭合表面、切片视图显示标签图。
Representations(表示)
- 列出受支持的表示及相应操作;
- 已存在的表示带绿色对勾,源表示(所有转换的来源、可编辑的表示)带金色星标;
- 每行的按钮用于创建、移除、更新表示:
- 长按(点击下拉箭头)
Create或Update可进行高级转换(使用非默认路径或转换参数); - 已存在的表示可通过点击
Make source设为源表示。源表示被用于转换、可被编辑,且是保存到磁盘的表示。
- 长按(点击下拉箭头)
Copy/move(导入/导出)
- 左侧面板列出所选分割中的节段;
- 右侧面板显示外部数据容器;
- 箭头按钮用于在分割与外部节点之间复制(带加号)或移动(不带加号)节段;
- 点击右侧面板顶部的相应按钮可新建 labelmap 或 model;
- 多个节段可导出到同一个 labelmap;当节段重叠时,后续节段会覆盖先前节段。
Subject hierarchy(主题层级)
- 分割与其他节点一样显示在主题层级中,区别在于其包含的节段位于一个“虚拟分支(virtual branch)”中;
- 节段可在不同分割之间移动,但除拖放到另一个分割之下外,不允许拖放到其他位置;
- 分割专属的主题层级功能:
Create representation——使用默认路径创建所选表示; - 节段专属的主题层级功能:
Show only this segment:节段很多且只需显示某一个时非常实用(避免逐个点击眼睛图标);Show all segments:显示全部节段。
已知局限性
当分割使用Closed surface表示在 2D 视图中显示时(无论是因为这是唯一可用的表示,还是因为在Segmentations模块中Display→Advanced→Representation in 2D views选择了Closed surface),轮廓的填充可能显示为不完整或反转。这仅是渲染误差,不影响分割内容本身。要避免此类渲染伪影,可创建Binary labelmap表示,并将Representation in 2D views设为Binary labelmap。
面向开发者的信息
分割功能的核心基础设施位于仓库的 Libs/vtkSegmentationCore 目录,主要组件包括:
vtkSegmentation/vtkSegment:分割与节段容器;vtkSegmentationConverter/vtkSegmentationConverterFactory:转换引擎与转换规则仓库;vtkSegmentationConverterRule及各转换规则子类:表示转换算法(stencil、marching cubes、surface nets 等);vtkOrientedImageData:带几何信息的体数据类;vtkCalculateOversamplingFactor:基于模糊规则的自动过采样因子计算。
模块的 GUI 与业务逻辑位于 Modules/Loadable/Segmentations,包括模块部件qSlicerSegmentationsModuleWidget、逻辑类vtkSlicerSegmentationsModuleLogic、读入器vtkSlicerSegmentationsReader、编辑器逻辑vtkSlicerSegmentEditorLogic以及主题层级插件qSlicerSubjectHierarchySegmentationsPlugin。脚本示例见 Script repository 的分割章节。
相关模块
- Segment Editor 模块用于编辑分割节点的节段内容。
致谢与作者
本模块作者包括 Csaba Pinter、Andras Lasso、Kyle Sunderland(PerkLab,皇后大学)。该工作部分由安大略省癌症护理应用癌症研究单元资助(资金来自安大略省卫生与长期护理部及安大略放射治疗自适应干预联盟 OCAIRO),旨在提供免费的、面向放疗与图像引导干预的开源工具集。
- 医疗健康
- 图像处理
- 数据可视化
- 桌面应用
- 3D渲染
【免费下载链接】Slicer
Multi-platform, free open source software for visualization and image computing.
相关推荐
WAMR 多模块(Multi-Module)示例全解析:跨模块导入导出、构建运行与源码实现
WAMR 多模块(Multi Module)示例全解析:跨模块导入导出、构建运行与源码实现 导读 本文围绕 WebAssembly Micro Runtime(
语言运行时嵌入式物联网ChatGPT-Shortcut 自定义提示词完全指南:创建、编辑、分享与数据导入导出
ChatGPT Shortcut 自定义提示词完全指南:创建、编辑、分享与数据导入导出 本文围绕 ChatGPT Shortcut(AI Short)的「自定义
AI 应用提示工程人工智能前端抖音视频下载两步搞定:抖音下载器完整实用教程
抖音视频下载两步搞定:抖音下载器完整实用教程 这篇教程带你用「抖音下载器」(douyin downloader)开源工具下载抖音视频。它既能下单条无水印视频,也
网页爬虫CLI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考