四维 / 动态体数据
我们认为这块内容足够重要,值得单独设一节。
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
) {
// ...
}
constructor(
imageVolumeProperties: ImageVolumeProps & {
splittingTag: string;
imageIdGroups: string[][];
},
streamingProperties: IStreamingVolumeProperties
) {
// ...
}
迁移步骤:
- 修改构造函数的调用,传入
imageIdGroups而不是scalarData。 - 删掉此前处理
scalarData数组的那些代码。
管理 ImageId 的新方法
版本 2 引入了几个管理 image ID 的新方法:
getCurrentTimePointImageIds()flatImageIdIndexToTimePointIndex()flatImageIdIndexToImageIdIndex()
迁移步骤:
- 用
getCurrentTimePointImageIds()取得当前时间点的 image ID。 - 用
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();
迁移步骤:
- 把对
scalarData数组的直接访问,替换为调用相应的VoxelManager方法。 - 把此前手工管理时间点的代码,改用
VoxelManager那些「知道时间点」的方法。 - 用
getCurrentTimePointScalarData()或getTimePointScalarData(tp)替代已被移除的getScalarData()方法。 - 如果需要跨所有时间点做操作,可以借助
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;
import {
cornerstoneStreamingDynamicImageVolumeLoader,
StreamingDynamicImageVolume,
} from '@cornerstonejs/core';
import { getDynamicVolumeInfo } from '@cornerstonejs/core/utilities';
import { Enums } from '@cornerstonejs/core/enums';
Enums.Events.DYNAMIC_VOLUME_TIME_POINT_INDEX_CHANGED;
getDataInTime
imageCoordinate 选项现在改名为 worldCoordinate,
以更准确地反映它是一个世界坐标、而不是影像坐标。
- 迁移前 📦
- 迁移后 🚀
function getDataInTime(
dynamicVolume: Types.IDynamicImageVolume,
options: {
frameNumbers?;
maskVolumeId?;
imageCoordinate?;
}
): number[] | number[][];
function getDataInTime(
dynamicVolume: Types.IDynamicImageVolume,
options: {
frameNumbers?;
maskVolumeId?;
worldCoordinate?;
}
): number[] | number[][];
用法示例
- 迁移前 📦
- 迁移后 🚀
const result = getDataInTime(dynamicVolume, {
frameNumbers: [0, 1, 2],
imageCoordinate: [100, 100, 100],
});
const result = getDataInTime(dynamicVolume, {
frameNumbers: [0, 1, 2],
worldCoordinate: [100, 100, 100],
});
generateImageFromTimeData
- 迁移前 📦
- 迁移后 🚀
function generateImageFromTimeData(
dynamicVolume: Types.IDynamicImageVolume,
operation: string,
frameNumbers?: number[]
);
function generateImageFromTimeData(
dynamicVolume: Types.IDynamicImageVolume,
operation: Enums.GenerateImageType,
options: {
frameNumbers?: number[];
}
): Float32Array;
主要变化
operation现在使用Enums.GenerateImageType枚举。- 帧号改为放在一个 options 对象里传入。
- 该函数现在显式返回
Float32Array。
用法示例
- 迁移前 📦
- 迁移后 🚀
const result = generateImageFromTimeData(dynamicVolume, 'SUM', [0, 1, 2]);
const result = generateImageFromTimeData(
dynamicVolume,
Enums.GenerateImageType.SUM,
{
frameNumbers: [0, 1, 2],
}
);
其他变化汇总
- 新增了
updateVolumeFromTimeData函数,用于就地更新体数据。 - 这两个函数现在都使用
voxelManager,性能更好。 - 错误处理得到加强,错误信息也做了统一。
- 各项操作现在使用
Enums.GenerateImageType,类型安全性更好。
本页描述的是 2.x 的状态。基于时间点(time point)的这套 API
在 4.x 中已被移除,改为基于维度组(dimension group)的 API——
timePointIndex 变为从 1 起算的 dimensionGroupNumber,
相关事件也一并改名。如果你要升级到 4.x 或更高版本,请接着看
动态体数据 API 的变化。