【DICOM医学影像1】数据格式存储于显示,基本知识科普指南

2023-11-05

DICOM(Digital Imaging and Communications in Medicine)数据格式,是医学影像存储中的标准格式。无论是X光、CT,还是MRI等等影像,采集的原理不同,但是存储的格式一般都是统一的。本文就对DICOM文件的图像显示,做个介绍。

要显示DICOM格式的医学图像,必须将原始图像数据经过一系列的转换才能得到可直接在显示设备上显示的数据(称之为P Values)。DICOM医学图像显示需要经过Modality LUT、VOI LUT、Presentation LUT三个转换过程,最终输出的P Values才是可以直接显示的图像数据。

下图展示了从dicom中的pixel到显示的gray data的全过程,和相关需要的参数。
1
其中:

  • LUT:是Look Up Table查找表缩写
  • VOI:是Volume of Interest感兴趣区域缩写
  • P Values:是Presentation Values表现值缩写

为什么显示要经过这样繁琐的过程?

通常不同生产厂商的设备很难保证在一种设备上生成的图像和其他生产厂商的同类型设备上生成的图像在度量上是一致的,为此就需要将不同设备厂家产生的图像的原始数据转换到一个标准的度量空间, Modality LUT转换就是完成这个功能的。

CT成像技术为例,我们已经知道人体的灰度范围是-1000到+1000。但是因为设备厂家不同采集后的数据可能会有偏差,比如假设A组织标准范围是50到200,但是设备厂家1出来的可能是60到210,设备2出来的可能是40到190。如果每个厂家设备都有偏差那么我们就没有办法根据灰度值来评判组织(因为我这里的肺检测出来时150,到了你那里可能就变成140了)。

所以DICOM标准要求设备厂家在导出数据的时候要将自身设备出来的灰度范围变换到标准的-1000~1000范围内。也就是说Modality LUT是设备厂家自身与标准之间的一次变换映射

DICOM 分类上可以查到这四个 Tag 分成两个模组,以下举例几个相关的关键 Tag

  1. Modality LUT
- (0028,1052) Rescale Intercept
- (0028,1053) Rescale Slope
- (0028,1054) Rescale Type
- (0028,3000) Modality LUT Sequence
    - (0028,3002) LUT Descriptor
    - (0028,3003) LUT Explanation
    - (0028,3004) Modality LUT Type
    - (0028,3006) LUT Data
  1. VOI LUT
- (0028,1050) Window Center
- (0028,1051) Window Width
- (0028,1056) VOI LUT Function
- (0028,3010) VOI LUT Sequence
    - (0028,3002) LUT Descriptor
    - (0028,3003) LUT Explanation
    - (0028,3006) LUT Data

其中:

  • 窗位(Window Center):代表可视范围(或是感兴趣区域)的 CT 值范围中心
  • 窗宽(Window Width):可视范围大小
  • 调整斜率(Rescale Slope)
  • 调整截距(Rescale Intercept)

以上几个属性(Attribute)使用要注意几个规则:

  • Window Center (0028,1050) 与 VOI LUT Sequence (0028,3010) 选择一个使用
  • Window Center (0028,1050) 须与 Window Width (0028,1051) 搭配使用
  • Rescale Intercept (0028,1052) 与 Modality LUT Sequence (0028,3000) 选择一个使用
  • Rescale Intercept (0028,1052) 须与 Rescale Slope (0028,1053) 搭配使用

一、Modality LUT

看到这边就大概知道为什麽还要 Rescale Intercept Rescale Slope ,为了转换成 CT 值(HU)

这部分的属性值需要设备厂商正确提供才能准确的把拍摄的图像数值转换成对照的 CT 值。常规转换公式如下:
在这里插入图片描述

当我们要将CT值映射到8-bit [0,255]萤幕上显示,可以用以下一元二次方程式来计算
在这里插入图片描述
在这里插入图片描述
1

上述公式要转换到16-bit/12-bit/10-bit值域,只要把255替换成欲转换值域的最大值即可。一般情况下,

  • Rescale Intercept(0028,1052)预设为 0;
  • Rescale Slope(0028,1053)预设为 1

这边补充一个网上对 InterceptSlope 的概念说明,为什么要引入这两个参数:

CT 生成的图像数值范围是 [-1024…+32768] 共 33793 阶,而 DICOM 的 CT 影像常用 12-bit 储存数据,最多储存 4096 阶,为了能将 CT 能表示的数值存入 DICOM 档案内,所以使用截距斜率进行转换

二、VOI LUT

VOI LUT是将CT值,转化为灰度值,用于显示。其中

  • 窗位(Window Center/Window Level):代表可视范围(或是感兴趣区域)的 CT 值范围中心
  • 窗宽(Window Width):可视范围大小

用下面这张图就很好理解 WL WW 的功用,用来增强我们想关注的部位的呈现效果

在这里插入图片描述

像上图 AirDense BoneCT 灰阶值有 2001 阶,若要映射到用 8-bit 显示灰阶萤幕,只能使用 0~255256 阶 (比如 Windows 的 sRGB)

WL, WW 的设定好坏,关係到医生是否能准确的分析出病徵有很大关係。基于以上原因,那只要把关注几个部位的对应 CT 值框进 WL, WW 内,那就可以很清楚看出异常病灶处

以下列出几个换算公式:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 窄窗宽 (Narrow Window Width)
  • 对比度(Contrast)增加
  • 适合有相似的衰减值(HU/CT)的部位,比如:软组织
  1. 宽窗宽 (Wide Window Width)
  • 对比度(Contrast)减少
  • 适合衰减值(HU/CT)明显不同的部位,比如:肺与支气管

Window Center控制影像的亮度(Brightness),而 Window Width 控制影像的对比度(Contrast)。调整窗位与窗宽的影响如下:

  • Window Center 越大亮度越暗,反之越小亮度越亮
  • Window Width 越大对比度越低,反之越小对比度越高

如下:垂直方向表示WC亮度变化(下到上→亮到暗);水平方向表示WW对比度变化(左到右→高到低)

在这里插入图片描述

总结可发现: WC, WW 是针对 CT 图像来设计,计算上都要把数值转换为 CT 值才能做窗位、窗宽调整。

这个转换包括把多余高位 bit 变成 0(最低灰阶值),低位 bit 变成最高灰阶值(8-bit: 255, 10-bit:1023, 12-bit: 4096, 14-bit: 16383, 16-bit: 65535),再用 Rescale Intercept 与 Rescale Slope 作单位换算。

三、杂记

到此会发现都没说到最开始提到的 VOI LUT SequenceModality LUT Sequence,这两个主要是给非常规的转换而来,主要方法是用查表映射(Lookup Table)对应数值

  • VOI LUT Sequence 的几个属性就单纯查表对应使用

  • Modality LUT Sequence 除了查表用属性外,还有一个 Modality LUT Type(0028,3004) 来指明转换后的数值单位(除了 HU 也可能使用光电量测单位)

面对显示器往往只有 8-bit,而数据有 12-16 bit 的落差,过去的演算法把数据的 Max 到 Min 之间转换到 8-bit 的 0-255,过程是个有损转换,最终得到的图像常常突现一些噪声(Noise)

针对这些问题,研究学者提出几项要求来规范转换的演算法,目前转换方式便是基于以下这些要求设计出来:

  • 充分利用 0-255 之间的有效显示范围
  • 尽量减少数值压缩带来的损失
  • 不能损失应该凸显的组织部分

总结下,在DICOM文件存储标准中,Modality LUT、VOI LUT 和 Presentation LUT 是用于图像处理和显示的不同类型的查找表。它们在医学影像中的处理和呈现中起着重要的作用。

  1. Modality LUT(Modality Lookup Table):模态查找表
    Modality LUT 用于将图像数据从设备特定的原始单位(例如CT值、MR信号强度等)转换为更具有物理含义的单位。它可以用来调整图像的对比度和亮度等,以确保图像在显示时具有适当的视觉效果。Modality LUT 通常由设备厂商在图像采集时应用,以便在图像存储时进行修正。

  2. VOI LUT(VoiLookup Table):值域查找表
    VOI LUT 用于调整图像的值域,即图像中各像素的灰度值。它可以用于增强或减弱图像中不同结构的对比度,以更好地突显感兴趣的解剖结构。VOI LUT 可以在显示过程中应用,以适应不同的显示环境和需求。

  3. Presentation LUT(Presentation Lookup Table):呈现查找表
    Presentation LUT 用于将图像数据从原始的灰度值映射到显示设备的灰度范围。它用于确保图像在不同的显示设备上具有一致的外观。Presentation LUT 可以根据显示设备的特性进行调整,以便在各种显示条件下都能获得良好的图像质量。

总之,Modality LUT、VOI LUT 和 Presentation LUT 是在DICOM标准中定义的不同类型的查找表,用于处理和呈现医学影像。它们在图像的获取、处理和显示过程中相互配合,以确保图像的质量和一致性。

参考内容:

  1. https://dotblogs.azurewebsites.net/MemoryRecall/2021/07/17/170824
  2. https://www.cnblogs.com/grass-and-moon/p/16595919.html
  3. https://programming.vip/docs/dicom-image-display-dcmtk-three-conversions-of-pixel-data.html
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【DICOM医学影像1】数据格式存储于显示,基本知识科普指南 的相关文章

  • Lighttpd 和 cgi python

    我正在尝试通过 lighttpd 执行一些 python 脚本 但是当我尝试运行它时 我只得到一个要求我下载的空白文件 lighttpd conf server modules mod access mod alias mod access
  • Python getstatusoutput 替换不返回完整输出

    我发现了这个很棒的替代品getstatusoutput Python 2 中的函数在 Unix 和 Windows 上同样有效 不过我觉得这个方法有问题output被构建 它只返回输出的最后一行 但我不明白为什么 任何帮助都是极好的 def
  • 删除flask中的一对一关系

    我目前正在使用 Flask 开发一个应用程序 并且在删除一对一关系中的项目时遇到了一个大问题 我的模型中有以下结构 class User db Model tablename user user id db Column db String
  • YOLOv8获取预测边界框

    我想将 OpenCV 与 YOLOv8 集成ultralytics 所以我想从模型预测中获取边界框坐标 我该怎么做呢 from ultralytics import YOLO import cv2 model YOLO yolov8n pt
  • 如何在 Python 中解析和比较 ISO 8601 持续时间? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个 Python v2 库 它允许我解析和比较 ISO 8601 持续时间may处于不同单
  • Python 2:SMTPServerDisconnected:连接意外关闭

    我在用 Python 发送电子邮件时遇到一个小问题 me my email address you recipient s email address me email protected cdn cgi l email protectio
  • Python beautifulsoup 仅限 1 级文本

    我看过其他 beautifulsoup 得到相同级别类型的问题 看来我的有点不同 这是网站 我正试图拿到右边那张桌子 请注意表的第一行如何展开为该数据的详细细分 我不想要那个数据 我只想要最顶层的数据 您还可以看到其他行也可以展开 但在本例
  • 从Python中的字典列表中查找特定值

    我的字典列表中有以下数据 data I versicolor 0 Sepal Length 7 9 I setosa 0 I virginica 1 I versicolor 0 I setosa 1 I virginica 0 Sepal
  • “隐藏”内置类对象、函数、代码等的名称和性质[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我很好奇模块中存在的类builtins无法直接访问的 例如 type lambda 0 name function of module
  • 在Python中检索PostgreSQL数据库的新记录

    在数据库表中 第二列和第三列有数字 将会不断添加新行 每次 每当数据库表中添加新行时 python 都需要不断检查它们 当 sql 表中收到的新行数低于 105 时 python 应打印一条通知消息 警告 数量已降至 105 以下 另一方面
  • pyspark 将 twitter json 流式传输到 DF

    我正在从事集成工作spark streaming with twitter using pythonAPI 我看到的大多数示例或代码片段和博客是他们从Twitter JSON文件进行最终处理 但根据我的用例 我需要所有字段twitter J
  • 加快网络抓取速度

    我正在使用一个非常简单的网络抓取工具抓取 23770 个网页scrapy 我对 scrapy 甚至 python 都很陌生 但设法编写了一个可以完成这项工作的蜘蛛 然而 它确实很慢 爬行 23770 个页面大约需要 28 小时 我看过scr
  • javascript 是否有等效的 __repr__ ?

    我最接近Python的东西repr这是 function User name password this name name this password password User prototype toString function r
  • pip 列出活动 virtualenv 中的全局包

    将 pip 从 1 4 x 升级到 1 5 后pip freeze输出我的全局安装 系统 软件包的列表 而不是我的 virtualenv 中安装的软件包的列表 我尝试再次降级到 1 4 但这并不能解决我的问题 这有点类似于这个问题 http
  • 根据列 value_counts 过滤数据框(pandas)

    我是第一次尝试熊猫 我有一个包含两列的数据框 user id and string 每个 user id 可能有多个字符串 因此会多次出现在数据帧中 我想从中导出另一个数据框 一个只有那些user ids列出至少有 2 个或更多string
  • 如何在 pygtk 中创建新信号

    我创建了一个 python 对象 但我想在它上面发送信号 我让它继承自 gobject GObject 但似乎没有任何方法可以在我的对象上创建新信号 您还可以在类定义中定义信号 class MyGObjectClass gobject GO
  • python import inside函数隐藏现有变量

    我在我正在处理的多子模块项目中遇到了一个奇怪的 UnboundLocalError 分配之前引用的局部变量 问题 并将其精简为这个片段 使用标准库中的日志记录模块 import logging def foo logging info fo
  • Python ImportError:无法导入名称 __init__.py

    我收到此错误 ImportError cannot import name life table from cdc life tables C Users tony OneDrive Documents Retirement retirem
  • Kivy - 单击按钮时编辑标签

    我希望 Button1 在单击时编辑标签 etykietka 但我不知道如何操作 你有什么想法吗 class Zastepstwa App def build self lista WebOps getList layout BoxLayo
  • 使用随机放置的 NaN 创建示例 numpy 数组

    出于测试目的 我想创建一个M by Nnumpy 数组与c随机放置的 NaN import numpy as np M 10 N 5 c 15 A np random randn M N A mask np nan 我在创建时遇到问题mas

随机推荐

  • RNN循环神经网络训练过程的matlab模拟仿真

    目录 1 算法概述 2 仿真效果 3 MATLAB仿真源码 1 算法概述 CNN 卷积神经网络 我们会发现 他们的输出都是只考虑前一个输入的影响而不考虑其它时刻输入的影响 比如简单的猫 狗 手写数字等单个物体的识别具有较好的效果 但是 对于
  • DataGrip使用

    DataGrip是JetBrains的一款数据库管理IDE 苦于现在使用的工具很不顺手 就安装了这款工具的试用版 发现功能还是很强大 JB还是很给力 下载 在官网下载DataGrip的社区试用版 地址是 https www jetbrain
  • [R语言]手把手教你如何绘图(万字)

    目录 概况 常用高级图形 条形图 csv文件导入 csv文件导出 R语言sep函数 seq函数 with函数 直方图和密度估计图 盒型图 boxplot 正态QQ图 散点图 pairs 散点矩阵图 曲线图 curve 三维图 动态三维图 低
  • 分享一个经典黑qss风格样式

    Shared QStackedWidget QLabel QPushButton QRadioButton QCheckBox QGroupBox QStatusBar QToolButton QComboBox QDialog backg
  • C语言神经网络识别手写数字,手写数字识别(0~9)基于BP神经网络算法

    博客链接 digittra txt 是训练集合 是数字图像像素值的数据项 digittest txt是测试集合 test accuracy x txt是输出的预测精度 1 文件 digitstest txt 220KB 下载 473 2 文
  • python cufflinks 绘制折线图_Python金融科技(一)cufflinks绘制金融图表

    前言 前段时间本蒟蒻发现一个功能强大的绘图工具库cufflinks 其最吸引我的地方是内置了量化金融绘图模块 可以很方便地绘制K线和技术指标图表 但遗憾的是 在网络上并没有找到cufflinks的参考手册 虽然网络上有一些介绍cufflin
  • idea前端可视化_jsp可视化开发工具_netbeans jsp可视化_idea 可视化开发 jsp

    数字生态钜惠来袭 秒杀 2核4G 5M带宽 1200元 3年 1核1G首购 99元 年 把默认改成 myeclipse jsp editor 原默认的jsp编辑器是 myeclipse visual jspdesigner 顾名思义 此编译
  • linux ALSA & ASOC(1)—— framwork

    一 ALSA framwork 涉及文件 函数 sound core sound c snd register device for dev 创建次设备 sound core init c snd card create 创建contorl
  • java自定义注解

    Java自定义注解的步骤如下123 使用 interface关键字定义注解 注解的成员参数只能是基本类型 String Class Enum Annotation或者它们的数组 使用元注解 Target Retention Document
  • chatgpt赋能python:如何用Python计算居民用电量

    如何用Python计算居民用电量 介绍 居民用电量是一个重要的经济指标 对于一个家庭来说 如果能够掌握自己的用电量情况 不仅可以控制开支 还可以提高用电效率 节约能源 而对于电力公司来说 了解居民用电量的变化规律 可以更好地调节电力供给 提
  • tomcat设置线程数

    查看Tomcat线程数 1 Tomcat默认线程数200 2 修改server xml文件 增加maxThreads minSpareThreads maxSpareThreads acceptCount 3 参数解释 maxThreads
  • 股指期货的基差为负值说明什么(股指期货的基差为负值说明什么问题)

    期货基差低于全年基差是什么意思 简单说期货基差的意思就是现阶段某个期货价格和现货价格之间的差价 基差 现货价格 期货价格 基差为负值 说明现货过多 此时现货价格小于该商品的期货价格 基差为正值 说明当市场商品供应出现短缺 供不应求时 现货价
  • AD20/Altium designer——如何从立创EDA获取元器件封装库原理图库PCB库

    1 打开并登录立创EDA 找到需要的元器件 2 导出原理图 PCB封装文件 1 导出原理图封装 2 导出PCB封装 与上述导出方法同理 2 打开AD20软件 1 新建原理图库和PCB元件库 2 将刚下载的文件拖入AD内打开 3 复制白嫖元器
  • 使用vsomeip遇到的一些问题

    1 接口设计 在编写fdepl文件时 要先写attribute 在写method 再写broadcast 不能像fidl文件 穿插着写 否则编译不过 2 在运行程序时 有时候会遇到无法连接的问题 需要把 tmp vsomeip 0 这一系列
  • 宏定义中有浮点数_算法笔记

    2 9 2浮点数的比较 由于计算机当中采用有限位的二进制编码 因此浮点数在计算机当中的存储并不总是精确地 例如在大量的计算以后 一个浮点类型的数3 14在计算机当中可能存储成3 1400000000001 也有可能存储成3 13999999
  • 动态NFT的构建、部署和出售

    原文地址 NFT是只有在区块链领域里才存在的工具 有着广泛的应用和机遇 ERC721代币标准可以构建收藏品 独立代币 票据 游戏等多种应用 对于那些想要参与构建的开发者来说 一个动态和随机的NFT是一个很好的开始 但我们现在可以用它做什么
  • 【机器学习实战】11、利用SVD简化数据

    文章目录 14 1 1 隐形语义索引 14 1 2 推荐系统 14 2 矩阵分解 SVD矩阵分解 14 3 利用python实现SVD 14 4 1 相似度计算 14 4 2 基于物品的相似度还是基于用户的相似度 14 4 3 推荐引擎的评
  • 【数据挖掘】数据清洗

    什么是数据清洗 数据清洗是指发现并纠正数据文件中可识别的错误的最后一道程序 包括检查数据一致性 处理无效值和缺失值等 与问卷审核不同 录入后的数据清理一般是由计算机而不是人工完成 数据清洗的步骤 缺失值的处理 无效值的处理 统一规格 纠正错
  • 断点续传与差分升级

    断点续传的原理 基于STM32单片机的差分升级 增量升级 算法 OTA 差分升级 云端一体化差分升级 AliOS Things物联网升级 利器 详解STM32在线IAP升级 单片机差分升级算法 STM32 M0 M3 M4等芯片都适用 Al
  • 【DICOM医学影像1】数据格式存储于显示,基本知识科普指南

    DICOM Digital Imaging and Communications in Medicine 数据格式 是医学影像存储中的标准格式 无论是X光 CT 还是MRI等等影像 采集的原理不同 但是存储的格式一般都是统一的 本文就对DI