DcmViewer医疗影像系统网站:dcmviewer.com
DcmViewer是一个纯客户端的即时医疗影像系统,支持标准的DICOM影像文件,用来提供看图阅片等功能,同时支持一些配套图形操作工具,使用过程中不会保存任何影像信息到服务器端。在进入系统后,系统将自动从服务器上下载一个样例数据,因为一套完整的CT数据大约有几十兆大小,下载完整的数据,需要一定的时间,为了提高样例的加载效率,DcmViewer首先下载其中的10张样例数据,显示为2D图像。
如果需要浏览样例的3D图像,点击工具箱里的“三维”按钮,等样例数据全部图片加载完成后即可查看。
工具箱里的“三维”按钮:
3D图像界面:
同时,DcmViewer支持移动端,当屏幕不足够大时,只显示最基本的视图布局切换和影像图片导航功能(样例数据将不支持冠状面和矢状面)。
小屏幕移动端:
在实际使用DcmViewer时,比如打开一个真实的影像文件时,因同是纯客户端响应,加载速度将是秒级的。
点击“文件”,然后选择“打开”,选择需要浏览的影像文件。
DcmViewer支持以下几种方式打开影像文件:
点击工具箱旁边的收缩展开图标可以隐藏和展开工具箱。
DcmViewer提供三个面的视图 (3D视图)切换,分别支持:
冠状面 (coronal view):也就是额状面。
矢状面(sagittal view):将人体纵切为左、右两部分。
横切面(axial view):即水平面。
如,假设有一个大小为512*512的切片共10张,在内存中的存储情况如下图。
那么横断面、冠状面和矢状面的数据来源为:
横断面: x,y方向不动,沿着z方向移动, 一个横断面对应的数据来源应为一个切片的数据, 即一个切片所有(x,y)对应点的集合。
冠状面:x,z方向不动,沿着y方向移动,假设一个冠状面图像素坐标(256,256),即切片的中心位置开始,那么这一个冠状面的数据来源为每一个切片的y=256时,每个切片内所有x对应点的集合,即上图紫色数据集合。
矢状面:y,z方向不动,沿着x方向移动,假设一个矢状面图像素坐标(256,256),即切片的中心位置开始,那么这一个矢状面的数据来源为每一个切片的x=256时,每个切片内所有y对应点的集合,即上图绿色数据集合。
从内存(数据来源)中查找横断面、冠状面和矢状面所需数据的第一个数据的关键算法:
let offset = 0;
for (let i = 0; i < 3; ++i) { // 3 表示3个维度 - x,y,z
// index为当前视图位置,后面讲到。这里只留下方向轴上的值,如:
// 横断面: (0,0,67) 表示第67个切片
// 冠状面:(0,256,0) 表示每一个切片的y=256时,每个切片内所有x对应点的集合形成的视图
// 矢状面:(256,0,0) 表示每一个切片的x=256时,每个切片内所有y对应点的集合形成的视图
offset += index.get(i) * this.getDimSize(i, start);
}
getDimSize(dimension, start):
let size = 1;
for (let i = start; i < dimension; ++i) {
// sizeArray为整套图像的大小维度,
// 如大小为512*512的切片共10张表示为(512,512,10)
size *= sizeArray.get(i);
}
这项功能用来指示比例图像是否平滑,它本身就是Canvas API的一个属性, 当图片放大时,默认大小改变的算法可能造成像素模糊,通过改变此项属性,达到图像平滑的目的。具体参考: CanvasRenderingContext2D 属性
CT窗口技术是CT检查中用以观察人体不同密度组织的一种显示技术,包括窗宽(window width)和窗位(window level)。
窗宽(window width): 因为人眼可以分辨16 个灰阶, 而CT能识别人体内2000个不同灰阶的密度差别,因此,要对特定的组织的观察需要分段进行,利用窗宽窗位来界定感兴趣的CT值范围,再将其分为16个灰阶,借此对目标组织进行观察。因此窗宽指CT图像所显示的CT值范围,在该CT值范围内的组织,按其密度的高低从白到黑分为16 个灰阶显示。例如,窗宽为100 HU,则人眼可分辨的CT值为100 / 16 =6.25 HU,即两种组织CT值相差在6.25 HU以上者即可为人眼所识别。因此,窗宽的宽窄直接影响图像的清晰度与对比度(HU - Hounsfield unites 是CT值的单位,用于表示X线穿过组织后被吸收的衰减值)。
使用窄的窗宽,则显示的CT 值范围小,每一灰阶代表的CT 值幅度小,对比度强,适于观察密度接近的组织结构(如脑组织)。
使用宽的窗宽,则显示的CT值范围大,每一灰阶代表的CT 值幅度大,则图像对比度差,但密度均匀,适于观察密度差别大的结构(如骨组织)。
窗位(window level、窗中心、窗口级别):指窗宽范围内均值或中心值。例如将窗宽设为100HU,窗位选在0HU;则以窗位为中心(0HU),向上包含+50HU,向下包含-50HU,凡是在-50HU到+50HU共100HU范围内的组织均可显示,而大于+50HU的组织显示为白色;小于-50HU的组织显示为黑色,在CT图像中均无法显示其差异;人眼可识别-50HU到+50HU范围内的CT 值,每一个灰阶的CT值范围是100 / 16=6.25 HU 。窗口级别设置得越低,整个图像将变得越亮。
DcmViewer 提供了一些基础的窗位设置下拉列表,如:
伪色彩设置,即伪彩色映射,通过将灰度图像转换为彩色图像,有效地增强某些特征的可视性。它通过将灰度图像中的像素值映射到特定的颜色来实现彩色显示。医学影像中的灰度图经常用于表示不同密度或强度的区域,通过伪彩色映射,这些区域可以在视觉上更容易被识别和分析。DcmViewer 通过使用查找表(Look-Up Table, LUT)将每个灰度值映射到一个RGB颜色, 可以突出显示或隐藏不同的特征或信息,例如组织结构、病变位置或血管分布等。
几个概念说明:
要在屏幕上显示DICOM影像,那么需要把原始图像数据经过一系列的转换,才能得到可直接在显示设备上显示的数据。
Modality LUT转换:通常不同生产厂商的设备很难保证在一种设备上生成的图像和其他生产厂商的同类型设备上生成的图像在度量上是一致的,为此就需要将不同设备厂家产生的图像的原始数据转换到一个标准的度量空间,这一步的转换就是完成这个功能的。医疗设备的生产厂商都会在自己的图像中采用DICOM标准规定的格式说明如何将自己的数据转换为标准图像数据,可以使用通过查找表(Look Up Table,简称LUT查找)和通过斜率/截距(Rescale/Intercept)线性变换来转换。
使用的公式是:
VOl(Value Of Interest)LUT转换:由于医学图像数据动态范围大(像素深度通常不低于4096个灰度级),因此一般显示器很难提供如此高的动态范围一次显示整幅图像的全部信息细节,在图像的处理中一般都是先选择一个操作者感兴趣的区域,然后将该区域的图像信息映射到显示器能显示的整个数据范围,这样就增加了该区域的图像信息的对比度。VOI LUT转换可以使用设置窗宽、窗位的线性转换算法实现。
通过设置窗宽、窗位, 可以调整该区域的图像数据的最大值和最小值, 从而得到有效的VOl(Value Of Interest), 即把Max到Min之间的数据转换为显示器能接受的8-bit颜色值(0-255)。
if (x <= c - 0.5 - (w - 1)/2)
y = ymin
else if (x > c-0.5 + (w-1)/2)
y = ymax
else
y = ((x - (c-0.5))/(w-1) + 0.5) * (ymax - ymin) + ymin
y = (ymax - ymin)/(1+exp(-4*(x-c)/w)) + ymin
if (x <= c - w/2)
y = ymin
else if (x > c + w/2)
y = ymax
else
y = ((x - c)/w + 0.5) * (ymax - ymin) + ymin
x:是即将执行LUT变换的输入,如Modality LUT变换后的结果。
c:window center,DICOM Tag (0028,1050)。
w:window width,DICOM Tag (0028,1051)。
y:转换后的输出,一般在0-255之间。
ymin:输出的最小值, 即0。
ymax:输出的最大值, 即255。
经过以上两次转换以后,图像数据全部将被限定在显示器能接受的0-255之间。
Presentation LUT转换:对图像像素要做的最后一个变换,它用于特定图像的显示, 一般不被使用。DICOM Tag (2050,0020) Presentation LUT Shape 为IDENTITY,无需额外处理,如果为INVERSE,需要对结果进行inversion操作。
DcmViewer 提供以下几种伪色彩设置下拉框 - Plain(白片), InvPlain (反片) ,Rainbow, Hot, Hot Iron, PET, Hot Metal Blue 和 PET 20 Step,根据DICOM规范标准,定义红、绿、蓝颜色查找表(Red Palette Color Lookup Table Data),将上述VOl(Value Of Interest)值通过颜色查找表(Red Palette Color Lookup Table Data)赋色。
如,选择Hot Iron的效果:
DcmViewer提供对影像图像如下快捷操作:
“缩放”没被点亮时,鼠标的滚动用来导航(查看)至每张图像,当“缩放”被点亮时, 鼠标的滚动则用来缩放图像的大小。
DcmViewer影像图像导航,是指通过按钮查看至每张图像。
DcmViewer 同时提供病人(屏幕)坐标和像素坐标的对照坐标信息。 当导航影像图像或者在影像图像上任意点击鼠标时,底部将显示病人(屏幕)坐标和像素坐标的对照坐标信息及对应点的VOl(Value Of Interest)值。
在病人(屏幕)坐标和像素坐标之间相互转换前,需要了解的几个DICOM元素(Tag):
DICOM Tag (0020,0032) Image Position: 图像位置,指示了图像左上角的第一个像素的空间坐标 (x,y,z)。 也就是DICOM文件传输的第一个像素的坐标,3个浮点数值。
DICOM Tag (0020,0037) Image Orientation: 图像方向,指示了图像第一行和第一列相对于病人的方向cosine(余弦值,包含6个浮点数值 "Xx, Xy, Xz, Yx, Yy, Yz"), 描述为3X3矩阵为:
其中 [C] = [X] x [Y] 的叉乘, 表示影像图像的堆叠方向, 用来判断横断面、冠状面和矢状面及图像导航时的方向。
如果切片是垂直于病人坐标系的Z轴的, 即横断面,那么切片在z方向上的投影为0,此时Xz和Yz就是0;如果连切片的x、y方向跟病人坐标系都是一致,那么(0020,0037) Image Orientation就是 (1,0,0,0,1,0), 3X3矩阵为:
如果切片是垂直于病人坐标系的y轴,即冠状面, 如果连切片的x、z方向跟病人坐标系都是一致, 则:
DICOM Tag (0028,0030) Pixel Spacing: 像素间距, 一般是通过体模校正获得。
另外,坐标轴的方向是根据病人的方向来确定的(X轴指向病人的左手边,y轴指向病人的后面,Z轴指向病人的头部。
举例:
切片 m(黄色实线框):
0020,0032 Image Position (Patient): -99.8046875/-282.8046875/94.25
0020,0037 Image Orientation (Patient): 1/0/0/0/1/0
切片n(黄色虚线框):
0020,0032 Image Position (Patient): -99.8046875/-282.8046875/157.5
0020,0037 Image Orientation (Patient): 1/0/0/0/1/0
切片l(红色框):
假设了一个影像切片与病人坐标系不一致的情况,Image Position的6个值就是根据夹角(图中只标出了2个夹角)的cosine算出的, 分别为x在X上的cosine、y在X上的cosine、x在Y上的cosine、y在Y上的cosine、x在Z上的cosine和y在Z上的cosine。
上述举例数据用图形表示如下。
病人(屏幕)坐标和像素坐标之间的转换公式
根据 Image Position and Image Orientation DICOM 标准,将切片图像的像素点坐标表示为齐次形式(x,y,0,1),变换为病人坐标后是(x’,y’,z’,0),则:
(0020,0037) Image Orientation 依次对应公式中的 Xx、Xy、Xz、Yx、Yy、Yz,表示的就是切片x、y方向与病人坐标x、y、z方向的夹角关系,因为描述的是方向都是基于单位向量,所以(Xx,Xy,Xz)就是切片x方向在病人坐标系三个方向上的夹角余弦值(投影值),(Yx,Yy,Yz)同理。
(0020,0032) Image Position (Patient)依次对应公式中的Sx、Sy、Sz,单位毫米,表示的是切片图像左上角像素在病人坐标系中的坐标。
切片坐标(x,y)经过(Xx,Xy,Xz)、(Yx,Yy,Yz)投影至病人坐标系的三个方向以后,只是相对于切片左上角(0,0)的距离,还要加上Sx、Sy、Sz才能得到最终的病人坐标值。
切片坐标(x,y)是图像像素坐标,所以变换矩阵中的余弦值还需要乘上像素间隔(0028,0030)Pixel Spacing,即公式中的 delta x 和 delta y。
举例说明:假设有一个大小为512 * 512 [ DICOM Tag (0028,0010)Rows 和 DICOM Tag(0028,0011)Columns] 的影像图像。
像素坐标index (如,256,256,0)转至病人(屏幕)坐标World(如,-99.8046875,-282.8046875,94.25)的关键步骤:
// 乘 delta x 和 delta y(delta z 通常为1)
const spacing = this.getSpacing();
const orientedPoint3D = new Point3D(
index.get(0) * spacing.get(0),
index.get(1) * spacing.get(1),
index.get(2) * spacing.get(2)
);
// 乘 Image Orientation的矩阵
const point3D = this.getOrientation().multiplyPoint3D(orientedPoint3D);
// 加 Sx、Sy、Sz
const values = index.getValues();
const origin = this.getOrigin();
values[0] = origin.getX() + point3D.getX();
values[1] = origin.getY() + point3D.getY();
values[2] = origin.getZ() + point3D.getZ();
病人(屏幕)坐标World(如,-99.8046875,-282.8046875,94.25)转至像素坐标index (如,256,256,0)的关键步骤:
// point 为病人(屏幕)坐标World(如,-99.8046875,-282.8046875,94.25)
// 减 Sx、Sy、Sz
const point3D = new Point3D(
point.get(0) - origin.getX(),
point.get(1) - origin.getY(),
point.get(2) - origin.getZ()
);
// 乘 Image Orientation的逆矩阵
const orientedPoint3D =
this.getOrientation().getInverse().multiplyPoint3D(point3D);
const values = point.getValues();
// 除以 delta x 和 delta y(delta z 通常为1)
const spacing = this.getSpacing();
values[0] = Math.round(orientedPoint3D.getX() / spacing.get(0));
values[1] = Math.round(orientedPoint3D.getY() / spacing.get(1));
values[2] = Math.round(orientedPoint3D.getZ() / spacing.get(2));
判断影像导航方向的关键步骤:
通过上述DICOM Tag (0020,0037) Image Orientation 矩阵的第三列(Cx, Cy, Cz)可以得知下一张图片的移动方向。
// Image Orientation 矩阵的第三列表示移动方向,
// 返回0(Cx=1)则为矢状面方向移动,
// 返回1(Cy=1)则为冠状面方向移动,
// 返回2(Cz=1)则为横断面方向移动。
dim = this.getColAbsMax(2).index;
// 像素坐标index。
const values = new Array(index.length());
values.fill(0);
// 对应的移动方向上赋予值-1,以便对应的移动方向上能够减去1。
values[dim] = -1;
const incr = new Index(values);
// 对应的移动方向上减去1,达到导航后的新的index
index.add(incr);
// 根据新的index即可以拿到新的slide的数据。
在使用测量与绘制时,DcmViewer默认颜色为黄色。
如果需要使用其他的颜色,去掉勾选后,点击颜色框,弹出调色板,选择颜色即可。
DcmViewer 基于 Konvajs Shapes 的基础图形开发,并提供以下的测量工具。
点亮按钮,在图像上拖动图标,即可画出所选按钮的形状及测量数据。 再次点击该按钮,取消点亮来取消绘制测量。
选中所画出的的形状,可以通过拖动来改变形状的大小及位置来调整测量。
选中所画出的的形状,将形状拖至X处,或按下delete键可以删除该形状。
测量与绘制只发生在当前的视图上,当使用影像导航至上一张或者下一张影像,再次返回,画出的形状及测量数据不会被清除。
我们都知道, 表示颜色的RGBA参数用来描述颜色和透明度,四个字母分别对应红、绿、蓝三个颜色通道和一个透明度通道。每个参数通过数值组合决定最终的呈现效果。红绿蓝三个颜色通道取值范围为0到255,数值越大颜色越浓,透明度通道用0到1之间的小数表示,0代表完全透明,1代表完全不透明。比如RGBA(255,0,0,0.5)表示半透明的纯红色,RGBA(255,0,0,1)表示不透明的纯红色。
DcmViewer可以设置某个CT值区间,使在这个CT值区间之外的颜色透明,而在这个区间之内的颜色绝对的不透明。 滑动滑块可以改变CT值区间。
在2(1)中讲到, CT切片图像所有的CT值,拿样例举例,样例中一个CT值可表示为16位无符号整数,那么它代表的数可以覆盖的范围是 , 如果一个CT值可表示为16位有符号整数, 那么它代表的数可以覆盖的范围是 -32768 到 32768。
比如,把样例中的颜色不透明区间设置为 100-32768。
则CT切片图像中CT值少于100的颜色将全部透明(即不显示),仅显示CT切片图像中CT值在100-32768之间的颜色。
参考2(1)来设置对比度,在2(1)中讲到了DcmViewer医疗影像系统中的窗宽(window width)/ 窗位(window level、窗中心、窗口级别)的设置, 可以通过下拉框选取一个窗宽(window width)/ 窗位(window level、窗中心、窗口级别),通过调整窗宽(window width)/ 窗位(window level、窗中心、窗口级别)值,来增加VOl(Value Of Interest)区域的图像信息的对比度。
DcmViewer医疗影像系统可以设置整个视图的透明度, 设置区间为0-1, 这将设置整张图片的透明度。
默认值为1, 即整张图片不透明, 可以通过拖动滑块来设置这个透明度的值, 如设置为0.3的效果如下:
点击帮助图标, DcmViewer提供以下文档(链接)供参考。
技术是无止境的,如有任何问题或者需要任何技术支持请联系 networkregister@126.com, 让我们一起探讨,一起完善, 一起成长!
tips: 技术支持邮箱:networkregister@126.com