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 方案
在加载图像时,由于需要加载大量的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))) };