CornerstoneJs用法

800 阅读3分钟

CornerstoneJs用法

1. 简介

cornerstonejs是一个开源项目,是为了提供一个基于 web 的医疗成像平台。github地址

主要用到了其中五个模块

库名作用
cornerstone Core提供图像渲染、加载、缓存和视口转换的中央库
cornerstone Tools用于帮助注释、分割和测量医学图像
cornerstone WADO Image Loader用于通过 HTTP(WADO-URI)或 DICOMWeb(WADO-RS)的 DICOM P10 实例的图像加载器
dicom Parser用于在现代基于 HTML5 的 web 浏览器(IE10+)节点中解析 DICOM P10 字节流以及原始(未封装在第 10 部分中)字节流
cornerstone Math数学和计算几何

2. vue项目集成

  • 安装库

    通过下面的命令安装以上5个库

    // cornerstone Core
    yarn add cornerstone-core
    ​
    // cornerstone Tools
    yarn add cornerstone-tools
    ​
    // cornerstone WADO Image Loader
    yarn add cornerstone-wado-image-loader
    ​
    // dicom-parser
    yarn add dicom-parser
    ​
    // cornerstone Math
    yarn add cornerstone-math
    
  • vite配置

    cornerstone在引入后悔生成唯一的一个cornerstone对象,为了在各个模块中使用这个对象,需要引入插件,将其配置为全局变量

    安装rollup/plugin-inject插件

    yarn add @rollup/plugin-inject
    

    由于cornerstone库为commonjs规范,vite基于ESbuild,所以要对其进行兼容性处理

    安装rollup/plugin-commonjs插件

    yarn add @rollup/plugin-commonjs
    

    然后再vite中配置全局变量

    import inject from '@rollup/plugin-inject';
    import commonjs from '@rollup/plugin-commonjs';
    import { defineConfig } from 'vite';
    export default defineConfig({
        plugins: [
            commonjs(),
            inject({
                cornerstone: 'cornerstone-core',
                'window.cornerstone': 'cornerstone-core',
                dicomParser: 'dicom-parser',
                'window.dicomParser': 'dicom-parser',
                cornerstoneTools: 'cornerstone-tools/dist/cornerstoneTools.min.js',
                'window.cornerstoneTools': 'cornerstone-tools/dist/cornerstoneTools.min.js',
                cornerstoneWADOImageLoader: 'cornerstone-wado-image-loader/dist/cornerstoneWADOImageLoader.bundle.min.js',
                'window.cornerstoneWADOImageLoader': 'cornerstoneWADOImageLoader',
            }),
        ],
        define: {
            'process.env': {},
        },
        resolve: {
            alias: {
                '@': resolve('./src'),
                cornerstone: 'cornerstone-core',
                dicomParser: 'dicom-parser',
                cornerstoneTools: 'cornerstone-tools/dist/cornerstoneTools.min.js',
                cornerstoneWADOImageLoader: 'cornerstone-wado-image-loader/dist/cornerstoneWADOImageLoader.bundle.min.js',
            },
        },
        base: '/', // 打包路径
    });
    
  • 项目主入口配置

    需要在main.js中注册cornerstone各个模块,并初始化cornerstoneTools工具以及WebWorker

    import { createApp } from 'vue';
    import './style.css';
    import App from './App.vue';
    import { store } from '@/store';
    import router from '@/router/index';
    // import './router/permission';
    import 'element-plus/theme-chalk/dark/css-vars.css';
    import './assets/icon/iconfont';
    import './assets/icon/iconfont.css';
    import './styles/common.scss';
    import cornerstone from 'cornerstone-core';
    import dicomParser from 'dicom-parser';
    import cornerstoneMath from 'cornerstone-math';
    import cornerstoneTools from 'cornerstone-tools/dist/cornerstoneTools.min.js';
    import Hammer from 'hammerjs';
    // import cornerstoneDICOMImageLoader from '@cornerstonejs/dicom-image-loader/dist/dynamic-import/cornerstoneDICOMImageLoader.min.js';
    import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader/dist/cornerstoneWADOImageLoader.bundle.min.js';
    ​
    const app = createApp(App);
    app.use(router);
    app.use(store);
    app.use(cornerstone);
    app.use(dicomParser);
    app.use(cornerstoneWADOImageLoader);
    // 指定要注册加载程序的基石实例
    cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
    // dicom影像数据转换
    cornerstoneWADOImageLoader.external.dicomParser = dicomParser;
    ​
    let webWorkerUrl = './assets/cornerstone/cornerstoneWADOImageLoaderWebWorker.js';
    let codecsUrl = 'cornerstoneWADOImageLoaderCodecs.js';
    let config = {
        maxWebWorkers: navigator.hardwareConcurrency || 1,
        startWebWorkersOnDemand: true,
        webWorkerPath: webWorkerUrl,
        webWorkerTaskPaths: [],
        taskConfiguration: {
            decodeTask: {
                loadCodecsOnStartup: true,
                initializeCodecsOnStartup: false,
                codecsPath: codecsUrl,
                usePDFJS: false,
                strict: false,
            },
        },
    };
    cornerstoneWADOImageLoader.webWorkerManager.initialize(config);
    cornerstoneTools.init({
        // 当元素被启用时,是否监听鼠标事件
        mouseEnabled: true,
        // 当元素被启用时,是否监听触摸事件
        touchEnabled: true,
        // 全局工具同步
        globalToolSyncEnabled: true,
        // 显示svg光标
        showSVGCursors: false,
        // 自动调整视口大小
        autoResizeViewports: true,
        // 虚线样式
        lineDash: [4, 4],
    });
    cornerstoneTools.external.cornerstone = cornerstone;
    cornerstoneTools.external.Hammer = Hammer;
    cornerstoneTools.external.cornerstoneMath = cornerstoneMath;
    ​
    app.use(cornerstoneTools);
    app.mount('#app');
    

3. loader简介

在此之前需要了解imageIds

ImageId是一个URL,它标识要显示的单个图像。cornerstone使用ImageId中的URL模式来确定要调用哪个loader来加载图像,该策略允许工具同时显示多个不同的协议或者不同的服务器获取到的图像。例如,cornerstone可以将通过WADO获得的DICOM CT图像与JPEG皮肤病学图像一起显示,这些图像由数码相机捕获并存储在文件系统中

常见的imageId类型

// wadouri - HTTP GET
const wadouriImageId =
  "wadouri:http://xxx/wado?requestType=WADO&studyUID=1.3.6.1.4.1.25403.166563008443.5076.20120418075541.1";
​
// dicomweb - HTTP GET
const dicomwebImageId =
  "dicomweb:http://xxxx/wado?requestType=WADO&studyUID=1.3.6.1.4.1.25403.166563008443.5076.20120418075541.1";
​
// wadors - RESTful 风格 HTTP GET
const wadorsImageId =
  "wadors:https://xxx/xxx/studies/1.3.6.1.4.1.14519.5.2.1.7777.9002.198875685720513246512710453733/series/1.3.6.1.4.1.14519.5.2.1.7777.9002.207203214132667549392101803048/instances/1.3.6.1.4.1.14519.5.2.1.7777.9002.327873213718058651550666129029/frames/1";
​
// dicomfile - 本地文件
const dicomfileImageId = "dicomfile:1";

imageloader流程

ImageLoader 向 cornerstone 注册,加载特定的 ImageId URL 方案

2352e65314644d98b87b150bfd4fabc8.png

在加载图像时,由于需要加载大量的DICOM文件,所以需要使用到Web Workers技术来请求图像。由于JavaScript是单线程的,Web Worker的出现就是为 Web 内容在后台线程中运行脚本提供了一种简单的方法。线程可以执行任务而不干扰用户界面。通过Worker() 构造器启动worker线程在后台请求多个影像

4. 简单使用

  • 通过请求获取到DICOM地址,并将地址存在imageIds中

    let imageIds = []
    const getImage = async () => {
        const {imageList} = await getImageList();
        imageList.forEach((item) => {
            item?.url && imageIds.value.push('wadouri:' + item.url);
        });
    };
    
  • 模板中需要有影像容器用于显示影像

    <template>
        <div class="cornerstone-content" ref="dicomCanvas"></div>
    </template>
    
  • 请求通过cornerstone请求并加载图像

    const dicomCanvas = ref();
    const loadAndViewImage = async () => {
        const image = await cornerstone.loadAndCacheImage(imageIds.value[0]);
        cornerstone.displayImage(dicomCanvas.value, image);
        cornerstoneHandle.viewportResize(dicomCanvas.value);
        Promise.all(imageIds.value.map((imageId) => cornerstone.loadAndCacheImage(imageId)))
    };