7. DICOM图像显示-DCMTK-像素数据的三次转换和源码分析

  要显示DICOM格式的医学图像必须将原始图像数据经过一系列的转换才能得到可直接在显示设备上显示的数据(称之为P Values)。DICOM医学图像显示需要经过Modality LUT、VOI LUT、Presentation LUT三个转换过程,最终输出的P Values才是可以直接显示的图像数据。
LUT是Look Up Table查找表缩写,VOI是Volume of Interest感兴趣区域缩写,P Values是Presentation Values表现值缩写。
在这里插入图片描述

一. 协议剖析

1.1 Modality LUT

  通常不同生产厂商的设备很难保证在一种设备上生成的图像和其他生产厂商的同类型设备上生成的图像在度量上是一致的,为此就需要将不同设备厂家产生的图像的原始数据转换到一个标准的度量空间, Modality LUT转换就是完成这个功能的。
  以CT成像技术为例,我们已经知道人体的灰度范围是-1000到+1000,但是因为设备厂家不同采集后的数据可能会有偏差,比如假设A组织标准范围是50到200,但是设备厂家1出来的可能是60到210,设备2出来的可能是40到190。如果每个厂家设备都有偏差那么我们就没有办法根据灰度值来评判组织(因为我这里的肺检测出来时150,到了你那里可能就变成140了)。所以DICOM标准要求设备厂家在导出数据的时候要将自身设备出来的灰度范围变换到标准的-1000~1000范围内。也就是说Modality LUT是设备厂家自身与标准之间的一次变换映射。
  Modality LUT相关的元素如下图所示
在这里插入图片描述
Modality LUT提供了线性和非线性两种映射方式查找表非线性转换和斜率/截距线性转换。
  Modality LUT查找表方法是一种非线性变换算法。一个查找表由很多数据项组成,每一个数据项为相应原始数值转换后的数据值,同时还会提供一个被转换为查找表第一个数据项的原始数据的数据值。
  斜率/截距(Rescale/Intercept)变换是一种线性变换,使用的公式是:标准图像像素值 = 原始图像像素值 * 斜率 + 截距,斜率和截距在DICOM文件中可以读取。

Hu = pixel * slope + intercept

  通过这一步转换后图像像素就从设备有关变成设备无关了。

1.2 VOl LUT转换VOl LUT转换

  医学图像的输出值多为12或16bit,而人眼实际能分辨的灰度约为8bit,大多数显示器也只能显示256级灰度。即便是专业的医学影像显示器,其灰度分辨率也只达到10到12bit的水平,离16bit还有很大的差距。为了在屏幕上显示这些高色深的医学影像,不可避免地需要将图像数据值域压缩到8bit,这是一个典型的有损转换,且这种转换容易突出图像中的噪音部分。
  VOl LUT相关的元素如下图所示
在这里插入图片描述
  为了突出感兴趣区域的细节,VOl LUT转换同样提供了线性和非线性两种映射方式查找表非线性转换和窗宽窗位线性转换。
  线性映射亦即临床医生较为关心的窗宽窗位调节算法。该转换定义了一些较好的映射算法,充分利用0~255间的显示有效值域,减少了值域压缩带来的损失,并且尽量突出医生感兴趣的组织部分,满足了医学图像对灰度处理的特殊要求。标准公式见式(1),其中所有输入值均为整数,并且窗宽w必须大于1。其中:w为窗宽;c为窗位;xmin为最小输入值;xmax为最大输入值;fmin为最小输出值;fmax为最大输出值。
在这里插入图片描述

min = (2 * wl - ww) / 2.0 + 0.5;
max = (2 * wl + ww) / 2.0 + 0.5;
gray_value = (ct_value - min) * 255.0 / (max - min)

  窗宽窗位线性转换算法是根据预知的窗宽和窗位值获得需要显示的窗口大小(窗宽)和中心位置(窗位),从而将窗口区域的图像数据线性地转换到显示器的最大范围内,高于或低于窗口上、下限的图像数据则分别设置为最高或最暗的显示值。
  在这里窗宽是指需要显示图像的范围,调节窗宽主要影响对比度,窗宽越大图像灰度层次多,组织对比度减少,细节显示差,而窗位也称窗中心,表示显示区域的中心位置,例如骨骼的窗位、窗宽分别为300,1500,那么就可以利用调窗处理将窗宽调节到骨骼窗宽,窗位调节到骨骼的窗位,然后利用上面的公式将图像V换算成显示器显示值,最终得到的结果是只显示窗口范围内的图像,也就是骨骼。
  DICOM图片自身提供的一对或多对窗储存于Window Center(0028,1050)和Window Width(0028,1051)元素中。对于未提供窗的图片,一般以xmax - xmin为窗宽,以(xmax + xmin)/2为窗位,进行线性映射。
  某些时候,线性映射对一些窗口太宽或病灶太微小且与周围正常组织密度差太小的图像则收效甚微。面对这种情况,技师会在采集工作站上用一些非线性转换来提高对比度,同时补偿人眼对光的非线性反应。这类非线性转换不能简单地用窗宽窗位来推导。因此,DICOM标准将这类非线性映射关系以查找表的方式储存在Voilut Sequence(0028,3010)序列中。该序列包括了LUT Descriptor(0028,3002),LUT Explanation(0028,3003)和LUT Data(0028,3006)这3个DICOM元素。
  一般说来,如果DICOM文件里有Voilut Sequence这个元素,必须首先采用Voilut查表方式做映射。同线性映射一样,一幅图像可以提供1个或多个查找表。不同的查找表映射不同灰度区域的图像信息。实际使用过程中,经常用到的非线性映射有对数映射、SigMoid映射等。

1.3 Presentation LUT

  对图像像素要做的最后一个变换,它用于特定图像的显示。这一模块转换完成后的输出值为P Values,P Values是独立于任何显示设备的特性曲线,与人的视觉反应近似相关的值,可直接作为已经校正的软拷贝设备或硬拷贝的输入。Presentation LUT参照人类视觉特征曲线非线性的特点,变换输入数据使得灰度输出值Presentation Values(P-Values)与人眼的灰度视觉特性成正比。P-Values和指定显示设备的特征曲线无关,是标准显示设备的输入项。Presentation LUT常见于矫形图像显示,通过非线性校正曲线提高对比度,以便寻找患者骨头中的断缝。
  Presentation LUT相关的元素如下图所示
在这里插入图片描述
  Presentation LUT转换同样提供了线性和非线性两种映射方式查找表非线性转换和Presentation Shape线性转换,这两种转换方法只能使用一种。
  Presentation LUT转换的过程基本同上面介绍的两种LUT算法。
  Presentation Shape使用INDENTITY和INVERSE两者中的一个。INDENTITY表示经过VOI LUT转换得来的数据值即P-Values值,不需要转换,一般图像的软拷贝使用这个值;INVERSE 的值应与 IDENTITY 的值含义相同,但最小输出值应表示最大可用亮度的含义,最大值应表示最小可用亮度。
在这里插入图片描述
INVERSE方式如下计算:

P-Value = maximum value - output value

  常见的DICOM图像一般只需Modality LUT、VOI LUT两个转换过程即可显示,一般不使用Presentation LUT转换。

二. 源码剖析

在这里插入图片描述
  dcmtk中用到dcmimgle模块的DicomImage类,如果是单色图像只需dcmimgle模块,如果是彩色图像还需要dcmimage模块。
  Modality LUT、VOI LUT、Presentation LUT转换后的数据和dcmtk的模块/方法对应关系如下:
  dcmdata模块的getUint8Array方法返回值,为原始Pixel Data数据
  dcmdata模块的getUint16Array方法返回值,为设备相关的数据
  dcmimgle模块的getInterData方法返回值,为Modality LUT转换后的数据
  dcmimgle模块的getOutputData方法返回值,为VOl LUT和Presentation LUT转换后的数据。

  dcmimgle模块的DicomImage类只要实例化后,即可获得Modality LUT转换后的数据和VOl LUT转换后的数据,下面进行dcmtk源码分析。

dicomImg = new DicomImage(dcmParse->GetDataSet(), EXS_LittleEndianExplicit);
const DiPixel *diPixel = dicomImg->getInterData();
EP_Representation rep = diPixel->getRepresentation();
switch (rep) {
   
case EPR_Sint8:
	break;
case EPR_Uint8:
	break;
case EPR_Sint16:
	//Modality LUT转换后的数据
	CTValue = (signed short*)diPixel->getData();
	break;
//VOl LUT和Presentation LUT转换后的数据
unsigned char *pixelDataGrey = (unsigned char*)(dicomImg->getOutputData(8, 0, 0));

2.1 获得设备相关图像素数据

  将 (7FE0,0010)Pixel Data数据转换为Modality LUT输入数据InputData
  convert pixel data from DICOM dataset to input representation

  DicomImage内部调用DiMono2Image

Image = new DiMono2Image(Document, ImageStatus)

  DiMono2Image继承DiMonoImage,DiMonoImage继承DiImage,DiImage构造函数中调用convertPixelData()方法,convertPixelData方法将Dicom存储的8bit的Pixel Data数据转换为设备相关的16bit的数据,即为Modality LUT的输入。
  根据(0028,0103)Pixel Representation判断(7FE0,0010)Pixel Data存储的数据是有符号还是无符号。
  这里,根据BitsStored=12和Pixel Representation=0,调用对应的方法。

else if (BitsStored <= 16)
{
   
	//根据(0028,0103)Pixel Representation判断(7FE0,0010)Pixel Data存储的数据是有符号还是无符号
     if (hasSignedRepresentation)
         InputData = new DiInputPixelTemplate<Uint16, Sint16
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要使用DCMTK 3.6.3的dcm2pnm.exe将多帧DICOM图像转换为单个PNG图像,您可以按照以下步骤操作: 1. 首先,确保已经正确安装DCMTK 3.6.3库。您可以从DCMTK的官方网站(https://dicom.offis.de/dcmtk.php.en)下载并按照说明进行安装。 2. 打开命令行提示符或终端窗口,并导航到包含DICOM图像文件的目录。 3. 运行以下命令以将多帧DICOM图像转换为单个PNG图像: ``` dcm2pnm +Fpng input.dcm output.png ``` 其中,`input.dcm`是您要转换的多帧DICOM图像文件的路径,`output.png`是生成的单个PNG图像文件的路径。 请确保在命令行中正确指定了dcm2pnm.exe的路径,或者将其添加到系统环境变量中,以便可以直接在任何目录下运行该命令。 4. 执行命令后,dcm2pnm将会解析输入的多帧DICOM图像,并将其转换为单个PNG图像。生成的PNG图像文件将保存在指定的输出路径中。 请注意,dcm2pnm是DCMTK提供的一个实用工具,可用于将DICOM图像转换为其他常见的图像格式。根据您的需求,您可以使用其他选项和参数来进一步控制转换过程。您可以通过运行 `dcm2pnm --help` 命令获取更多用法和选项的详细信息。 此外,如果您希望在自己的程序中实现DICOM图像转换,您可以使用DCMTK库提供的API来读取和处理DICOM图像,并将其保存为PNG格式。具体的实现方式将涉及更多的编程细节,可以参考DCMTK的文档和示例代码以获取更多信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

DICOM医学影像

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

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

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

打赏作者

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

抵扣说明:

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

余额充值