工具介绍
简单介绍一下在Cornerstone中什么是工具,工具是一个未实例化的类,它至少实现了Cornerstone中BaseTool
接口。如果我们想要在我们的代码中使用一个工具,则必须实现以下两个步骤:
-
使用Cornerstone的顶层addTool函数添加未实例化的工具
-
将工具添加到工具组中
支持的工具类型
我们在使用工具时,主要会涉及到对图像的原始操作(缩放、平移等等)、注释操作(在图像的上层圈定一定的区域查看信息)、分割操作等等。
所以介绍的工具主要分为以下三大类:
-
操作类工具
-
注释类工具
-
分割类工具
操作类工具
Cornerstone3DTools提供了一组工具,可用于在视口中操作图像。主要包括
-
放大和缩小图像(ZoomTool)
-
平移图像(PanTool)
-
滚动图像的instance(StackScrollMouseWheelTool)
-
操作图像的windowLevel (WindowLevelTool)
注释类工具
Cornerstone3DTools提供了一套注释工具。可以用来创建和编辑注释
-
测量两点距离(Length Tool)
-
测量宽度和长度(Bidirectional Tool)
-
矩形面积的测量和统计(RectangleRoi Tool)
-
测量椭球体的体积和统计信息(EllipseRoi Tool)
-
获取体素的底层值(Probe Tool)
分割类工具
Cornerstone3D还提供了分割工具。这包括3D SegmentationDisplay和3D分割编辑工具,如画笔,矩形和圆形剪刀,以及3D球体工具。
工具的模式
我们注册的工具(在对应的toolGroup中)可以处于以下四种模式之一,每种模式都会影响工具对交互的响应方式。📢 注意:在同一种绑定方式下有且仅有一种工具被激活,不会有两个工具被激活
模式 | 对应的交互效果 |
---|---|
Active(激活模式) | 1. Active模式下的工具将响应交互 2. 如果该工具是注释工具,则单击未覆盖现有注释的事件将创建新注释,覆盖现在注释将选中注释,3. 不响应交互 |
Passive (default)(消极模式) | 1. 如果工具是注释工具,如果它可以被选中,它可以被移动和重新定位 |
Enabled(可用模式) | 1. 工具可以呈现,但不能进行交互响应 |
Disabled(禁用模式) | 1. 工具既不渲染,也不会响应交互 |
工具组
ToolGroup是Cornerstone3D中的一个新概念。
ToolGroup的目标是定义一种简单的方法,以每个视口方式定义工具的行为。 除此之外,绑定了同一个TooGroup的Viewport可以共享工具组相同的配置、模式及组内的工具。
Viewport 和 ToolGroup 的关系
Viewport 和 ToolGroup 是一对一的关系,同一个ToolGroup可以绑定多个Viewport,但是一个Viewport只能绑定一个ToolGroup
创建及使用工具组
toolGroup由ToolGroupManager管理。ToolGroupManager用于创建、搜索和销毁工具组
初始化工具组
JavaScript
import { ToolGroupManager } from '@cornerstonejs/tools';
const toolGroupId = 'ctToolGroup';
const ctToolGroup = ToolGroupManager.createToolGroup(toolGroupId);
工具组添加工具
JavaScript
ctToolGroup.addTool(PanTool.toolName);
ctToolGroup.addTool(ZoomTool.toolName);
ctToolGroup.addTool(ProbeTool.toolName);
工具组与视图进行绑定
JavaScript
ctToolGroup.addViewport(viewportId, renderingEngineId);
激活一个工具
JavaScript
ctToolGroup.setToolActive(LengthTool.toolName, {
bindings: [{ mouseButton: MouseBindings.Primary }],
});
ctToolGroup.setToolActive(PanTool.toolName, {
bindings: [{ mouseButton: MouseBindings.Auxiliary }],
});
ctToolGroup.setToolActive(ZoomTool.toolName, {
bindings: [{ mouseButton: MouseBindings.Secondary }],
});
ctToolGroup.setToolActive(StackScrollMouseWheelTool.toolName);
总结回顾
同步器
同步器(Synchronizers)可以使多个视图同步响应同一个工具的操作,例如我们在MPR视图下,同步操作三个视图的缩放程度、windowLevel等等
一个同步器必须需要以下几个部分才可以执行
-
一个监听事件(什么情况下触发同步)
-
一个回调函数(监听事件触发时需要执行什么操作)
-
一组源视图(原作用于哪些视图)
-
一组目标视图(要同步于哪些视图)
使用同步器
同步器的使用方式类似于工具组,先使用 SynchronizerManager 创建一个同步器,被创建的同步器含有addSource、addTarget、add(将视图作为source视图和target视图同步添加)等函数。
特别值得注意的是:当绑定了同步器的视图被禁用时,同步器会自动在target列表和source列表中移除被禁用的视图,而无需手动操作。
内置的同步器
可以在 @cornerstonejs/tools 抛出的 synchronizers
对象中查看内置的同步器,从以下图片可看到目前内置了5种同步器(实际是4种,createStackImageSynchronizer
和 createImageSliceSynchronizer
功能性一致,只是兼容性处理)
-
createCameraPositionSynchronizer: 创建一个新的同步器,监听CAMERA_MODIFIED呈现事件并调用cameraSyncCallback。
-
createVOISynchronizer :创建一个新的同步器,监听VOI_MODIFIED渲染事件并调用voiSyncCallback。
-
createZoomPanSynchronizer:创建一个新的同步器,监听CAMERA_MODIFIED事件并调用zoomPanSyncCallback
-
createImageSliceSynchronizer:创建一个新的同步器,监听STACK_NEW_IMAGE渲染事件并调用ImageSliceSyncCallback。
使用内置同步器
以同步更新缩放和位移位置为例,演示一下在我们的代码中如何使用内置同步器
创建同步器
JavaScript
import {synchronizers, SynchronizerManager} from '@cornerstonejs/tools'
synchronizers.createZoomPanSynchronizer('CAMERA_SYNCHRONIZER_ID');
绑定视图
JavaScript
// 根据同步器ID获取到对应的同步器
const cameraSynchronizer = SynchronizerManager.getSynchronizer('CAMERA_SYNCHRONIZER_ID');
// 为同步器绑定视图,add表示将当前视图同步绑定到source列表和target列表中
cameraSynchronizer.add({
renderingEngineId,
viewportId,
});
自定义同步器
如果内置的同步器无法满足我们的需求,支持自定义一个同步器。如果我们想要自定义一个同步器主要需要实现以下一个核心点
JavaScript
import { Enums } from '@cornerstonejs/core';
import { SynchronizerManager } from '@cornerstonejs/tools';
const cameraPositionSynchronizer = SynchronizerManager.createSynchronizer(
'synchronizerName', // 核心点1:同步器的ID
Enums.Events.CAMERA_MODIFIED, // 核心点2:同步器监听的事件
(
synchronizerInstance,
sourceViewport,
targetViewport,
cameraModifiedEvent
) => {
// 核心点3:监听事件后触发的回调函数
}
);
以下为内置的createCameraPositionSynchronizer同步器的实现
JavaScript
export default function createCameraPositionSynchronizer(
synchronizerName: string
): Synchronizer {
const cameraPositionSynchronizer = createSynchronizer(
synchronizerName,
CAMERA_MODIFIED,
cameraSyncCallback
);
return cameraPositionSynchronizer;
}
总结回顾
Annotations
"Annotations"(注释)指的是在医学图像上添加的额外信息,例如测量、标记或其他重要信息。这些注释通常用于帮助医生或医学专业人员更好地理解和解释图像,以及进行诊断。
主要从以下几个问题介绍Annotations:
-
绘制的注释信息如何存储
-
如何管理注释信息
-
如何操作或多次操作注释信息
-
如何更改注释信息的样式
-
是否可以将相同类型的注释信息进行分组管理
Annotation State
用于管理和维护注释的一种机制。FrameOfReference注释状态管理器,其中注释使用世界坐标系标注。
-
state 是一个普通的JavaScript对象,用于存储annotation实例的状态。例如注释的统计信息、注释数据和相机位置等信息都存储在该对象中。
-
创建新的注释时(注释工具中的addNewAnnotation方法),将基于元数据和工具的当前状态创建新的注释数据,并将其添加到全局注释状态(state)中。
JavaScript
// 注释数据对象包含的属性
const annotation = {
// a. 注释状态
invalidated: boolean, // 注释是否因为某些操作而导致无效
highlighted: boolean, // 鼠标悬停时是否突出显示注释
annotationUID: string, // 注释的UID
// b. 元数据信息
metadata: {
viewPlaneNormal: Types.Point3, // (摄像机的视图平面法线)The view plane normal of the camera
viewUp: Types.Point3, // (相机的视图向上矢量)The view up vector of the camera
FrameOfReferenceUID: string, // (已绘制注释的viewport的FrameOfReferenceUID)viewport's FrameOfReferenceUID the annotation has been drawn on
referencedImageId?: string, // (已绘制注释的图像ID)The image ID the annotation has been drawn on (if applicable)
toolName: string, // The tool name
},
// c. 注释数据
data: {
handles: {
points: [Types.Point3], // (手柄点的世界坐标)The handles points in world coordinates (probe tool = 1 handle = 1 x,y,z point)
},
cachedStats: {}, // (为注释存储的统计信息)Stored Statistics for the annotation
},
}
新增/获取注释
JavaScript
// Adds annotation
cornerstone3DTools.annotations.state.addAnnotation(element, annotation);
// Remove the annotations given the annotation reference.
cornerstone3DTools.annotations.state.removeAnnotation(element, annotationUID);
// Returns the full annotations for a given Tool
cornerstone3DTools.annotations.state.getAnnotations(element, toolName);
// A helper which returns the single annotation entry matching the UID.
cornerstone3DTools.annotations.state.getAnnotation(annotationUID);
Annotation Manager
Annotation Manager是一个单例类,用于管理CornerstoneTools中的注释,包括:存储 注释、检索 注释、保存 和恢复注释。
内置
默认的注释管理器FrameOfReferenceSpecificAnnotationManager基于FrameOfReferenceUID存储注释。这意味着注释是被每个FrameOfReferenceUID单独存储的。
目前在渲染管道中,如果两个volumeviewport共享相同的FrameOfReferenceUID,它们将共享相同的注释。然而,StackViewports工作在每个imageId的基础上,所以注释不能在StackViewports之间共享。
GroupKey
groupKey是一个字符串,用于标识注释组。如上所述,默认Annotation Manager基于FrameOfReferenceUID存储注释,因此groupKey是FrameOfReferenceUID。
自定义Manager
你可以通过实现IAnnotationManager接口来创建你自己的自定义注解管理器
JavaScript
interface IAnnotationManager {
getGroupKey: (annotationGroupSelector: any) => string; // 获取groupKey标识,
getAnnotations: ( // 获取给定 groupKey和工具名 的所有注释
groupKey: string,
toolName?: string
) => Annotations | GroupSpecificAnnotations | undefined;
addAnnotation: (annotation: Annotation, groupKey?: string) => void; // 向管理器中新增注释
removeAnnotation: (annotationUID: string) => void; // 移除指定UID的注释
removeAnnotations: (groupKey: string, toolName?: string) => void; // 移除给定 groupKey和工具名 的所有注释
saveAnnotations: ( // 保存注释
groupKey?: string,
toolName?: string
) => AnnotationState | GroupSpecificAnnotations | Annotations;
restoreAnnotations: ( // 恢复注释
state: AnnotationState | GroupSpecificAnnotations | Annotations,
groupKey?: string,
toolName?: string
) => void;
getNumberOfAllAnnotations: () => number; // 获取注释的个数
removeAllAnnotations: () => void; // 移除全部的注释
}
使用自定义注释管理器
JavaScript
import { annotation } from '@cornerstonejs/tools';
import myCustomAnnotationManager from './myCustomAnnotationManager';
annotation.state.setAnnotationManager(myCustomAnnotationManager);
场景:
- 使用自定注释管理:例如在具有相同的FrameOfReferenceUID的两个VolumeViewport中不共享注释
注释操作
选中与取消
可以通过按下shift键并且点击注释来选中注释
JavaScript
import { annotations } from '@cornerstonejs/tools';
// selection of an annotation
annotations.selection.setAnnotationSelected(
annotationUID,
(selected = true),
(preserveSelected = false)
);
// get all the selected annotations
annotations.selection.getAnnotationsSelected();
// get all selected annotations from a specific tool
annotations.selection.getAnnotationsSelectedByToolName(toolName);
锁定
JavaScript
import { annotations } from '@cornerstonejs/tools';
// selection of an annotation
annotations.selection.setAnnotationSelected(
annotationUID,
(selected = true),
(preserveSelected = false)
);
// get all the selected annotations
annotations.selection.getAnnotationsSelected();
// get all selected annotations from a specific tool
annotations.selection.getAnnotationsSelectedByToolName(toolName);
样式配置
配置等级
- 注释级别
JavaScript
annotations.config.styles.setAnnotationToolStyle(annotationUID, style);
- 视口级别
JavaScript
annotations.config.styles.setViewportToolStyle(viewportId, styles);
- 工具组级别
JavaScript
annotations.config.styles.setToolGroupToolStyle(toolGroupId, styles);
- 全局
JavaScript
annotations.config.styles.setDefaultToolStyle(deepMerge(styles, newStyles));
支持的配置项
JavaScript
{
color: 'rgb(255, 255, 0)',
colorHighlighted: 'rgb(0, 255, 0)',
colorSelected: 'rgb(0, 220, 0)',
colorLocked: 'rgb(255, 255, 0)',
lineWidth: '1',
lineDash: '',
textBoxVisibility: true,
textBoxFontFamily: 'Helvetica Neue, Helvetica, Arial, sans-serif',
textBoxFontSize: '14px',
textBoxColor: 'rgb(255, 255, 0)',
textBoxColorHighlighted: 'rgb(0, 255, 0)',
textBoxColorSelected: 'rgb(0, 255, 0)',
textBoxColorLocked: 'rgb(255, 255, 0)',
textBoxBackground: '',
textBoxLinkLineWidth: '1',
textBoxLinkLineDash: '2,3',
};
Annotation Groups
为了表明注释是相互关联的,AnnotationGroup类可用于对注释进行分组。
- 创建一个注释组
JavaScript
const group = new cornerstoneTools.annotation.AnnotationGroup();
- 向组中新增注释
如果组处于活动状态,并且对其调用了addListeners方法,则可以自动将注释添加到组中。或者可以通过调用注释组上的add方法手动添加它们。
JavaScript
group.add(annotation.annotationUID);
- 设置注释可见性
可以通过调用注释组上的setVisibility方法来显示/隐藏注释
JavaScript
group.setVisibility(!group.isVisible, { viewportId, renderingEngineId });
总结回顾
JavaScript
import { segmentation } from '@cornerstonejs/tools
// 在对照表的某个位置tian
segmentation.config.color.addColorLUT(colorLUT, colorLUTIndex)
// sets the colorLUT index to use for the segmentation representation
segmentation.config.color.setColorLUT(toolGroupId, representationUID, colorLUTIndex)
// get the color for the segment index
segmentation.config.color.getColorForSegmentIndex(toolGroupId, representationUID, segmentIndex)
Segmentations
介绍
在介绍Cornerstone3D中的分割器之前,我们先简单介绍一下在医学成像领域的 Segmentations
。
在医学成像领域,Segmentations一般指的是图像处理技术,用于标识和隔离成像数据中的特定区域或结构。这项技术被广泛应用于分析和解释放射学图像,如CT、MRI和X光等。它可以帮助医生识别、度量并可视化解剖结构、病理改变或任何特定区域,从而支持诊断、治疗规划和疾病监测。这种技术可以是手动的,由放射科医生或技术人员操作,也可以是半自动或完全自动的,依赖于先进的计算机算法。在Cornerstone3D中提供的分割器就是既可以支持手动操作,也支持半自动化或自动化处理。
手动标记
用户根据特定的场景和需求,使用分割器工具进行编辑或标记影像中的特定部分(即分割器作为产品中的一个工具使用,类似于放大器、平移器等等)
半自动化或自动化
利用算法对影像进行分析,辅助进行标记和分割(即如果想要自动化标记,单纯依靠Cornerstone无法实现,需要算法支持)
特性
在Cornerstone3D中的Segmentations功能具有灵活性和高性能渲染性;
灵活性
在Cornerstone3D中,分割器(Segmentation)和可视化表示(Segmentation Representation)被分开处理,提高了灵活性。这种分离允许从同一数据源创建多种可视化展示形式(例如可以在一个分割器中既可以展示圆形分割、也可以展示椭球形分割)
高性能渲染
与旧版Cornerstone对元素进行绘制分割和标记而导致重复分割不同,新版本中的Segmentation Representation不再仅限于单个元素,而是应用于整个ToolGroup,使得Segmentation在多个视口(例如MPR视图)中共享和应用。
状态管理
在Cornerstone3D中,Segmentation的状态管理涉及多个关键部分。
SegmentationState存储了库中所有关于Segmentation和SegmentationRepresentations的当前状态信息。主要包括以下信息
-
GlobalConfig
:全局配置项,控制所有Segmentation Representation的配置 -
ColorLUT
:存储用于渲染Segmentation Representation的颜色查找表 -
Segmentation
:在状态管理中的分割器对象,主要包含唯一标识符、分割类型及创建分割表示所需的信息等等
Segmentation
由于分割器(Segmentation)和分割可视化表示(Segmentation Representation)是被分开处理的,所以在状态管理中的 Segmentation
是一个包含【分割器信息】+ 【创建该分割器下的可视化表示所需信息】的对象
JavaScript
{
segmentationId: 'segmentation1', // 分割器唯一ID,由用户创建时添加
mainType: 'Labelmap', // 分割类型,内部执行
activeSegmentIndex: 0, // 当前激活的分割索引,供分割工具使用
segmentsLocked: new Set(), // 当前被锁定的分割
label: 'segmentation1', // 分割上显示的标签
cachedStats: {},
representationData: { // 当前分割器下的分割可视化信息
LABELMAP: {
volumeId: 'segmentation1',
},
CONTOUR: {
geometryIds: ['contourSet1', 'contourSet2'],
},
},
}
向状态管理中新增一个Segmentation
我们可以通过调用@cornerstonejs/tools中的顶层API(addSegmentations)向state中新增一个分割器(Segmentation),📣 特别注意:当我们在state中新增一个Segmentation时,是不会渲染分割及标记的,只有同时在toolGroup中新增分割可视化表示(Segmentation Representation)才会支持渲染分割。
JavaScript
import { segmentation, Enums } from '@cornerstonejs/tools';
segmentation.addSegmentations([
{
segmentationId,
representation: {
type: Enums.SegmentationRepresentations.Labelmap,
data: {
volumeId: segmentationId,
},
},
},
]);
向ToolGroup中新增一个分割表示
正如上面所说,如果想要渲染一个分割效果,需要同时在state中新增Segmentation
和 ToolGroup中新增 Segmentation Representation
,接下来我们看如何在toolGroup中新增一个 Segmentation Representation
JavaScript
import {
segmentation,
SegmentationDisplayTool,
Enums,
} from '@cornerstonejs/tools';
// 01 - 创建一个工具组
const toolGroup = ToolGroupManager.getToolGroup(toolGroupId);
// 02 - 向工具组中新增分割器工具并设置工具可用
toolGroup.addTool(SegmentationDisplayTool.toolName);
toolGroup.setToolEnabled(SegmentationDisplayTool.toolName);
// 03 - 使用segmentation模块的addSegmentationRepresentations方法,向对应的Segmentation对象中新增一条表示
await segmentation.addSegmentationRepresentations(toolGroupId, [
{
segmentationId,
type: Enums.SegmentationRepresentations.Labelmap,
},
]);
addSegmentationRepresentations 方法支持三个参数,当某个工具组需要配置特殊的分割表示配置项时,可以传入第三个参数
-
toolGroupId:绑定的工具组的ID
-
segmentationRepresentation:分割表示数组
-
specialConfig:【可选项】仅作用于当前工具组的配置项
JavaScript
const toolGroupSpecificRepresentationConfig = {
renderInactiveSegmentations: true,
representations: {
[Enums.SegmentationRepresentations.Labelmap]: {
renderOutline: true,
},
},
};
await segmentation.addSegmentationRepresentations(
toolGroupId,
[
{
segmentationId,
type: Enums.SegmentationRepresentations.Labelmap,
},
],
toolGroupSpecificRepresentationConfig
);
- 工具使用演示DEMO:github.com/jianyaoo/vu...
操作API
上面主要介绍了如何使用Segmentation绘制一个分割,对于已经绘制的分割标记,官方提供了一些API支持去操作这些分割标记,包括激活、锁定等等
激活API
每一个工具组可以同时展示多个分割标记,但是同一时间有且仅有一个分割标记被激活,而被激活的这个就是可以被工具操作的这个
JavaScript
import { segmentation } from '@cornerstonejs/tools';
// 获取一个工具组内被激活的分割标记
segmentation.getActiveSegmentationRepresentation(toolGroupId);
// 设置一个工具组内的一个分割标记为激活状态
segmentation.setActiveSegmentationRepresentation(
toolGroupId,
representationUID
);
锁定API
我们可以在分割器内选择一个分割可视化标记进行锁定,被锁定的标记不可以被任何工具修改
JavaScript
import { segmentation } from '@cornerstonejs/tools';
// 设置锁定
segmentation.locking.setSegmentIndexLocked(
segmentationId,
segmentIndex,
locked
);
//获取被锁定的标记
segmentation.locking.getLockedSegments(segmentationId);
// 检查某个标记是否被锁定
segmentation.locking.isSegmentIndexLocked(
segmentationId,
segmentIndex
);
配置API
在了解了如何操作分割器之后,我们接着来看一下如何配置一个分割器达到自己想要的效果。
在Cornerstone3D的分割器配置中,主要支持两种配置:
-
全局配置:该配置将作用于所有工具组的所有的分割
-
工具组配置:只对配置的工具组起作用,并且优先级高于全局配置(即如果同时在全局配置和工具组配置中设置了同一个配置项,工具组中的配置将总是覆盖全局配置)
配置API
在了解了如何操作分割器之后,我们接着来看一下如何配置一个分割器达到自己想要的效果。
在Cornerstone3D的分割器配置中,主要支持两种配置:
-
全局配置:该配置将作用于所有工具组的所有的分割
-
工具组配置:只对配置的工具组起作用,并且优先级高于全局配置(即如果同时在全局配置和工具组配置中设置了同一个配置项,工具组中的配置将总是覆盖全局配置)
状态配置API
JavaScript
import {segmentation, Enums} from '@cornerstonejs/tools
// 获取全局配置项
segmentation.config.getGlobalConfig()
// 设置全局配置项
segmentation.config.setGlobalConfig(config)
// 获取某个工具组特定的配置项
segmentation.config.getToolGroupSpecificConfig(toolGroupId)
// 为某个工具组设置特定的配置项
segmentation.config.setToolGroupSpecificConfig(toolGroupId, config)
// Get global representation configuration for a specific representation (e.g., labelmap)
const representationType = Enums.SegmentationRepresentations.Labelmap
segmentation.config.getGlobalRepresentationConfig(representationType)
// Set global representation configuration for a specific representation (e.g., labelmap)
segmentation.config.setGlobalRepresentationConfig(representationType, config)
无论是全局配置还是工具组配置,都支持下面的配置项内容,即上面代码中的参数 config
JavaScript
{
renderInactiveSegmentations: false,
representations: {
LABELMAP: {
activeSegmentOutlineWidthDelta?: number
fillAlpha?: number
fillAlphaInactive?: number
outlineOpacity?: number
outlineOpacityInactive?: number
outlineWidthActive?: number
outlineWidthInactive?: number
renderFill?: boolean
renderFillInactive?: boolean
renderOutline?: boolean
},
},
},
显示/隐藏API
Segmentation
模块提供了对应的API去获取或者设置某个分割标志是否可见
JavaScript
import { segmentation } from '@cornerstonejs/tools
// 设置工具组下的分割标志是否可见
segmentation.config.visibility.setSegmentationVisibility(toolGroupId, representationUID, visibility)
// 获取工具组下的分割标志是否可见
segmentation.config.visibility.getSegmentationVisibility(toolGroupId, representationUID)
配置颜色
在 Segmentation
模块中提供了一组颜色对照表(colorLUT)用来渲染不同索引的分割标记。例如索引为1的分割器将应用colorLUT中索引为1的颜色。
所以如果我们想要改变分割表示的颜色,不能直接在分割标志上配置,而是先在颜色对照表中新增一个我们需要的颜色,然后再设置分期标志的颜色为对照表中对应颜色的索引。
JavaScript
import { segmentation } from '@cornerstonejs/tools
// 在颜色对照表中新增一个颜色
segmentation.config.color.addColorLUT(colorLUT, colorLUTIndex)
// 设置某个分割标记为添加的颜色
segmentation.config.color.setColorLUT(toolGroupId, representationUID, colorLUTIndex)
// 获取某个分割标记的颜色
segmentation.config.color.getColorForSegmentIndex(toolGroupId, representationUID, segmentIndex)
总结回顾
可运行代码演示:github.com/jianyaoo/vu... clone到本地后直接运行 npm run serve 即可,目前支持演示Demo如下,持续更新,欢迎关注