写点什么

cornerstone 基础概念篇(一)

用户头像
Lazy
关注
发布于: 2021 年 05 月 14 日
cornerstone 基础概念篇(一)

本文根据官网 https://docs.cornerstonejs.org/ 翻译,加上了自己的一些理解


cornerstone 是一个基于 web 的较全面的影像文件处理组件,使用的是 MIT License。 cornerstone 拥有多个组件,如: cornerstone-core cornerstoneTools cornerstone-nifti-image-loader 等等,要想灵活的使用 cornerstone,必须先了解 cornerstone-core 这个组件,它是一个比较轻量的 js 库,提供了影像处理的核心类和一些框架代码。

安装

  • 方式 1:引入


<script src="/path/to/cornerstone.js"></script>
复制代码


  • 方式 2:npm 安装


npm install cornerstone-core --save
复制代码


  • 方式 3: 编译


git clone https://github.com/cornerstonejs/cornerstone.git node_modules/cornerstonecd node_modules/cornerstonenpm installnpm run build
复制代码

概念解释

要想弄清 cornerstone, 必须先弄清楚它定义一些概念,这样才能事半功倍。


  • Enabled Elements

  • Image Ids

  • Image Loaders

  • Viewport

  • Images

  • Pixel Coordinate System

  • Rendering Loop

  • Libraries

  • Rendering Pipeline

  • Metadata Providers

Enabled Elements

可用页面元素,典型就是使用 div, 在这个页面元素里展示可交互的影像文件。 具体步骤如下:


  1. 引入 cornerstone-core 和 image-loader。

  2. 建一个 div, 并给个 ID

  3. 通过 CSS 给这个 div 设置好宽高、位置等

  4. 使用 cornerstone.enable(element) , 这个 API 会做一些展示前的准备工作

  5. 使用 cornerstone.loadImage(imageId),这个 API 会加载影像文件(imageId 解释见下文)

  6. 在 loadImage 后使用 cornerstone.displayImage() 展示影像


以下示例代码帮助理解


<body>...  <div id='dicomImage'></div>...<body><script>import cornerstone from "cornerstone-core";import * as imageLoader from "cornerstone-nifti-image-loader";
let element = document.getElementById('dicomImage');let imageId = 'example://1';cornerstone.enable(element);cornerstone.loadImage(imageId).then(function(image) { cornerstone.displayImage(element, image); ...})</script>
复制代码


例子中<div id='dicomImage'></div> 就是一个 Enabled Element

Image Ids

Image Id 是一个标记图像的自定义 url 地址,具体格式如下:



cornerstone-core 只定义了 Image Id 的结构,具体的内容是由各自的 image loader 实现的。


  • scheme name: 决定使用什么 image loader 来加载图像, 在注册 image loader 时指定;比如 niftiImageLoader 首先调用 registerImageLoader API 进行注册:


cornerstone.registerImageLoader('nifti', (imageId) => this.cornerstoneLoader(imageId, this));
复制代码


这样,当调用 cornerstone.loadImage(imageId)加载影像时,先会根据 imageId 的 scheme name 选择 image loader, 如果是 nifti:xxx, 则就会使用 niftiImageLoader 。


  • hierarchical: 英文翻译过来是层次结构的意思,就是路径的层次,类比 http url, 如:aaa/bbb/ccc 这样的多层路径, 当然这里其实是没有什么限制的,具体什么值完全取决于 image loader 自己的实现。

  • query、#fragment : 类比 http url 中 参数和锚点,具体什么值完全取决于 image loader 自己的实现。

Image Loaders

Image Loader 其实就是一个定义好的函数 , 形式如下:


function loadImage(imageId) {  ...  const promise = new Promise((resolve, reject) => {});  return {promise};}
复制代码


回顾 Enabled Elements 中的示例, 我们的代码调用加载影像文件时是这样写的


...let element = document.getElementById('dicomImage');let imageId = 'example://1';cornerstone.enable(element);cornerstone.loadImage(imageId).then(function(image) {  cornerstone.displayImage(element, image);  ...})</script>
复制代码


当我们的代码调用 cornerstone.loadImage(imageId) 方法时,cornerstone-core 首先会根据 imageId 中的 scheme (例子中就是example)找到对应的 image loader 函数,然后执行这个函数返回 promise 对象,这个 promise 对象会携带影像文件的像素数据。通过这种方式,cornerstone 就可以灵活的扩展不同方式获取影像数据方法,如: wado-uri、wado-rs、qido-rs、stow-rs、nifiti 等。下图是官网给的流程图,参考理解:



Viewport

Viewport 直译是视口,可以理解为图像的显示区域,窗口。 这里的 Viewport 是指窗口对象,包含了一些设置参数。



以下是对 LUT 知识扩展,不感兴趣可直接略过。


DICOM 医学图像显示转换过程需要经过 Modality LUT、VOI LUT、Presentation LUT 三个转换过程,最终输出的 P Values 才是可以直接显示的图像数据


Modality LUT 转换(数据规范化转换通常不同生产厂商的设备很难保证在一种设备上生成的图像和其他生产厂商的同类型设备上生成的图像在度量上是一致的,为此就需要将不同设备厂家产生的图像的原始数据转换到一个标准的度量空间,转换就是完成这个功能的。医疗设备的生产厂商都会在自己的图像中采用 DICOM 标准规定的格式说明如何将自己的数据转换为标准图像数据,中规定可以使用通过查找表(Look Up Table,简称 LUn 查找和通过斜率/截距(RescaIe/转换两种方法中的一种。


VOl(Value Of Interest)LUT 转换(感兴趣区转换,由于医学图像数据动态范围大(像素深度通常不低于 4096 个灰度级),因此一般显示器很难提供如此高的动态范围一次显示整幅图像的全部信息细节,在图像的处理中一般都是先选择一个操作者感兴趣的区域,然后将该区域的图像信息映射到显示器能显示的整个数据范围,这样就增加了该区域的图像信息的对比度。这个过程 DICOM 标准中称之为感兴趣区简称 VOI)LUT(Look Up Table)转换。临床医生感兴趣的窗宽、窗位调节功能就是 VOI LUT 转换的一种算法实现。VOI LUT 转换可以使用设置窗宽、窗位的线性转换算法和通过查找查找表(LUT)转换的非线性算法两种算法中的一种,且只能使用其中的一种,具体使用哪种算法在 DICOM 文件中有专门的标记来设置。


Presentation LUT 转换是对图像像素要做的最后一个变换,它用于特定图像的显示。这一模块转换完成后的输出值为 P—Values,P-Values 是独立于任何显示设备的特性曲线,与人的视觉反应近似相关的值,可直接作为已经校正的软拷贝设备或硬拷贝的输入。转换也有两种转换方法,一种是通过 Presentation LUT 进行转换的非线性转换方法,一种是通过 Presentation Shape 的转换方法,这两种转换方法只能使用一种。Presentation LUT 转换的过程基本同上面介绍的两种 LUT 算法。


以上摘抄自  DICOM医学图像显示算法改进与实现——LUT


下面简单示例了设置 viewport 后的效果


 const viewport = cornerstone.getDefaultViewportForImage(element, image); viewport.scale = 0.5;  viewport.translation = {x:100,y:0}; // 左移100 viewport.invert = true; // 灰度倒置 // cornerstone.setViewport(element,viewport) cornerstone.displayImage(element, image, viewport); // 打开resize后,会根据图片自动调整图像,上面的scale、translation 会失效 // cornerstone.resize(element, true);  
复制代码




可以看出图片的灰度、大小、位置都发生了改变。


本篇介绍了 Enabled Elements、Image Ids、Image Loaders、Viewport,剩下的概念下篇继续。

发布于: 2021 年 05 月 14 日阅读数: 22
用户头像

Lazy

关注

某知名软件上市公司基层软件开发。 2019.10.17 加入

助力于脑科学软件工程,为中国脑计划舔砖加瓦。 脑科学软件工程包含多种模态数据的处理分析(如脑影像、基因、行为评测等)、脑相关科研平台、研究成果转化。其应用可覆盖到医疗、教育、生活娱乐等各个领域。

评论

发布
暂无评论
cornerstone 基础概念篇(一)