影像云胶片:Dicom纯js的三维重建影像阅片器

影像云胶片主要:通过浏览器浏览Dicom影像阅片,通过多终端设备(如电脑、平板、手机),为医生、患者及其他授权人员提供随时随地的影像调阅功能,打破时间和空间限制。同时,支持影像数据在不同医疗机构之间的安全共享,促进医疗协作与远程会诊的开展。主要功能:

  1. 支持标准DIcom影像的2D浏览,预设窗位,伪彩,序列间,序列内多种布局方式。
  2. 影像处理,提供影像翻图、缩放、移动、透镜、反相、旋转、截图等操作
  3. 影像测量,提供箭头、直线、十字架、角度、Cobb、心胸比、椭圆、矩形、勾画,橡皮擦、CT值等数据的测量
  4. 支持影像的三维重建,包括多平面重建,容积漫游技术(VR)、最大/小密度投影等功能
  5. 支持影像胶片打印功能,包括DR,CT等胶片自定义布局打印
  6. 支持平板,手机等移动设备的影像浏览

总体架构:BS(浏览器/服务器)架构

  • 前端:基于HTML5、WebGL技术开发,无需安装插件,支持PC浏览器、手机H5、微信小程序、支付宝小程序等多种终端。

  • 后端:后端居于fo-dicom组件进行开发,对dicom文件访问授权服务,访问MD5签名验证等身份验证。

核心技术栈

  • 影像渲染引擎:使用 VTK.js 等开源框架,实现基于WebGL的高性能二维、三维影像渲染。

  • DICOM服务:自研或使用开源组件(如fo-dicom)实现DICOM文件的接收(C-Store)、查询(C-Find)、检索(C-Move)等服务。

主要代码示例

1:前端采用有vue3+element-ui进行开发,检查屏幕大小,以便适应不同的屏幕

影像云胶片:Dicom纯js的三维重建影像阅片器

<script setup> import LeftSeriesMobile from './views/LeftSeriesMobile.vue' import CenterImage from './views/CenterImage.vue' import RightToolMobile from './views/RightToolMobile.vue' import { ElMessageBox } from 'element-plus'  // 注册resize事件监听器 调整laytou大小 window.addEventListener('resize', function (evt) {   if (window.innerWidth > 768) {     ElMessageBox.alert("系统检测到你在阅片期间对浏览器进行了缩放。为防止图像显示及测量工作不精确,强烈建议您重新打开影像!");   } });  </script>  <template>   <div class="divRightMb">     <RightToolMobile />   </div>   <div class="divCenterMb" id="divCenter">     <CenterImage />   </div>   <div class="divLeftMb">     <LeftSeriesMobile />   </div> </template>  <style scoped></style>

View Code

 

最终在PC端和手机端效果图如下:

影像云胶片:Dicom纯js的三维重建影像阅片器

影像云胶片:Dicom纯js的三维重建影像阅片器

 

 

2:使用VTK.js 等开源框架,实现基于WebGL的高性能二维、三维影像渲染。

 

影像云胶片:Dicom纯js的三维重建影像阅片器

//初始化一个视窗 function ViewGridChange_LoadDicom_OneView(layout, element, showSeries) {   //注册事件   element.addEventListener(IMAGE_RENDERED, IMAGE_RENDERED_CallBack);    layout.ShowSeries = showSeries;//当前窗体显示的序列对象   element.ShowSeries = showSeries;//当前窗体显示的序列对象   let viewport;   if (showSeries.SeriesItemType == 1) {     viewport = {       viewportId: layout.viewportId,       type: showSeries.viewType,       element: element     }     element.addEventListener(STACK_NEW_IMAGE, STACK_NEW_IMAGE_CallBack);   } else {     viewport = {       viewportId: layout.viewportId,       type: showSeries.viewType,       element: element,       defaultOptions: {         orientation: showSeries.orientation       },     }     element.addEventListener(VOLUME_NEW_IMAGE, VOLUME_NEW_IMAGE_CallBack);   }   return viewport; }

View Code

 

3:实现三维十字准线工具的功能

 影像云胶片:Dicom纯js的三维重建影像阅片器View Code

 

 ​三维重建效果如图所示:

影像云胶片:Dicom纯js的三维重建影像阅片器

影像云胶片:Dicom纯js的三维重建影像阅片器

 

 

4:胶片打印布局设置相关代码

 

影像云胶片:Dicom纯js的三维重建影像阅片器

//设置中间图像大小 let curGolb_PaperSize = "";//当前纸张大小 let curGolb_Direction = "";//当前方向 let curGolb_ShowScale = "1";//当前显示比例 function CenterSetImageSize(paperSize, direction, showScale, isPrint) {     SetImageSizeisPrint = isPrint;     if (isEmpty(paperSize)) paperSize = curGolb_PaperSize;     if (isEmpty(direction)) direction = curGolb_Direction;     if (isEmpty(showScale)) showScale = curGolb_ShowScale;     if (curGolb_PaperSize == paperSize && curGolb_Direction == direction && curGolb_ShowScale == showScale) {         return;     }     curGolb_PaperSize = paperSize;     curGolb_Direction = direction;     curGolb_ShowScale = showScale;      //根据纸张大写设置图像大小     let paperObj = null;     for (let i = 0; i < PaperSizeArys.length; i++) {         const item = PaperSizeArys[i];         if (item.value == paperSize) {             paperObj = item;             break;         }     }     if (!paperObj) return;      //设置图像大小     let imgWidth = 0;     let imgHeight = 0;     if (direction == "0") {//横向         imgWidth = paperObj.ImgHeight;         imgHeight = paperObj.ImgWidth;     } else {//纵向         imgWidth = paperObj.ImgWidth;         imgHeight = paperObj.ImgHeight;     }     let imgWidthPx = imgWidth * 96;     let imgHeightPx = imgHeight * 96;      let scaleFloat = 1;     if (showScale == "-2") {//自适应宽高         const rect = divImgElemet.parentElement.getBoundingClientRect();         //如果宽或者高 任意一个大于了外层容器 则进行缩放         if (imgWidthPx > rect.width || imgHeightPx > rect.height) {             //如果宽超出的范围更大,则以宽为基准进行缩放             if (imgWidthPx - rect.width >= imgHeightPx - rect.height) {                 scaleFloat = rect.width / imgWidthPx;             } else {                 //以高位基准进行缩放                 scaleFloat = rect.height / imgHeightPx;             }             scaleFloat = scaleFloat * 0.98;//自适应时设置图像显示比例98%,防止出现滚动条         }     } else if (showScale == "-1") {//自适应宽         const rect = divImgElemet.parentElement.getBoundingClientRect();         //如果宽或者高 任意一个大于了外层容器 则进行缩放         if (imgWidthPx > rect.width) {             //如果宽超出的范围更大,则以宽为基准进行缩放                         scaleFloat = rect.width / imgWidthPx * 0.98;//自适应时设置图像显示比例98%,防止出现滚动条         }     } else {         scaleFloat = parseFloat(showScale);     }     imgWidth = numToFixed(imgWidth * scaleFloat, 0) + "in";     imgHeight = numToFixed(imgHeight * scaleFloat, 0) + "in";      if (imgWidth == divImgElemet.style.width && imgHeight == divImgElemet.style.height) {         //图像大小不变,如果是打印则直接执行打印         if (SetImageSizeisPrint == true) {             PrintCurrentPage(false);         }     } else {         divImgElemet.style.width = imgWidth;         divImgElemet.style.height = imgHeight;          //设置图像上字体大小         let dfontSieze = 11;         if (!isEmpty(PrintConfigObj.FontSize)) {             dfontSieze = parseInt(PrintConfigObj.FontSize);         }         const setFontSize = numToFixed(dfontSieze * scaleFloat, 2) + "px";//标注字体为11px,乘以缩放比例         divImgElemet.style.fontSize = setFontSize;          //获取元素像素大小         document.querySelector("#spShowImgSizePx").innerHTML = divImgElemet.scrollWidth + "×" + divImgElemet.scrollHeight;     } }

View Code

 

 

胶片打印布局效果如图

影像云胶片:Dicom纯js的三维重建影像阅片器

 

 技术交流沟通联系QQ:343798739;469116292

 

发表评论

评论已关闭。

相关文章