医学图像的CT值与像素值总结及转换代码

一、CT图像的调窗

CT值又叫HU值。HU(Hounsfiled Unit)值,反映了组织对X射线吸收程度。以水的吸收程度作为参考,即水的HU=0,衰减系数大于水的为正直,小于水的为负值。并以骨皮质和空气的HU值为上限和下限。
因为HU值是与设备无关的,不同范围之内的值可以代表不同器官。HU的范围一般来说很大,这就导致了对比度很差,如果需要针对具体的器官进行处理,效果会不好,于是就有了调窗(windowing)的方法。
在这里插入图片描述
图像的亮度取决于window level,图像的对比度取决于window width。
窗技术一种特殊的显示技术。窗技术包括窗宽和窗位,窗宽是ct图像上显示的ct值范围,在此ct值范围内的组织和病变均以不同的模拟灰度显示,ct值高于或低于此范围的组织或病变均不存在灰度差别。
窗宽主要影响图像对比度,窗宽大图像层次多,但组织对比减小,细节显示差。
窗位是窗的中心位置,同样的窗宽,由于窗位不同,其所包括ct值范围的ct值也不同。窗位主要影响图像的亮度,窗位越高,图像越黑,反之,图像变白。欲观察某一组织结构及其病变,应以该组织的ct值为窗位。
所以简而言之骨窗就是以选取骨组织ct值为窗位的适合窗宽所设计的显像序列从而对骨组织的病变显示更为清楚。

1、Window width

Wide window: 宽窗口经常用于ct值变化很大的领域,比如肺部或外皮组织,这些地方空气和血管将会一同出现。
Narrow window: 窄的窗口常用于ct值相似的区域,例如软组织。

2、Window level/center

窗口水平,也经常成为窗口中心,是ct值的中点。
窗口level减少,图片将变亮,level增大,图片变暗。

窗口化目标范围公式:[level - width/2 , level + width/2] , 其中w代表ct值width,L代表ct值level

在这里插入图片描述

二、DICOM文件中窗宽窗位对应字段

DICOM文件中与窗宽窗位对应的字段主要有6个。分别为:
1.(0028, 1025)Rescale Intercept
2.(0028, 1053)Rescale Slope

可以简单的理解: Rescale Intercept就是截距, Rescale Slope为斜率。
因为每个公司的设备不同,就算同一家公司的不同设备,每台设备产生出来的原始数据(.dcm里边存储的数据,可以理解成灰度值)也可能是不同的。比如dicom规定,肌肉的灰度范围为40~80,但是每台机器出来可能不是这个值。
如果设备出来的原始数据和dicom规定的CT值是线性相关的,那么我们就可以通过线性映射,将设备出来的原始数据转换为dicom规定的CT值。公式为:y=k*x+b。x就是设备出来的原始值,k为 Rescale Slope,b为Rescale Intercept。这样经过这个线性变换,就将设备产生的数据映射为dicom规定的人体CT值。

3.(0028, 1050) Window Center
4.(0028, 1051) Window Width

Window Center 为窗位,Window Width为窗宽,就如第一节介绍的。

5.Modality LUT
6.VOI LUT

然而并不是所有设备产生的值与dicom规定的CT值是线性映射。当不是线性映射时,就需要列一个表,将设备产生的数据与dicom规定的CT值一一对应,Modality LUT就是这个表。
当映射不是线性时,窗宽,窗位也就不是线性映射了。所以也需要一个表来对应,VOI LUT就是这个表。

注意:上述六个字段并不是同时存在的,1,2和5是对立的,有1,2就不会有5。3,4和6是对应的,有3,4不会有6。

三、CT值与像素值转换(线性映射)

无论对于dcm还是nii格式的图片,只要是ct图,就都可以选择将储存的原始数据转化为Hu值,因为Hu值即代表了物体真正的密度。
对于nii格式的图片,经过测试,nibabel常用的api接口,都会自动的进行上述转化过程,即取出来的值已经是Hu了。
(除非专门用nib.load(‘xx’).dataobj.get_unscaled()或者itk.ReadImage(‘xx’).GetPixel(x,y,z)才能取得原始数据)
对于dcm格式的图片,经过测试,simpleitk, pydicom常用的api接口都不会将原始数据自动转化为Hu!!(itk snap软件读入dcm或nii都不会对数据进行scale操作)

import nibabel as nib
import SimpleITK as itk
import pydicom


nii_file = r'case_002\case_002.nii.gz'

dcm_file = r'DICOM\case_002'

img = nib.load(nii_file)
"""
经过测试get_fdata会自动根据头文件数据中的
inter, slope 将raw data转换到hu data
img.dataobj.get_unscaled获取的就是未转化的
raw data。还需要注意的是,img.header中的
scl_slope, scl_inter为nan,因为对于转换后的
hu data而言,这两个值已经不重要了
想要知道的话,可以专门用
img.dataobj.slope, img.dataobj.inter 获取
"""
hu_data = img.get_fdata()  # Hu data
pixel_data = img.dataobj.get_unscaled() # raw data

seg = itk.ReadImage(nii_file)
segimg = itk.GetArrayFromImage(seg)  
print(seg.GetPixel(0, 0, 0))  # unscale, raw data
"""经过测试,itk里的头文件不会像nib将inter和slope抹去"""
 for key in seg.GetMetaDataKeys():
#     print("{0}:{1}".format(key, seg.GetMetaData(key)))

print('---------------')

dcm_itk = itk.ReadImage(dcm_file)
# for key in dcm_itk.GetMetaDataKeys():
#     print("{0}:{1}".format(key, dcm_itk.GetMetaData(key)))

print(dcm_itk.GetPixel(0, 0, 0))  # -1024 unscaled, raw data
data_itk = itk.GetArrayFromImage(dcm_itk)
print(data_itk)  # -1024,unscaled, raw data

print(pydicom.dcmread(dcm_file).pixel_array)  # == data_itk,unscaled, raw data

1、itk-snap软件和sitk代码示例

在这里插入图片描述
在这里插入图片描述
头文件信息:
头文件信息

2、Mango软件和nibabel代码示例

在这里插入图片描述
在这里插入图片描述

总结

将dcm图像的值转换为HU值应当满足公式:

HU = pixel_val * slope + intercept

如上面例子:
sitk读到的最大值为32767,其中头文件信息中Slope = 0.02333 Intercept = 764.51166
那么HU = 32767 * 0.02333 + 764.51166 = 1,528.97

有的图像就已经是CT值(HU值),该图像的Solpe=1,Intercept=0,如果按照上面的公式计算,就还是图像的值;
而有的图像则是像素值,所以需要转化,如该图像的Slope = 0.02333 Intercept = 764.51166

  • 17
    点赞
  • 118
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值