超简单,如何使用cornerstone画出dicom

1.前置知识

虽然今天国内医学影像行业较前几年已经发达很多,但是前端方面,关于cornerstone的资料还是比较少。再加上cornerstone本身文档不是特别完善,所以新人上手比较困难。下面讲简单记录一些我关于这个库的探索及理解。下面的表格主要列一下cornerstone主要仓库的作用

仓库名称主要作用
cornerstoneWADOImageLoader加载dicom图,供后期cornerstone展示
dicomParser解析dicom tag
cornerstone主要用于图像展示
cornerstoneToolscornerstone常用工具封装

2.如何画出dicom

下述代码使用react框架,全部使用cornerstone最新版本,主要展示了dicom加载,显示,工具使用及tag解析。仅贴出主要部分,完整代码请参考文章末尾github链接。(由于快速实现需要,请忽略TS部分)

a.初始化cornerstone Externals及cornerstoneWADOImageLoader方法

// cornerstoneWADOImageLoader config配置
const config = {
  maxWebWorkers: navigator.hardwareConcurrency || 1,
  startWebWorkersOnDemand: true,
  taskConfiguration: {
    decodeTask: {
      initializeCodecsOnStartup: false,
      usePDFJS: false,
      strict: false,
    },
  },
};

// 初始化cornerstone Externals及cornerstoneWADOImageLoader方法
function _initCornerstone() {
  // Externals
  cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
  cornerstoneWADOImageLoader.external.dicomParser = dicomParser;
  cornerstoneTools.external.cornerstoneMath = cornerstoneMath;
  cornerstoneTools.external.cornerstone = cornerstone;
  cornerstoneTools.external.Hammer = Hammer;

  // Image Loader
  cornerstoneWADOImageLoader.webWorkerManager.initialize(config);
}

b.解析tag方法

const parserDicom = (file: any) => {
  const reader = new FileReader();
  reader.onload = function (file) {
    var arrayBuffer = reader.result;
    if (!arrayBuffer || typeof arrayBuffer === "string") return;
    const byteArray = new Uint8Array(arrayBuffer);

    let dataSet;

    dataSet = dicomParser.parseDicom(byteArray);
    // access a string element
    const studyInstanceUid = dataSet.string("x0020000d");
    // get the pixel data element (contains the offset and length of the data)
    const pixelDataElement = dataSet.elements.x7fe00010;

    console.log("dicomParser", studyInstanceUid, pixelDataElement);
  };
  reader.readAsArrayBuffer(file);
};

c.主函数

function App() {
  useEffect(() => {
    // 初始化cornerstone相关配置
    _initCornerstone();
  }, []);
  
  // 处理上传文件
  const handleFileSelect = async (e: ChangeEvent<HTMLInputElement>) => {
    // 获取展示宿主元素
    const element = document.getElementById("dicomImage");
    
    // 初始化工具,此方法必须放在cornerstone.enable(element)前,否则工具可能会无法使用
    cornerstoneTools.init({
      showSVGCursors: true,
    });
    
    // 激活element
    cornerstone.enable(element);
    
    // 获取上传文件
    const files = e.target.files || [];
    const file = files[0];
    
    // 解析相关标签示例 
    parserDicom(file);
    // cornerstoneWADOImageLoader解析文件,获取imageId
    const imageId = cornerstoneWADOImageLoader.wadouri.fileManager.add(file);
   
    // 展示dicom
    cornerstone.loadImage(imageId).then(function (image: any) {
      cornerstone.displayImage(element, image);
    });
    
    // 长度工具使用示例
    const toolName = "Length";
    const apiTool = cornerstoneTools[`${toolName}Tool`];
    cornerstoneTools.addTool(apiTool);
    // toolName不能使用cornerstoneTools.LengthTool.name, 他们不一样
    cornerstoneTools.setToolActive(toolName, { mouseButtonMask: 1 });
  };

  return (
    <div className="App">
      <div
        className="viewport"
        id={"dicomImage"}
        style={{ width: "512px", height: "512px", background: "gray" }}
      ></div>
      <input type={"file"} onChange={handleFileSelect}></input>
    </div>
  );
}

export default App;

附:

链接:github 对于commit:1aa626d
在线预览链接

欢迎同行业朋友交流

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

A-wliang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值