若是dicom格式的图片,得先转化为hu值(即ct图像值,若图片本来就是ct,则不需要转换)(见下面更新内容) ,因为hu值是与设备无关的,不同范围之内的值可以代表不同器官。常见的对应如下(w代表ct值width,L代表ct值level,即 [level - width/2 , level + width/2]为其窗口化目标范围):

2019-7-24更新
其实无论对于dcm还是nii格式的图片,只要是ct图,就都可以选择将储存的原始数据转化为Hu值,因为Hu值即代表了物体真正的密度。
对于nii格式的图片,经过测试,nibabel, simpleitk常用的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 pydicomnii_file = r'G:\data\LITS17\LITS17_vol\volume-0.nii'dcm_file = r'G:\data\3Dircadb\3Dircadb1.1\PATIENT_DICOM\image_0'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 dataseg = itk.ReadImage(nii_file)
segimg = itk.GetArrayFromImage(seg)  # == img.get_fdata(), Hu data
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 dataprint(pydicom.dcmread(dcm_file).pixel_array)  # == data_itk,unscaled, raw data

文章目录

  • dicom转化为hu的示例代码
  • windowing
    • Window width
      • Wide window
      • Narrow window
    • Window level/center
    • Upper and lower grey level calculation
  • windowing代码

dicom转化为hu的示例代码

如下:

def get_pixels_hu(scans):#type(scans[0].pixel_array)#Out[15]: numpy.ndarray#scans[0].pixel_array.shape#Out[16]: (512, 512)# image.shape: (129,512,512)image = np.stack([s.pixel_array for s in scans])# Convert to int16 (from sometimes int16), # should be possible as values should always be low enough (<32k)image = image.astype(np.int16)# Set outside-of-scan pixels to 1# The intercept is usually -1024, so air is approximately 0image[image == -2000] = 0# Convert to Hounsfield units (HU)intercept = scans[0].RescaleInterceptslope = scans[0].RescaleSlopeif slope != 1:image = slope * image.astype(np.float64)image = image.astype(np.int16)image += np.int16(intercept)return np.array(image, dtype=np.int16)

windowing

然而,hu的范围一般来说很大,这就导致了对比度很差,如果需要针对具体的器官进行处理,效果会不好,于是就有了windowing的方法:

Windowing, also known as grey-level mapping, contrast stretching, histogram modification or contrast enhancement is the process in which the CT image greyscale component of an image is manipulated via the CT numbers; doing this will change the appearance of the picture to highlight particular structures. The brightness of the image is, adjusted via the window level. The contrast is adjusted via the window width.

图像的亮度取决于window level,图像的对比度取决于window width。

Window width

The window width (WW) as the name suggests is the measure of the range of CT numbers that an image contains.

窗口宽度就是一幅ct图片包含的ct值范围。

A wider window width (2000 HU), therefore, will display a wider range of CT numbers. Consequently, the transition of dark to light structures will occur over a larger transition area to that of a narrow window width (<1000 HU).

更宽的窗口,相对于窄的窗口来说,从暗到亮的结构过度将会在发生在更大的过度区域。

Accordingly, it is important to note, that a significantly wide window displaying all the CT numbers will result in different attenuations between soft tissues to become obscured.

因此,一个展示了所有ct值的宽窗口,将导致软组织间不同的ct值变得模糊。

Wide window

Defined as 400-2000 HU best used in areas of acute differing attenuation values, a good example is lungs or cortical tissue, where air and vessels will sit side by side.

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

Narrow window

Defined as 50-350 HU are excellent when examining areas of similar attenuation, for example, soft tissue.

窄的窗口常用于ct值相似的区域,例如软组织。

Window level/center

The window level (WL), often also referred to as window center, is the midpoint of the range of the CT numbers displayed.

窗口水平,也经常成为窗口中心,是ct值的中点。

When the window level is decreased the CT image will be brighter and vice versa.

窗口level减少,图片将变亮,level增大,图片变暗。

Upper and lower grey level calculation

When presented with a WW and WL one can calculate the upper and lower grey levels i.e. values over x will be white and values below y will be black.

当给定了window width和window level后,就能计算出窗口的上下界。
超过上界的,是白色,低于下界的,是黑色。
下面是计算方法和举例。

the upper grey level (x) is calculated via WL + (WW ÷ 2)
the lower grey level (y) is calculated via WL - (WW ÷ 2)

For example, a brain is W:80 L:40, therefore, all values above +80 will be white and all values below 0 are black.

windowing代码

def transform_ctdata(self, windowWidth, windowCenter, normal=False):"""注意,这个函数的self.image一定得是float类型的,否则就无效!return: trucated image according to window center and window width"""minWindow = float(windowCenter) - 0.5*float(windowWidth)newimg = (self.image - minWindow) / float(windowWidth)newimg[newimg < 0] = 0newimg[newimg > 1] = 1if not normal:newimg = (newimg * 255).astype('uint8')return newimg

2019-10-9 更新
windowCenter和windowWidth的选择:
一是可以根据所需部位的hu值(对于CT数据而言)分布范围选取(注意若是增强ct的话hu值会有一些差别,可以画一下几个随机数据的hu分布图看一看)
二是可以根据图像的统计信息,例如图像均值作为窗口中心,正负2.5(这个值并非固定)的方差作为窗口宽度
下面是github上,vnet一个预处理过程,使用了基于统计的窗口化操作

class StatisticalNormalization(object):"""Normalize an image by mapping intensity with intensity distribution"""def __init__(self, sigma):self.name = 'StatisticalNormalization'assert isinstance(sigma, float)self.sigma = sigmadef __call__(self, sample):image, label = sample['image'], sample['label']statisticsFilter = sitk.StatisticsImageFilter()statisticsFilter.Execute(image)intensityWindowingFilter = sitk.IntensityWindowingImageFilter()intensityWindowingFilter.SetOutputMaximum(255)intensityWindowingFilter.SetOutputMinimum(0)intensityWindowingFilter.SetWindowMaximum(statisticsFilter.GetMean() + self.sigma * statisticsFilter.GetSigma())intensityWindowingFilter.SetWindowMinimum(statisticsFilter.GetMean() - self.sigma * statisticsFilter.GetSigma())image = intensityWindowingFilter.Execute(image)return {'image': image, 'label': label}

医学图像预处理(三)——windowing(ct对比增强)相关推荐

  1. 论文阅读:CRA-CNN对比增强的注意力卷积神经网络

    Contrastively-reinforced Attention Convolutional Neural Network for Fine-grained Image Recognition 个 ...

  2. 图像多尺度对比增强算法

    多尺度对比增强算法的基本观点是将图像分解成代表图像单个细节的像素,然后立 即在这些像素上提高对比度,因此要求选择一种图像分解方法. 在图像分解方法的选择上要遵循以下两个基本条件:           ...

  3. 元素隐藏的三种方式对比(针对移动端项目中的按钮,先隐藏且不能被点击 visibility:hidden)

    元素隐藏的三种方式对比 display:none opacity:0 visibility:hidden 项目需求 表面一个图片遮罩,鼠标hover遮罩消失,内部元素展现,其中有一个按钮在移动端是手指 ...

  4. vector,list deque三种容器对比

    一.vector与list对比 vector: 随机访问快,即下标运算尾添加,不申请空间的情况下,速度很快不支持,快速插入和删除,比较慢 list: 随机访问慢支持快速插入和删除 二.内存对比 vec ...

  5. 【老生谈算法】matlab实现EKF UKF PF三种算法对比源码——EKF UKF PF算法

    EKF UKF PF三种算法对比 matlab程序 1.文档下载: 本算法已经整理成文档如下,有需要的朋友可以点击进行下载 序号 文档(点击下载) 本项目文档 [老生谈算法]EKF-UKF-PF三种算 ...

  6. APS计划排程系统之下的MRPII、JIT、TOC三种方式对比分析

    1.生产物流计划的制订方式对比 ①MRPII采用的是集中式的物料计划方式,建立好产品加工程序,在电脑中确定好准确的订单需求和库存量,对各个生产单元传送生产指令: ②JIT利用的是看板管理控制方式,按照 ...

  7. android 版本比对,iQOO Neo三个版本对比体验 845版、855版、855 Plus版对比实测

    iQOO Neo三个版本对比体验 845版.855版.855 Plus版对比实测 2020-03-27 14:54:45 4点赞 0收藏 1评论 iQOO虽然到现在成立还不到一周年,但是已经推出了5款 ...

  8. java 时间戳 对比_Java中获取时间戳的三种方式对比实现

    Java中获取时间戳 三种方式对比 最近项目开发过程中发现了项目中获取时间戳的业务.而获取时间戳有以下三种方式,首先先声明推荐使用System类来获取时间戳,下面一起看一看三种方式. 1.System ...

  9. Storm与Spark、Hadoop三种框架对比

    目录 Storm与Spark.Hadoop三种框架对比 一.Storm与Spark.Hadoop三种框架对比 二.hadoop的应用业务分析 二.浅谈Hadoop的基本原理 Hadoop与Storm的 ...

最新文章

  1. 23-hadoop-hive的DDL和DML操作
  2. Java设计模式学习之工厂模式
  3. python 新闻分析系统 源码_python 源码分析之类型系统
  4. 四、CI框架之通过URL路径访问C中的函数
  5. 无线路由器和计算机怎么连接网络连接,华为无线路由器怎么连接宽带上网
  6. 小程序购物车抛物线(贝塞尔曲线实现)
  7. 计算机如何模拟人类说话,七十、计算机如何模拟痛觉
  8. rfid 标签内存_RFID有源与无源的区别与联系
  9. mysql 临时表 主键_MySQL临时表
  10. java adf是什么_在ArcIMS9.2中使用JAVA ADF实现图层要素的查询
  11. Atitit.软件仪表盘(2)--vm子系统--资源占用监测
  12. 开发反应执行阿里云mysql语句报错
  13. 定时获取AccessToken——萤石开放平台
  14. 固态硬盘打开计算机就死机,SSD固态硬盘死机卡顿无响应怎么办?SSD卡顿故障处理教程 | 麦田一棵葱...
  15. PHP开发微信支付小微商户V3版本 图片上传、生成签名、平台证书获取、平台证书编号、敏感信息加密
  16. Ant(蚂蚁搬家)工具
  17. python改变数组形状_NumPy数组的变形(改变数组形状)
  18. 哭得累了   矛盾心里总是强求   劝自己要放手   闭上眼让你走
  19. HTML语言中表格的书写中TD TR TH的英文全称
  20. Task xxx not found in root project xxx.

热门文章

  1. Monaco Editor教程(一): 开源项目 monaco-editor 开启本地开发环境
  2. Thymeleaf语法webjars使用
  3. android电脑不识别手机号码,安卓手机刷机后电脑不识别怎么办 如何让电脑重新识别手机...
  4. Mac音乐增强播放器——“Amarra 4”
  5. 电脑端bp抓手机数据包
  6. 微信小程序输入框数据获取(九)
  7. Win10系统自带的CPU和内存悬浮窗口
  8. 【 高透明塑料抗菌剂iHeir-ECO 塑料制品添加剂】
  9. kali linux渗透测试之漏洞扫描
  10. Java 根据id不同,生成唯一礼包码