跳到主要内容

四维 / 动态体数据

我们认为这块内容足够重要,值得单独设一节。

imageIdsGroups 改名为 imageIdGroups​

如果你原先是用 splitImageIdsBy4DTags 来取 imageIdsGroups 的, 那么现在返回对象里的字段是 imageIdGroups,而不是 imageIdsGroups。

迁移做法:

const { imageIdsGroups } = splitImageIdsBy4DTags(imageIds);

应改为

const { imageIdGroups } = splitImageIdsBy4DTags(imageIds);

StreamingDynamicImageVolume​

构造函数的变化​

构造函数签名已更新:改为接收 imageIdGroups,而不是若干独立的 scalarData 数组。

constructor(
imageVolumeProperties: Types.ImageVolumeProps & { splittingTag: string },
streamingProperties: Types.IStreamingVolumeProperties
) {
// ...
}

迁移步骤:

  1. 修改构造函数的调用,传入 imageIdGroups 而不是 scalarData。
  2. 删掉此前处理 scalarData 数组的那些代码。

管理 ImageId 的新方法​

版本 2 引入了几个管理 image ID 的新方法:

  • getCurrentTimePointImageIds()
  • flatImageIdIndexToTimePointIndex()
  • flatImageIdIndexToImageIdIndex()

迁移步骤:

  1. 用 getCurrentTimePointImageIds() 取得当前时间点的 image ID。
  2. 用 flatImageIdIndexToTimePointIndex() 和 flatImageIdIndexToImageIdIndex() 在扁平索引与时间点 / 影像索引之间换算。

getScalarData 方法被移除,动态影像体数据改用 VoxelManager​

getScalarData() 方法在版本 2 中被移除,改由新的 VoxelManager 承担。

在版本 2 中,StreamingDynamicImageVolume 类现在使用 VoxelManager 来处理时间点数据。这带来了更高效的内存管理, 也让跨时间点访问体素数据更容易。下面是用 VoxelManager 访问和操作动态影像体数据的方式。

访问体素数据​

访问当前时间点的体素数据:

const voxelValue = volume.voxelManager.get(index);

访问某个特定时间点的体素数据:

const voxelValue = volume.voxelManager.getAtIndexAndTimePoint(index, timePoint);

取得标量数据​

取得当前时间点完整的标量数据数组:

const scalarData = volume.voxelManager.getCurrentTimePointScalarData();

取得某个特定时间点的标量数据:

const scalarData = volume.voxelManager.getTimePointScalarData(timePoint);

取得体数据信息​

可以通过 VoxelManager 访问体数据的各项属性:

const scalarDataLength = volume.voxelManager.getScalarDataLength();
const dataType = volume.voxelManager.getConstructor();
const dataRange = volume.voxelManager.getRange();
const middleSliceData = volume.voxelManager.getMiddleSliceData();

迁移步骤:

  1. 把对 scalarData 数组的直接访问,替换为调用相应的 VoxelManager 方法。
  2. 把此前手工管理时间点的代码,改用 VoxelManager 那些「知道时间点」的方法。
  3. 用 getCurrentTimePointScalarData() 或 getTimePointScalarData(tp) 替代已被移除的 getScalarData() 方法。
  4. 如果需要跨所有时间点做操作,可以借助 numTimePoints 属性 配合 getTimePointScalarData(tp) 方法来遍历。

借助 VoxelManager,你就能高效地处理动态影像体数据, 而不必手工管理多个标量数据数组。这种方式带来更好的性能和内存占用, 对时间点很多的大型数据集尤其明显。

导出与引入​

如果你此前使用的是 @cornerstonejs/streaming-image-volume-loader, 就需要更新 import,并可能要调整代码以使用 @cornerstonejs/core 中那套整合后的体数据加载 API。

import {
cornerstoneStreamingDynamicImageVolumeLoader,
StreamingDynamicImageVolume,
helpers,
Enums,
} from '@cornerstonejs/streaming-image-volume-loader';

Enums.Events.DYNAMIC_VOLUME_TIME_POINT_INDEX_CHANGED;

getDataInTime​

imageCoordinate 选项现在改名为 worldCoordinate, 以更准确地反映它是一个世界坐标、而不是影像坐标。

function getDataInTime(
dynamicVolume: Types.IDynamicImageVolume,
options: {
frameNumbers?;
maskVolumeId?;
imageCoordinate?;
}
): number[] | number[][];

用法示例​

const result = getDataInTime(dynamicVolume, {
frameNumbers: [0, 1, 2],
imageCoordinate: [100, 100, 100],
});

generateImageFromTimeData​

function generateImageFromTimeData(
dynamicVolume: Types.IDynamicImageVolume,
operation: string,
frameNumbers?: number[]
);

主要变化​

  1. operation 现在使用 Enums.GenerateImageType 枚举。
  2. 帧号改为放在一个 options 对象里传入。
  3. 该函数现在显式返回 Float32Array。

用法示例​

const result = generateImageFromTimeData(dynamicVolume, 'SUM', [0, 1, 2]);

其他变化汇总​

  • 新增了 updateVolumeFromTimeData 函数,用于就地更新体数据。
  • 这两个函数现在都使用 voxelManager,性能更好。
  • 错误处理得到加强,错误信息也做了统一。
  • 各项操作现在使用 Enums.GenerateImageType,类型安全性更好。
后续版本的进一步变化

本页描述的是 2.x 的状态。基于时间点(time point)的这套 API 在 4.x 中已被移除,改为基于维度组(dimension group)的 API—— timePointIndex 变为从 1 起算的 dimensionGroupNumber, 相关事件也一并改名。如果你要升级到 4.x 或更高版本,请接着看 动态体数据 API 的变化。