cornerstone3D学习笔记-MPR

最近在研究如何利用cornerstone3D (v1.70.13) 来实现MPR功能,找到它的一个demo -- volumeBasic, 运行效果如下图

看了下主程序的示例代码,非常简单,可以说corestone3D这个库把很多细节都封装起来了,使得调用者可以很简单的快速实现多平面重建,为了便于在它的基础上进行集成和调整,还是有必要深入了解它的内部实现,现将笔者的理解整理出来分享给读者。

笔者研究的cornerstone3D的版本是 v1.70.13, 代码入口路径在cornerstone3D/packages/core/examples/volumeBasic/index.ts

TypeScript 复制代码
import {
  RenderingEngine,
  Types,
  Enums,
  volumeLoader,
  CONSTANTS,
} from '@cornerstonejs/core';
import {
  initDemo,
  createImageIdsAndCacheMetaData,
  setTitleAndDescription,
  setCtTransferFunctionForVolumeActor,
} from '../../../../utils/demo/helpers';

// This is for debugging purposes
console.warn(
  'Click on index.ts to open source code for this example --------->'
);

const { ViewportType } = Enums;

// ======== Set up page ======== //
setTitleAndDescription(
  'Basic Volume',
  'Displays a DICOM series in a Volume viewport.'
);

const content = document.getElementById('content');
const element = document.createElement('div');
element.id = 'cornerstone-element';
element.style.width = '500px';
element.style.height = '500px';

content.appendChild(element);
// ============================= //

/**
 * Runs the demo
 */
async function run() {
  // Init Cornerstone and related libraries
  await initDemo();

  // Get Cornerstone imageIds and fetch metadata into RAM
  const imageIds = await createImageIdsAndCacheMetaData({
    StudyInstanceUID:
      '1.3.6.1.4.1.14519.5.2.1.7009.2403.334240657131972136850343327463',
    SeriesInstanceUID:
      '1.3.6.1.4.1.14519.5.2.1.7009.2403.226151125820845824875394858561',
    wadoRsRoot: 'https://d3t6nz73ql33tx.cloudfront.net/dicomweb',
  });

  // Instantiate a rendering engine
  const renderingEngineId = 'myRenderingEngine';
  const renderingEngine = new RenderingEngine(renderingEngineId);

  // Create a stack viewport
  const viewportId = 'CT_SAGITTAL_STACK';
  const viewportInput = {
    viewportId,
    type: ViewportType.ORTHOGRAPHIC,
    element,
    defaultOptions: {
      orientation: Enums.OrientationAxis.SAGITTAL,
      background: <Types.Point3>[0.2, 0, 0.2],
    },
  };

  renderingEngine.enableElement(viewportInput);

  // Get the stack viewport that was created
  const viewport = <Types.IVolumeViewport>(
    renderingEngine.getViewport(viewportId)
  );

  // Define a unique id for the volume
  const volumeName = 'CT_VOLUME_ID'; // Id of the volume less loader prefix
  const volumeLoaderScheme = 'cornerstoneStreamingImageVolume'; // Loader id which defines which volume loader to use
  const volumeId = `${volumeLoaderScheme}:${volumeName}`; // VolumeId with loader id + volume id

  // Define a volume in memory
  const volume = await volumeLoader.createAndCacheVolume(volumeId, {
    imageIds,
  });

  // Set the volume to load
  volume.load();

  // Set the volume on the viewport
  viewport.setVolumes([
    { volumeId, callback: setCtTransferFunctionForVolumeActor },
  ]);

  // Render the image
  viewport.render();
}

run();

下图是对这个代码的基本分析

下图是针对imageLoader.loadImage做了更细致的分析,描述是如何从后端得到影像原始数据并转换到Volume里

对整个过程可以总结来说就是:

  • 初始化和注册imageLoader(cornerstoneDICOMImageLoader),这个是专门用于下载并解码DICOM图像并加载到Volume的图像buffer里。初始化和注册VolumeLoader, 这个是用于将二维数据重建为Volume。
  • 通过dicomwebClient从后端获取meta信息
  • 初始化renderEnginee(专门处理渲染)及viewport和canvas
  • 使用volumeLoader(cornerstoneStreamingImageVolumeLoader)创建volume实例(streamingImageVolume), 并初始化volume的scalarData和imageData的数据结构 (基于vtk.js)
  • 加载streamingImageVolume,触发cornerstoneDICOMImageLoader去从后端加载每张图片的原始图像数据并拷贝到volume的内部buffer里
  • 将viewport与volume绑定,调用vtk的内部方法去实现mapper,actor的初始化
  • 调用viewport的render方法,其实最终是调用vtk的渲染方法

因笔者能力有限,代码也仅分析到这个层面,权当抛砖引玉,更多细节请读者自行研究

相关推荐
心无旁骛~2 小时前
Git笔记汇总,持续更新~
笔记·git
陈无左耳、2 小时前
HarmonyOS学习第2天: 解锁语言与框架的无限可能
学习·华为·harmonyos
朝九晚五ฺ2 小时前
【Linux探索学习】第三十弹——线程互斥与同步(上):深入理解线程保证安全的机制
linux·运维·学习
东方芷兰2 小时前
伯克利 CS61A 课堂笔记 12 —— Syntax
笔记·python
柃歌2 小时前
【UCB CS 61B SP24】Lecture 5 - Lists 3: DLLists and Arrays学习笔记
java·数据结构·笔记·学习·算法
剑走偏锋o.O3 小时前
MyBatis框架详解与核心配置解读
java·学习·mybatis
2025年一定要上岸3 小时前
Java EE初阶-计算机导论
学习·java-ee
im长街3 小时前
Ubuntu22.04 - gflags的安装和使用
学习
梦游钓鱼4 小时前
beremiz笔记chatgpt,部署在Ubuntu:20.04版本
linux·笔记·ubuntu
南宫生4 小时前
力扣每日一题【算法学习day.131】
java·学习·算法·leetcode