美文网首页
vue 使用cornerstone展示 dicom 影像数据

vue 使用cornerstone展示 dicom 影像数据

作者: 带熊二来看简书 | 来源:发表于2021-02-04 12:27 被阅读0次

    cornerstone 库地址

    可能访问失败,建议翻墙使用

    需要用到的依赖库,可 npm 可自行加入项目public 文件夹中,这里提供文件下载

    点此下载 密码: tcg3

    注意(坑)

    cornerstoneWADOImageLoader.js 文件中需要自行修改 path 路径(注意:是绝对路径哦),大概在 1750 行。当时卡了好久。

    var defaultConfig = {
     maxWebWorkers: navigator.hardwareConcurrency || 1,
     startWebWorkersOnDemand: true,
     webWorkerPath: '/models/js/cornerstoneWADOImageLoaderWebWorker.js',//此路径需要自行修改
     webWorkerTaskPaths: [],
     taskConfiguration: {
     decodeTask: {
     loadCodecsOnStartup: true,
     initializeCodecsOnStartup: false,
     codecsPath: '/models/js/cornerstoneWADOImageLoaderCodecs.js',//此路径需要自行修改
     usePDFJS: false,
     strict: options.strict
     }
     }
    };
    

    写在前面

    我只介绍了 cornerstone 的一些基本用法,具体如何在项目中应用,还是要灵活使用,例如我在项目中使用是先通过递归来缓存了所有的图像再逐个展示,节省了加载的时间;通过算法分析的结节坐标信息在图像上绘制结节等。如果需要帮助可留言。码字不易,研究不易,如需转载请注明出处。

    准备工作完毕,开始引入组件中

     *  需要安装的插件
     *  npm install --save dicom-parser //这个需要安装
    */
    // import Hammer from 'hammerjs';//移动端手势插件 npm install hammerjs --save //选用,不需要移动端可不用
    import * as cornerstone from '../../public/models/js/cornerstone';
    import * as cornerstoneTools from '../../public/models/js/cornerstoneTools.js';
    import * as cornerstoneWADOImageLoader from '../../public/models/js/cornerstoneWADOImageLoader';
    /*
     * cornerstoneMath.min.js文件 import 始终报错,无奈,最终在 index.html中加入解决,原因未知,知道的大佬可以告知一下
     * <script src="./models/js/cornerstoneMath.min.js"></script>
    */
    ​
    cornerstoneTools.external.cornerstone = cornerstone;
    // cornerstoneTools.external.Hammer = Hammer;
    cornerstoneTools.external.cornerstoneMath = cornerstoneMath;
    ​
    cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
    cornerstoneWADOImageLoader.external.cornerstoneMath = cornerstoneMath;
    

    初始化

    <template>
     <div id="DICOM" ref='dicom_canvas'></div>
    </template>
    ......
    init(){
     let element=this.$refs.dicom_canvas;//获取 dicom 元素节点
     cornerstone.enable(element);//启用节点
     window.addEventListener('resize',function(e){//自适应窗口
     cornerstone.resize(element,true)
     })
    }
    

    载入影像数据

    start(){
     cornerstone.loadAndCacheImage('http:XXXXXXXX.dcm').then((image)=>{//加载并缓存数据
     cornerstone.displayImage(element,image)//展示 dicom,参数 1:element 元素,参数 2:image
     this.getImageInfo(image);//获取图片信息
     }).catch((err)=>console.log(err))
    }
    

    cornerstoneimagerendered事件(重要!)

    每当图像被cornerstone重新绘制时,将发出CornerstoneImageRendered事件调用。这个事件包括可以使用HTML5 canvas上下文(例如几何图形或文本)在图像上绘制的信息。你也可以更新HTML覆盖与各种视口属性,如窗口宽度,窗口级别和缩放。

    ......
     element.addEventListener('cornerstoneimagerendered',function(e){
     let eventData=e.detail;
     this.getViewPort(eventData);//获取当前图片视口信息
     })
    getViewPort(eventData){
     this.imageInfo.windowWidth=Math.round(eventData.viewport.voi.windowWidth);//窗宽
     this.imageInfo.windowCenter=Math.round(eventData.viewport.voi.windowCenter);//窗位
     this.imageInfo.scale=parseInt(10 * eventData.viewport.scale);//缩放等级
    }
    getImageInfo(image){
     this.imageInfo.seriesNumber=image.data.string('x00200011');//图像序列号
     this.imageInfo.imageNum=image.data.string('x00200013');//图像位置
     this.imageInfo.imageDate=image.data.string("x00080021");//拍摄日期
     this.imageInfo.sliceThickness=image.data.string('x00180050');//层厚
     this.imageInfo.patientId=image.data.string('x00100020');//病理号
     // 判断窗宽窗位是否合法
     this.pixelR = image.data.uint16('x00280103');
     this.heightBit = image.data.uint16('x00280102') || '';
     // 病人基本信息
     this.patientName = image.data.string('x00100010');
     this.patientBirthDate = image.data.string('x00100030');
     this.patientID = image.data.string('x00100020');
     this.patientGender = image.data.string('x00100040');
     this.sID = image.data.string('x00200011');
     // 像素间距
     this.pixelSpacing = image.data.string('x00280030');
     this.imagePixelSpacing = image.data.string('x00181164') || '';
     this.rowPixelSpacing = image.rowPixelSpacing;
     // 放射放大系数
     this.magnification = Number(image.data.string('x00181114'));
     // 放射源到面板的距离
     this.sourceTOdetector = image.data.string('x00181110');
     // 放射源到病人的距离
     this.sourceTOpatient = image.data.string('x00181111');
     //this.modalityLUT = cornerstone.metaData.get('modalityLutModule', image.imageId).modalityLUTSequence;
     this.voiContent = cornerstone.metaData.get('voiLutModule', image.imageId);
     // 斜率截距
     this.rescaleIntercept = Number(image.data.string('x00281052'));
     this.rescaleSlope = Number(image.data.string('x00281053'));
    }
    

    cornerstoneTools (工具)

    // 启用工具
    /*
     数字:1 代表鼠标左键;2 代表鼠标中键;4 代表鼠标右键
     可逐一试验功能
    */
    cornerstoneTools.mouseInput.enable(this.element);//启动鼠标按下事件
     enableAllTools() {
     cornerstoneTools.wwwc.activate(element);
     cornerstoneTools.pan.activate(element, 2); 
     cornerstoneTools.zoom.activate(element, 1); 
     cornerstoneTools.probe.activate(element, 1);
     cornerstoneTools.length.activate(element, 1);
     cornerstoneTools.ellipticalRoi.activate(element, 1);
     cornerstoneTools.rectangleRoi.activate(element, 1);
     cornerstoneTools.angle.activate(element, 1);
     cornerstoneTools.highlight.activate(element, 1);
     cornerstoneTools.freehand.activate(element, 1);
     cornerstoneTools.stackScroll.activate(element);
     cornerstoneTools.arrowAnnotate.activate(element, 1);
     cornerstoneTools.freehand.activate(element, 1);
     // touch
     cornerstoneTools.wwwcTouchDrag.deactivate(element);
     cornerstoneTools.probeTouch.deactivate(element);
     cornerstoneTools.panTouchDrag.deactivate(element);
     cornerstoneTools.zoomTouchDrag.deactivate(element);
     cornerstoneTools.lengthTouch.deactivate(element);
     cornerstoneTools.ellipticalRoiTouch.deactivate(element);
     cornerstoneTools.rectangleRoiTouch.deactivate(element);
     cornerstoneTools.angleTouch.deactivate(element);
     cornerstoneTools.stackScrollTouchDrag.deactivate(element);
     cornerstoneTools.arrowAnnotateTouch.deactivate(element);
     cornerstoneTools.rotateTouchDrag.deactivate(element);
     cornerstoneTools.rotateTouch.disable(element);
     }
    // 停用工具    // before making a new tool active
     disableAllTools() {
     cornerstoneTools.wwwc.disable(element);
     cornerstoneTools.pan.deactivate(element, 2);
     cornerstoneTools.zoom.deactivate(element, 1); 
     cornerstoneTools.probe.deactivate(element, 1);
     cornerstoneTools.length.deactivate(element, 1);
     cornerstoneTools.ellipticalRoi.deactivate(element, 1);
     cornerstoneTools.rectangleRoi.deactivate(element, 1);
     cornerstoneTools.angle.deactivate(element, 1);
     cornerstoneTools.highlight.deactivate(element, 1);
     cornerstoneTools.freehand.deactivate(element, 1);
     cornerstoneTools.stackScroll.deactivate(element);
     cornerstoneTools.arrowAnnotate.deactivate(element, 1);
     cornerstoneTools.freehand.deactivate(element, 1);
     // touch
     cornerstoneTools.wwwcTouchDrag.deactivate(element);
     cornerstoneTools.probeTouch.deactivate(element);
     cornerstoneTools.panTouchDrag.deactivate(element);
     cornerstoneTools.zoomTouchDrag.deactivate(element);
     cornerstoneTools.lengthTouch.deactivate(element);
     cornerstoneTools.ellipticalRoiTouch.deactivate(element);
     cornerstoneTools.rectangleRoiTouch.deactivate(element);
     cornerstoneTools.angleTouch.deactivate(element);
     cornerstoneTools.stackScrollTouchDrag.deactivate(element);
     cornerstoneTools.arrowAnnotateTouch.deactivate(element);
     cornerstoneTools.rotateTouchDrag.deactivate(element);
     cornerstoneTools.rotateTouch.disable(element);
     }
    

    改变窗宽窗位

    windowChange(index){
     /*
     * index=1 ww:default,wl:default
     * index=2 ww:1500,wl:-450
     * index=3 ww:250,wl:30
     * index=4 ww:1000,wl:250
     * index=5 ww:300,wl:40
     */
     let viewportDefault = cornerstone.getDefaultViewportForImage(element, image);//获取当前图像默认的窗宽窗位
     // console.log(viewportDefault.voi.windowWidth,viewportDefault.voi.windowCenter)
     let viewport = cornerstone.getViewport(this.element);
     viewport.voiLUT = undefined;
    ​
    ​
     if(index==1){
     viewport.voi.windowWidth = viewportDefault.voi.windowWidth;
     viewport.voi.windowCenter = viewportDefault.voi.windowCenter;
     }else if(index==2){
     viewport.voi.windowWidth = 1500;
     viewport.voi.windowCenter = -450;
     }else if(index==3){
     viewport.voi.windowWidth = 250;
     viewport.voi.windowCenter = 30;
     }else if(index==4){
     viewport.voi.windowWidth = 1000;
     viewport.voi.windowCenter = 250;
     }else if(index==5){
     viewport.voi.windowWidth = 300;
     viewport.voi.windowCenter = 40;
     }
     cornerstone.setViewport(this.element, viewport);//调节窗宽窗位
     },
    

    鼠标滚轮切换图像

     /*鼠标滚轮事件 */
     mousewheelChange(){
     let _this=this;
     const wheelEvents = ['mousewheel', 'DOMMouseScroll'];
     wheelEvents.forEach((eventType) => {
     this.element.addEventListener(eventType, this.mousewheelHandle);
     });
     },
    
     mousewheelHandle(e){
     let _this=this;
     // Firefox e.detail > 0 scroll back, < 0 scroll forward
     // chrome/safari e.wheelDelta < 0 scroll back, > 0 scroll forward
     if (e.wheelDelta < 0  || e.detail > 0) {//向下滚动
     _this.currentImageIndex++;
     if(_this.currentImageIndex>_this.nowSeries.length-1){
     _this.currentImageIndex=0
     }
     } else {//向上滚动
     _this.currentImageIndex--;
     if(_this.currentImageIndex<0){
     _this.currentImageIndex=_this.nowSeries.length-1
     }
     }
     _this.updateTheImage(_this.currentImageIndex);//根据 ID 索引切换图像
    ​
     // 防止页面滚动
     return false;
     },
    

    其他功能

    // set the canvas context to the image coordinate system(将画布上下文设置为图像坐标系统)
    //绘制前调用
     cornerstone.setToPixelCoordinateSystem(eventData.enabledElement, eventData.canvasContext);
    ​
    //坐标转换
    cornerstone.pageToPixel(element, X, Y)//将像素坐标转为图像坐标,返回x,y对象
    ​
    //更新图像
    cornerstone.updateImage(element);
    ​
    //清除缓存
    cornerstone.imageCache.purgeCache();
    cornerstoneWADOImageLoader.wadouri.dataSetCacheManager.purge();
    cornerstoneWADOImageLoader.wadouri.fileManager.purge();
    ​
    //查看缓存
    const cacheInfo = cornerstone.imageCache.getCacheInfo();
    

    相关文章

      网友评论

          本文标题:vue 使用cornerstone展示 dicom 影像数据

          本文链接:https://www.haomeiwen.com/subject/pklbtltx.html