基础概念
- Eneabled Element
- Enable Element 是一个展示交互式医学图像的HTMLElement(通常是一个div元素)
- Image Ids
- Image Ids 是一个表示医学图像的url
- 使用Image Id 的url方案来确定调用那个Image Loader 插件来实际加载图像, 该策略允许Cornerstone同时显示使用不同协议从不同服务器多个图像
- Cornerstone 没有具体指定URL的内容,URL的内容是自定义的方便定位图像
- Image Ids 的格式
* eg: dicomweb://server/wado/{uid}/{uid}/{uid}
3. Image Loaders
* Image Loaders 是一个js函数,主要功能是为image 获取 image id,并将该图像的image loader对象返回给Cornerstone, image loader 对象包含一个promise, 解析后是一个image对象
* Image Loader 工作流:
* 两种类型的Image Loaders:
* WADO: 支持DICOM part 10 images、WADO-URI 和 WADO-RS、多帧DICOM实例、 从file对象读取DICOM
* Web: PNG, JPEG
- Viewports
- 展示图像的视口
- 可以通过getViewport()方法获取视口,通过setViewport设置视口
- Images
- image loaders 返回的image对象
- Pixel Coordinate System
- 像素坐标系:用于指定图像中像素点的坐标位置,精确到单个像素精度
- pageToPixel(): 可以用于将从浏览器事件中获取到坐标转换成像素坐标系中的坐标
- setToPixelCoordinateSystem(): 可以用于将canvas上下文设置为像素坐标,这在处理CornerstoneImageRendered事件以在图像顶部绘制几何体时非常有用。
- 像素坐标系:用于指定图像中像素点的坐标位置,精确到单个像素精度
- Rendering Loop
- 视口变换(平移,伸缩)通过基于requestAnimationFrame的Rendering Loop 来更新Cornerstone 元素
- Libraries (模块化库)
- Cornerstone是一个开源项目,目标是提供一个完整的基于web的医学成像平台。它提供了模块化库,可以一起使用,也可以单独使用。
- 除了Cornerston.js核心库之外,Cornerstone团队还维护了其他的几个库,为开发复杂的图像系统提供了完整的生态系统
- Cornerstone Core: 提供渲染、加载、缓存和视口转换的库
- Cornerstone Tool:对构建工具的可扩展支持,对鼠标、键盘和触摸设备的支持
- Cornerstone WOAD Image Loader: DICOM part 10 文件加载插件
- Cornerstone Web Image Loader: 用于Web图像文件(PNG,JPEG)的图像加载插件
- Cornerstone Math: 支持工具开发的数学使用函数和类
- dicomParser: 强大的DICOM part 10 文件解析器
- rendering pipelines
- Cornerstone 会根据图像(灰度、颜色、标签图、视口伪彩色)类型从多个图像渲染管道中进行选择
- 渲染路径:
- renderGaryscaleImage: 灰度图像的渲染管道,包括模态和VOILUT转换
- renderPseudoColorImage: 在设置colormap属性时使用,这将在VOI LUT 和 Modality LUT 转换之后将伪彩色LUT 转换应用于像素数据
- renderColorImage: 彩色图像的默认渲染管道你的,除非Image的rgba属性设置为true,否则所有的像素的Alpha 都是不透明的。
- renderWebImage: 用于浏览器加载图像(JPG,JPEG)的自定义渲染管道。如果没有使用VOI LUT 转换,则可以直接通过Image getImage 函数绘制画布
- renderLabelMapImage: 标签的渲染管道,伪彩色LUT变换直接应用于存储的像素数据,不应用Modality 或者 VOI LUT 转换
- Metadata Providers
- Metadata Providers 是一个js函数,具有访问Cornerstone中图像相关的元数据的功能, 用户可以自定义这个函数,以便为每个特定的图像返他们希望的任何元数据。
- 医学图像通常会有很多非像素的信息,例如图像的像素间距,患者ID或扫描采集日期。对于某些文件类型DICOM, 非像素的图像行医一般存储在头文件中, 可以被读取、解析并且在应用程序中传递。对于其他格式(JPG,JPEG),需要独立于实际像素数据提供废像素信息。
- 即便是DICOM格式的文件,应用程序开发人员通常也可以独立于从服务器到客户端的像素数据传输来提供元数据,因为这可以显著提高性能
- 为了处理这样的场景,Cornerstone为元数据提供者定义和使用提供哦那个了基础设施。Metadata Providers 只是一个简单的函数,接受一个 Image Id 和 指定的元数据,返回元数据本身
进阶
- Image cache
- 图像缓存,Cornerstone将图像存储在图像图像缓存中,以便追踪内存的使用情况
- 当解析image loader 返回的Promise对象时, Cornerstone会将解析生成的image 存储在图像缓存模块的对象中。图像缓存对象被设置为访问频率低的对象
- 开发者可以通过调用API 设置图像缓存对象
- setMaximumSizeBytes: 设置缓存的大小, 默认是1GB
- purgeCache: 手动清除所有的图像缓存
- getCacheInfo: 检索缓存摘要
- changeImagedCacheSize: 更改特定图像的记录缓存大小
- Enabled Element Layers
- 将图层添加到一有的医学图像中,Cornerstone 会将添加的标签与图像融合
- 使用 Enabled Element Layers API 为开发这提供了构建符合图像的方法
- Cornerstone中图像的基本能力:
- 一个图像可以拥有多个图层
- 每个图层都类似于一个图像, 每个图层都有自己的Viewport、off-screen rendering canvas…
- 每次只能激活一个图层
- 图层具有可见性和不同命读属性,并由图层ID唯一引用
- 当一个图层处于激活状态时:
- 图层的图像在enabledElement.image中可用
- 图层的视口位于enabledElement.viewport
- 图层处于激活状态时可以使用setViewport, getViewprot等方法
- addLayer:添加图层
- getLayer: 通过图层ID获取图层
- removeLayer: 更具图层ID 移除图层
- getActiveLayer: 检索当前活动的图层
- getLayers: 检索当前所有图层的ID
- getVisibleLayers: 检索所有可见图层的数组
- Modality LUT 和 VOI LUT
- Cornerstone 通过Modality LUT和 VOI LUT 查找LookUp Tables中存储的像素值到呈现像素值之间的转换
- Cornerstone 线性和非线形的像素值转(VOI LOT)
- Color Lookup Tables
- 开发者可自定自己的颜色列表用于显示带有伪彩色的灰度图像(只有一个采样颜色的图像)
- WebGL Rendering Pipeline
- Cornerstone 支持可选的WebGL渲染管道以提高性能
- Retrieving Pixel Data
- Cornerstone 支持从图像中存储和转换的像素
- getPixel
- getStoredPixel
- Cornerstone 支持从图像中存储和转换的像素
- Legacy Browser Support
- 通过为一些现代浏览器功能合并polyfills 让Cornerstone 可以支持传统浏览器
- DICOM医学图像显示转换过程需要经过Modality LUT、VOI LUT、Presentation LUT三个转换过程,最终输出的P Values才是可以直接显示的图像数据
API
名词解释
-
metadata
: metadata 是数据集的描述与说明; metadate是应用系统的辅助信息,能提高数据的利用价值 -
Volume
: 在医学影像中Volume是容积扫描得出的容积数据,在计算机视觉中称为体数据 -
Lookup Table
: 是一张像素灰度值的映射表 -
VOI(Volume of Interest)
: VOl(Value Of Interest)LUT转换(感兴趣区转换,由于医学图像数据动态范围大(像素深度通常不低于4096个灰度级),因此一般显示器很难提供如此高的动态范围一次显示整幅图像的全部信息细节,在图像的处理中一般都是先选择一个操作者感兴趣的区域,然后将该区域的图像信息映射到显示器能显示的整个数据范围,这样就增加了该区域的图像信息的对比度。这个过程DICOM标准中称之为感兴趣区简称VOI)LUT(Look Up Table)转换。临床医生感兴趣的窗宽、窗位调节功能就是VOI LUT转换的一种算法实现。VOI LUT转换可以使用设置窗宽、窗位的线性转换算法和通过查找查找表(LUT)转换的非线性算法两种算法中的一种,且只能使用其中的一种,具体使用哪种算法在DICOM文件中有专门的标记来设置。 -
Modality LUT Value
: Modality LUT转换(数据规范化转换通常不同生产厂商的设备很难保证在一种设备上生成的图像和其他生产厂商的同类型设备上生成的图像在度量上是一致的,为此就需要将不同设备厂家产生的图像的原始数据转换到一个标准的度量空间,转换就是完成这个功能的。医疗设备的生产厂商都会在自己的图像中采用DICOM标准规定的格式说明如何将自己的数据转换为标准图像数据,中规定可以使用通过查找表(Look Up Table,简称LUn查找和通过斜率/截距(RescaIe/转换两种方法中的一种。 -
Presentation LUT
: Presentation LUT转换是对图像像素要做的最后一个变换,它用于特定图像的显示。这一模块转换完成后的输出值为P—Values,P-Values是独立于任何显示设备的特性曲线,与人的视觉反应近似相关的值,可直接作为已经校正的软拷贝设备或硬拷贝的输入。转换也有两种转换方法,一种是通过Presentation LUT进行转换的非线性转换方法,一种是通过Presentation Shape的转换方法,这两种转换方法只能使用一种。Presentation LUT转换的过程基本同上面介绍的两种LUT算法。
cornerstone 对象
1. VOILUTFunction: Volume of Interest(VOI) Lookup Table Function, 存储像素值转换函数
* 接收的参数是modalityLUTValue(演示像素值)
* 返回值是一个转换的存储像素值
2. Viewport: cornerstone 视口对象
Viewport 对象类型:
interface ViewportType {
scale: number; // 控制医学图像的缩放
translaton: vec2; 用于描述像素在坐标中位置的对象,包含了x, y属性,初始化是 enabled element 的中心, x, y的值是0
voi: VOI; // 一个具有 windowWidth 和 windowCenter 属性的对象
invert: boolen; // 图像是否反转
pixelReplication: boolean; // 如果在图像放大时使用 soomth/interpolation 则为true, 如果使用图像复制则为false
hfilp: boolean; // 如果图像水平翻转则为true,默认为ifalse
vfilp: boolean; // 如果图像垂直翻转则为true,默认为false
rotation: number; // 图像的旋转角度(90度增量),默认为0
modalityLUT: LUT; // 应用演示像素值
voiLUT: LUT; // 应用存储像素值
colormap: string | Colormap; // 可选的颜色ID或颜色图像对像,将在渲染期间将图像转化为伪彩色
labelmap: boolean; // 是否将此图像渲染为标签图(即跳过 modality 和 VOI LUT 管道,并使用颜色查找表)
}
3. EnabledElementLayer: cornerstone 中 Enabled Element 图层对象
EnabledElementLayer 对象类型
interface EnabledElementLayerTyppe {
element: HTMLElement; // cornerstone 图像容器 DOM 元素
imgae: Image; // 当前显示在视口中的图像
viewport: Viewport; // 当前视口
canvas: HTMLCanvasElement; // 当前cornerstone 容器元素的 canvas
options: object; // 绘制图层的参数
invalid: boolean; // 当前Enabled Element下的图像像素数据是否已被更改,是否需要重新绘制
needsRedraw: boolean; // 用于在不重新检索像素数据的情况下出发canvas重绘的标志,
}
4. ImageLoadObject: 图像加载对像
ImageLoadObject 对象类型
promise: Promise; // 跟踪图像加载过程中的promise对象
cancelFn: function | undefined; // 取消图像加载请求的函数
5. Image: cornerstone 中的图像对象
Image 对象类型
ImageId: string; // 与图像对象关联的ImageId(医学图像的url)
minPixelValue: number; // 图像中最小存储像素值
maxPixelValue: number; // 图像中最大存储像素值
slope: number; // 将存储像素值转换为模态像素值的重新缩放斜率,如果为指定则为1
intercept: number; // 将存储像素值转换为模态值或0(未指定)的重新缩放截距
windowCenter: number; // 应用于图像中的默认窗位
windowWidth: number; // 应用于图像中的默认窗宽
getPixelData: number; // 一个返回底层像素数据的函数, 返回的值是用于灰度的整数数组和用于颜色的RGBA数组
getImageData: function; // 返回图像的canvas imageData 对象,仅适用于彩色图像
getCanvas: function; // 返回加载了图像的canvas元素,仅使用于彩色图像
getImage: function; // 返回包含图像信息的 JS Image 对象, 这是可选的,通常用于标准Web JPEG 和 PNG 格式编码的图像
rows: number; // 图像中的行数
columns: number; // 图像中的列数
height:number; // 图像的高度
width: number; // 图像的宽度
color: boolean; // 如果像素数据为RGB,则为true, 如果为灰度,则为false
lut: object; // 像素灰度映射表
rgba: boolean; // 图像的像素数据是否存储在rgba中
columnPixelSpacing: number; // 像素(像素宽度)的水平距离,以毫米为单位,未定义时是undefined
rowPixelSpcing: number; // 像素(像素高度)的垂直距离,以毫米为单位,为定义时是undefined
invert: boolean; // 如果图像被翻转显示则为true,否则为false
sizeInBytes: number; // 用于存储此图像像素的字节数
falseColor: boolean; // 图像是否经过假色映射
origPixelData: Array; // 图像经过伪彩色映射后的原始像素数据
status: ImageStatus; // 上次重绘图像的统计信息
cachedLUT: object; // 图像中缓存的像素灰度值映射表
colormap: string | Colormap; // 可选的颜色ID或颜色图像对像,将在渲染期间将图像转化为伪彩色
labelmap: boolean; // 是否将此图像渲染为标签图(即跳过 modality 和 VOI LUT 管道,并使用颜色查找表)
6. ImageStats: 图像统计对象
ImageStats 对象类型
lastGetPixelDataTime: number; // 检索绘制图像时所需的存储像素所花费的时间(以毫秒为单位)
lastStoredPixelDataToCanvasImageDataTime: number; // 从存储的像素数组映射到canvas像素数组所花费的时间(以毫秒为单位)
lastPutImageDataTime: number; // 将图像像素数据转化为canvas像素数据所花费的时间(以毫秒为单位)
lastRenderTime: number; // 整个渲染函数运行所用的时间(以毫秒为单位)
lastLutGenerateTime: number; // 生成图像灰度值映射表所花费的时间
7. LUT: 灰度值映射表
LUT 对象类型
firstValueMapped: number;
numBitesPerEntry: number;
lut: Array;
8. VOI: 存储像素值对象
VOI 对象类型
windowCenter: number; // 窗位
windowWidth: number; // 窗宽
9. vec2: 一个二维向量
vec2 对象类型
x: number; // x坐标
y: number; // y坐标
10. EnabledElement: cornerstone 中 Enabled Element 对象
EnabledElement 对象类型
element: HTMLElement; // cornerstone 展示医学图像的DOM元素
image: Image; // EnabledElement 中展示的图片对象
viewport: Viewport; // EnabledElement 视口
canvas: HTMLCanvasElement; // EnabledElement 的canvas元素
invalid: boolean; // EnabledElement 下的图像像素数据是否已经更改,是否需要重新绘制
needsRedraw: boolean; // 用于在不重新检索像素数据的情况下触发canvas重绘的标志
layers: Array<EnabledElementLayer>; // 添加到EnabledElement 中的图层
syncViewports: boolean; // 是否为每个EnabledElement的图层同步视口参数
lastSyncViewportsState: boolean; // 同步视口布尔值的先前状态
cornerstone 对象的实例方法
EnabledElements
1. getEnabledElement(element): 获取 cornerstone enabled element
对象
* 接受的参数是 `element`: 是一个`HTMLElement`, cornerstone 展示交互式医学图像的HTML元素
* 返回值是 EnabledElement 对象
2. addEnabledElement(enabledElement): 将 cornerstone enabled element
对像添加到enabledElements
的中央存储中
* 接收的参数`enabledElement`: 是一个`enabled element`对象
* 无返回值
3. getEnabledElementsByImageId(imageId): 通过imageId(表示医学图像的url)获取对应的enabled element
度对象
* `imageId`: 表示医学影像的 url;
* 返回值类型是 `Array<EnabledElement>`
4. getEnabledElement: 获取所有的应用中的enabled element
对象
* 返回类型是`Array<EnabledElement>`
ImageLoader
处理ImageLoaders、加载图像和缓存图像的模块
1.loadeImageFromImageLoader(imageId: string, options?: object): 使用已经注册的cornerstone 图像加载插件加载图像,使用的图像加载插件将由于imageId匹配的图像加载器的协议(‘dicomweb’, ‘wadouri’, ‘http’)来确定
* `imageId`: 表示医学影像的url
* `options`: 图像加载插件的选项
* 返回一个可用于在图像加载或加载失败后产生的对象`ImageLoadObject`
2. loadImage(image: string, options?: object): 给定一个imageId和一个可选的图像加载插件配置选项,返回一个promise对像,当图像加载失败或者加载时发生错误时返回的promise将会被解析。加载的图像不会被缓存。
* `imageId`: 表示医学影像的Url
* `options`: 图像加载插件的选项
* 返回一个可用于在图像加载或加载失败后产生的对象`ImageLoadObject`
3. loadAndCacheImage(imageId: ‘string’, options?: object): 给定一个imageId和一个可选的图像加载插件配置选项,返回一个promise对像,当图像加载失败或者加载时发生错误时返回的promise将会被解析。加载的图像会被缓存下来
* `imageId`: 表示医学影像的Url
* `options`: 图像加载插件的选项
* 返回值时`imageLoadObject`图像加载器对象
4. registerImageLoader(scheme: string, imageLoader: Function):传入指定的图像加载协议为cornerstone注册一个imageLoader插件
* `scheme`: 加载图像的协议('dicomweb', 'wadouri', 'http')
* `imageLoader`: cornerstone 图像加载器回调函数
5. registerUnknowImageLoader(imageLoader: Function): 注册一个unknowImageLoader并返回前一个插件
* `imageLoader`: cornerstone 图像加载器回调函数
* 返回值是上一个Image Loader 函数或者undefined
ImageCache
处理图像缓存的模块
MetaData
使用metadata 描述人体空间数据:
- 用于描述信息资源的高度结构化数据
- 管理和组织信息,并且可以挖掘信息资源,通过metadata可以在internet或internet上准确的识别、定位和访问信息
- 帮助准确的查询所需的信息
- 从不同的资料或组织获取metaData时还可以通过对相同的metadata元素进行比较和对比,获取最新的资料
1. addProvider(provider: Function, priority: number): 添加具有指定优先级的Metadata Providers(具有访问图像相关元数据的js函数)
provider
: 具有方法图像相关元数据的js函数priority
: 优先级,默认值时0, 大于0的优先级高于小于0的优先级
2. removeProvider(provider: Function): 移除metadata provider 函数
provider
: 具有方法图像相关元数据的js函数
3.getMetaData(type: string, imageId: string): 从已经注册的metadata providers 函数中获取metadata, 会根据优先级从高到低依次调用,知道响应为止
type
: 从metadata store 中请求的元数据类型imageId
: 表示医学影像的Url
ViewportSettings
getViewport(element): 获取特定元素的视口
element
: HTMLElement , 指定的cornerstone DOM 元素- 返回值是 目标元素的Viewport 对象
setViewport(element, viewport): 设置/更新给定 enabled element 的视口
element
: HTMLElement, 指定的 enabled elementviewport
?: Viewport 包含视口属性的对象
PixelCoordinateSystem
像素坐标系
canvasToPixel(element, pt)
: 将canvas坐标系中的点转化为像素坐标系,这可用于当在canvas空间中进行修改之后充值工具的图像坐标
* `element`: 在输入点上的cornerstone元素
* `pt`: {x: number, y: number} 在canvas中的输入点
* 返回值是{x: number, y: number} , 转换之后在像素坐标系中的坐标
pixelToCanvas(element, pt)
: 将像素坐标系中的点转化为canvas坐标系中的坐标,这课用于使用canvas上下文进行渲染时,不会产生来自缩放和非方形像素的副作用
* `element`: HTMLElement, cornerstone enabled element
* `pt`: {x: number, y: number}, 像素坐标系中的坐标
* 返回值{x: number, y: number} canvas 坐标系中的坐标
EnabledELementLayers
triggerEventForLayer(eventName, enabledElement, layerId): 用于在具有特定layerId的cornerstone元素上触发事件的辅助函数
* `eventName`: 事件名称
* `enabledElement`: enabled element
* `layerId`: 图层id
recaleImage(baseLayer, targetLayer): 根据每个图像的相对大小及像素尺寸,将目标层重新缩放到基础图层,此函数,将目标图层的视口参数更新为最新比例
* `baseLayer`: 基础图层
* `targetLayer`: 要重新缩放的目标图层
addLayer(element, image, options): 向 element元素中添加图层
* `element`: HTMLElement 添加图层的元素
* `image`: Image,要添加为新图层的cornerstone图像对象
* `options`: 图层选项
removeLayer(element, layerId): 根据图层id将指定的图层从cornerstoen元素中移除
* `element`: HTMLElement, enabled element
* `layerId`: 图层id
getLayer(element, layerId): 根据layerId从cornerstone 元素中获取图层
* `element`: HTMLElement, enabled element
* `layerId`: 图层id
getLayers(element): 获取element 中所有的图层
* `element`: HTMlElement