Skip to content

主要构成

主要组件

库目前主要分为以下三部分:

  • 视图类
  • IO 类
  • 工具类

其中,视图类是本库最核心的部分,分为二维视图和三维视图。二维视图主要用于显示图像,三维视图主要用于显示三维模型;IO 类用于解析各类文件,如医学图像里的 DICOM 图像,三维模型里的 STL,以及其他常见的 PNG、JPG 或是 .nii.gz 等;工具类用于提供各类静态函数,方便开发者获取定义各类数据,如点、线、框等类型。

此外,在 v0.0.12 后,增加了 4 个 Widget,分别是 XPointWidgetXLineWidgetXRectCenterWidgetXCircleCenterWidget。这 4 个 Widget 可以用于定义中心、长度、范围等信息,具体用法见 交互 Widget

视图类

三维视图

三维视图,顾名思义,是一个用于构建三维空间的组件。它的使用很简单,直接在 Vue 页面中引入该组件,并在 template 中使用就可以。下面的代码是一个示例。

vue
<template>
  <XView3D
    ref="view3D"
    viewID="vtk-container2"
    :background="[0.0, 0.0, 0.0, 1]"
    style="width: 500px; height: 800px"
  />
</template>

<script setup lang="ts">
import XView3D from "@/components/XView3D.vue";
import { ref, onMounted } from "vue";

const view3D = ref<InstanceType<typeof XView3D> | null>(null);
</script>

主要的属性

  • ref,模板引用,字符串类型,可通过 view3D.value 的方式直接调用组件的方法
  • background,背景颜色,如 [0.0, 0.0, 0.0, 1] 表示黑色
  • width,视图的宽度
  • height,视图的高度
  • style,视图的样式
  • viewID,视图的 ID,可在调试或者页面分析时用 id 进行查找、设置特殊样式,字符串类型

回调函数

以下为主要的回调函数,在组件中通过类似 @onPropWheel="..." 的方式应用,其中值为在组件部分中定义的方法:

  • 鼠标在模型上滚动触发
  • 鼠标滑动进入模型
  • 鼠标滑动离开模型
  • 鼠标左键按下模型
  • 鼠标左键按下抬起模型
  • 鼠标左键按下移动模型
  • 鼠标按下移动抬起模型

直接函数

以下为主要的直接函数,在组件内使用 view3D.value?.xxx() 来进行调用:

  • 获得 renderWindow

  • 获得 renderer

  • 获得 interactor

  • 获得 interactorStyle

  • 在 300ms 内只执行一次渲染操作

  • 无视节流限制,直接刷新渲染结果

  • 将渲染器的相机重置为默认视图

  • 屏幕坐标转换为世界坐标

  • 投影世界坐标到焦平面

  • 获得某个 actor 的 name

  • 添加一个模型 actor,其中 propActorProperty 定义如下:

    ts
    export interface propActorProperty {
      /** Actor 的颜色,使用 RGB 格式。 */
      color?: RGBColor;
      /** Actor 的透明度,范围从 0.0(完全透明)到 1.0(完全不透明)。 */
      opacity?: number;
      /** Actor 的可见性,true 表示可见,false 表示不可见。 */
      visibility?: boolean;
      /** Actor 的线宽度。 */
      lineWidth?: number;
      /** Actor 是否可拾取。 */
      pickable?: boolean;
    }
  • 添加一个图像 actor,其中 MPROrientation 的定义如下:

    ts
    export type MPROrientation = "axial" | "sagittal" | "coronal";
  • 添加分割 actor:

    ts
    addSegmentation: (
      segName: string,
      orientation: MPROrientation,
      linkedImageName?: string,
      opacity?: number,
      colorMap?: LabelColorMap,
    ) => XSegmentationActor;

    segName 分割图在 XDataStore 中的名称;orientation 切片方向(axial / sagittal / coronal);linkedImageName 要绑定切片平面的底层图像名称(可选);opacity 覆盖层透明度(0-1),默认 0.5;colorMap 自定义标签颜色表(可选)。

  • 获取指定名称的分割 actor

  • 移除一个分割 actor

  • 移除所有分割 actor

  • 切换视图内所有图像 actor 和分割 actor 的切片方向,并更新相机

  • 同步更新视图内所有图像 actor 和分割 actor 的切片位置

二维视图

二维视图与三维视图的内容基本一致。

IO 类

用于读取各类文件,如 DICOM 图像、STL 文件等。

readDICOM

读取 DICOM 图像的返回结果是 DicomReadResult,其定义如下:

ts
export interface DicomReadResult {
  /** VTK ImageData,可直接用于渲染 */
  imageData: vtkImageData;
  /** 原始 itk-wasm Image,包含完整元数据 */
  itkImage: Image;
  /** 排序后的文件名列表 */
  sortedFilenames: object;
  /** 序列首文件的全部 DICOM Tag,每项为 [tag, value],如 ["0010|0010", "张三"] */
  tags: Array<[string, string]>;
}

读取 DICOM tag 的返回结果是 DicomTagsResult,其定义如下:

ts
export interface DicomTagsResult {
  /** Tag 键值对数组,每项为 [tag, value],如 ["0010|0010", "张三"] */
  tags: Array<[string, string]>;
}

读取 tag

  • 读取单个 DICOM 文件的 Tag 信息,file 为单个 DICOM File 对象,tagKeywords 为可选,如 ["PatientName", "SeriesInstanceUID"];不传则读取全部
  • 从 ArrayBuffer 读取单个 DICOM 文件的 Tag 信息,data 为文件二进制内容,path 为文件名(如 "slice.dcm"),tagKeywords 同上

序列分组

将一组 DICOM File 按 SeriesInstanceUID 分组。

读取图像

  • 读取一组 DICOM 文件(同一序列),files 来自 <input type="file"> 的 File 对象数组,singleSortedSeries 文件是否已按序列顺序排好,默认 false(由库自动排序)
  • files 为数组,path 仅用于排序,填文件名即可

readNifti

读取 nifti 文件后返回的结果为 NiftiReadResult,其定义如下:

ts
export interface NiftiReadResult {
  /** VTK ImageData,可直接用于渲染 */
  imageData: vtkImageData;
  /** 原始 itk-wasm Image,包含完整元数据(spacing、direction、origin 等) */
  itkImage: Image;
}
  • 从浏览器 File 对象读取 NIfTI 文件
  • 从 ArrayBuffer / Uint8Array 读取 NIfTI 数据

readImage

读取 image 后,返回的结果为 ReadImageResult,其定义如下:

ts
export interface ReadImageResult {
  /** VTK ImageData,可直接用于渲染 */
  imageData: vtkImageData;
  /** 原始 itk-wasm Image,包含完整元数据(spacing、origin、direction 等) */
  itkImage: Image;
}
  • 从浏览器 File 对象读取图像
  • 从 Uint8Array 读取图像

readSTL

从文件中读取 STL 模型。

readObj

从文件中读取 OBJ 模型。

工具类

工具类主要是提供一些静态函数,供开发人员调用获取数据的接口。目前支持的有以下三种:

  • createFrame 用于创建矩形
  • createLine 用于创建直线
  • createPoint 用于创建点

使用示例

vue
<script setup lang="ts">
import { ref, onMounted } from "vue";
import { XDataStore } from "@/data/XDataStore";
import type { Vector3 } from "@kitware/vtk.js/types.d.ts";
import { createLine } from "@/utils/createLine";
import { createPoint } from "@/utils/createPoint";
import { createFrame } from "@/utils/createFrame";

onMounted(() => {
  XDataStore.getInstance()
    .addPropData("test")
    .add(createLine.line([0, 0, 0], [1, 1, 1]))
    .add(createLine.dashedLine([0, 0, 0], [10, 0, 0]))
    .add(createPoint.point([0, 0, 0], 0.1))
    .add(createPoint.crossPoint([1, 1, 1], 0.1))
    .add(createFrame.frame([0, 0, 0], [1, 1, 1]))
    .print();
});
</script>

createPoint

  • 创建一个点,radius 点的半径,thetaResolution 点的经向分辨率,phiResolution 点的纬向分辨率
  • 创建一个十字形的点,由三条线段组成,分别沿 x、y、z 轴方向

createLine

  • 创建一条线段,连接两个点 p1 和 p2
  • 创建虚线,由 numSegments 段等间距短线组成

createFrame

  • 创建一个矩形框架,由四条线段组成,连接 leftToprightBottom 定义的两个对角点
  • 创建一个虚线矩形框架,由四条虚线段组成,连接 leftToprightBottom 定义的两个对角点,numSegments 每条边的虚线段数,默认为 10