可以看到都从0028 group开始描述图像信息,讲述应该如何去阅读pixel,最终以7fe0,0010的地方开始存放PixelData,上面的是uncompressed file即未压缩的。

下面这张图是compressed JPEG格式(压缩版)

可以看到未压缩和压缩的一些细小差异:

  • Photometric Interpretation(光度解释) - 压缩的用的是YBR_FULL_42, 未压缩的就是RGB
  • PixelData - 压缩用的是201个sequence来解释,而未压缩的就是一系列简单的字节数组

下面我们来具体看看整个group 0028的一些概念属性介绍:

  • Rows / Columns - Rows(0028,0010)定义了图像的height(Y),Columns(0028,0011)定义了图像的width宽度(X),在我们上面的这个例子了每个frame帧都是1280*960个pixels
  • Samples Per Pixel - 定义了对应的颜色通道个数,对于灰度图像Grayscale来说,比如CT或者是MR,只需要设置为1,因为只需要单一灰度通道。对于彩色图像来说,以我们这个例子他就是3个颜色通道分别为Red,Green,Blue
  • Photometric Interpratation - 对于DICOM来说是独一无二的。他定义了每个color channel具体hold了什么概念属性,比如拿我们最上面的未压缩的版本来说,这里的解释是“RGB”,也就意味着第一个channel是Red,第二个是Green,第三个是Blue. 对于灰度图像来说一般是MONOCHROME2, 定义了他的灰度和0应该对应成Black黑色。 在一些fluoroscopic image(荧光镜)来说,可能这个值是为"MONOCHROME1",表示grayscale和0在这里对应的是White. 另外一些取值可能是"YBR_FULL"或者"YBR_FULL_422"表示color channel在YCbCr颜色空间(在JPEG中)
  • Planar Configuration - 定义了color channels应该以何种方式放置在pixel data buffer中。只有你的Sample Per Pixel > 1才有意义(color images).如果取值是0,表示是RGB的交错排列,如果是1,就表示他会分别把Red,Green,Blue依次存放,注意,这里分开存放的方式其实很少,一般出现在RLE的图像压缩算法中。下面的图片详细的解释了两种分别的情况
  • Bits Allocated, Bits Stored, High Bit - 大多数的toolkits基本都会帮你自动去提取以及组织对应的pixels.如果你想通过你自己来动手,你就需要依托这三个属性并且保证对应的大小端字节序的问题。
  • Bits Allocated(0028,0100) - 对于每一个Sample(参考Samples Per Pixel),比如RGB中的R或者G或者B,或者Grayscale中的灰度来说,一般每个Sample都是8bit(1 byte),即RGB就是24bit.这也是基本最标准的图像格式,每个channel被申请8bits. 这个情况带来的好处是sample可以字节对齐。基本所有的DICOM objects都会使用完整的字节来做申请,因此要么对于灰度来说你是8或者16(1或者2字节)来显示大于等于256灰阶Bits Stored(0028,0101) - 定义了你真正需要使用的位的个数。在我们的例子中,因为每个sample都是介于0~255,8位都被使用,因此我们的这个属性就是8.但是对于CT图像来说,每个sample实际上是介于0~4095(2的12次方是4096),通过上面的Bits Allocated我们知道会基于字节对齐,因此这里实际上会申请16位,那么多下来的4位就是多余的。因此在读取pixel values的时候,这些bits需要被遮盖。当然有些时候,这些bits会被当做overlay planes dataHigh Bit(0028,0102) - 定义了bits如何在allocated的内存中的对齐方式。是最后一个有效bit的个数,比如在8 bits中他是7,在CT(12bits)中他是11.下面这张图是标准中介绍pixels是如何按位排布的
  • Pixel Representation - 要么是unsigned的0,要么是signed的1.默认情况下是unsigned - 0.默认是unsigned, 注意VR中US和SS就分别代表了unsigned和signed.如果设置为signed,那么所有group 0028的属性都要被编码成Signed Shorts(ss),如果是unsigned,那么就变encoded成Unsigned(US)
  • Number of Frames - (0028,0008)交代了在这个image中有多少帧。通常来说都只有1个,因此这个element可以被省略。但是在DICOM中他支持你创建multi-frame多帧图像,因此你需要设置这个element,来表示多帧,在我们这个例子中可以看到我们设置了200帧频

以上为整个图像属性group 0028的介绍,下面开始讲图像属性本身 - Pixel Data,首先可以看到他所在的组并不是0028,而是7FE0,这个需要特别注意,这其实有2个好处:

  1. 他是一个非常长的element,一个比较好的方案就是把他放在整个DICOM element的最后一个,对于整个数据结构的合理性也是一个不错的解释
  2. 对于那些DICOM viewer软件来说,有些时候由于Pixel Data过于庞大,可能我们只需要去scan对应的header比如group 0028而不想过渡浪费内存空间去加载图像,这个情况下我们就可以停止阅读group 0028之后的element来达到节省内存空间

Pixel Data - (7FE0,0010),具体存放图像的数据,首先让我们来计算一下图像的长度,所有的参数我们都已经获得.我们拥有1280*960个pixel每帧,同时我们有200帧,并且每个pixel我们有3个samples color channel,每个sample表示一个字节,于是我们可以得到整个pixel data的长度为

ROWS * COLUMS * NUMBER_OF_FRAMES * SAMPLE_PER_PIXEL * (BITS_ALLOCATED/8) = 1280*960*200*3*8/8 = 737280000字节,将近720MB.注意在设置VR的时候,可以有OB和OW,都表示binary type,但是对于CT图像来说,每个sample都保存为2个字节,因此我们需要用OW这个VR来指示对应的toolkit作为数据存放的参考。

16位灰度数据成像_DICOM Pixel Data核心图像信息数据介绍相关推荐

  1. 【Android实现16位灰度图数据转RGB数据并以bitmap格式显示】

    Android实现16位灰度图数据转RGB数据并以bitmap显示(单通道Gray数据转三通道RGB数据并显示) 需求 发现问题 解决方案 需求 问题需求:项目上需要实现将深度相机传感器给出的数据实时 ...

  2. java读取16位深png_读取16位灰度TIFF

    我正在尝试使用小型C程序读取16位灰度TIFF文件(BitsPerSample = 16),以转换为浮点数数组以供进一步分析 . 根据 Headers 信息,像素数据在2048×2048像素的单个条带 ...

  3. 16位灰度数据成像_16位 250M双通道PCI数据采集卡 FCFR-PCI9808

    FCFR-PCI9808 16位 250M双通道PCI数据采集卡FCFR-PCI9808(简称PCI9808)是PCI接口高速高精度数字化仪,双通道同步采集,PCI9808A指标:16位,双通道采样率 ...

  4. 读写EEPROM遇到的问题:16位地址的内容都是最后写入的数据。

    #define EE_TYPE AT24C64 如下图所示,往EEPROM的地址0x1000.0x1001.0x1002和0x1003分别写入0xAA.0xBB.0xCC和0xDD,读出来的数据都是最 ...

  5. arduino i2c 如何写16位寄存器_基于STM32使用I2C读取传感器数据

    撑腰会儿:I2C通信协议介绍​zhuanlan.zhihu.com 上文介绍了I2C协议的基本结构,今天,使用STM32和LM75A温度传感器来实现I2C读取信息. 首先,为了使用I2C读取传感器测量 ...

  6. matlab 16位灰度值转8位,在matlab中如何将灰度值为24位的转化为8?

    我使用的是Visual c++6.0技术内幕里提供的类CDib来操作位图,最好提供可以两个独立的函数来分辨别实现着俩个功能.他们可以作为CDib类的成员函数来使用.类似下面的这个就可以,我用了下面的这 ...

  7. 王爽 16 位汇编语言学习记录

    以下为汇编学习记录,内容全部出自王爽的16位<汇编语言>,如有错误,可直接去查看原书. 汇编语言   机器语言是机器指令集的集合,机器指令是一列二进制数字,计算机将其翻译成高低电平,从而使 ...

  8. 【汇编语言】16位汇编总结

    16位汇编语言 学习操作系统前对汇编语言进行快速学习,参考汇编语言进行总结. Before Learning 进制: 字节和字: 字节,即Byte,是由八个位组成的一个单元,也就是8个bit组成1个B ...

  9. R语言data.table导入数据实战:把data.frame数据转化为data.table数据

    R语言data.table导入数据实战:把data.frame数据转化为data.table数据 目录 R语言data.table导入数据实战:把data.frame数据转化为data.table数据 ...

  10. 使用opencv将16位深度图转灰度图

    使用opencv将16位深度图转灰度图,默认深度图每个像素以uint16_t来保存. #include <string> #include "opencv2/core/core. ...

最新文章

  1. DvaJS 入门, 快速上手Dva
  2. 机器学习框架_一个框架解决几乎所有机器学习问题
  3. IE8的项目在IE11下 一些功能无法实现的解决方案
  4. symbol MC 3090 upgrade to symbol MC 3190
  5. 在Mapnik中显示中文(网上资料整理)
  6. C语言 | 结构体数组
  7. vivo S10系列官方渲染图公布 外壳太好看了!
  8. TensorFlow tf.keras.layers.Lambda
  9. Char05 Ansible 最佳实践
  10. 场景文字检测——CTPN模型介绍及代码实现
  11. [Scala]正则表达式——去除特殊字符,只保留中英文和数字以及下划线
  12. Java桶排序LSD
  13. 基于 Stable Diffusion 一键 AI 作画:什么“小镇做题家”?人人都是艺术家
  14. tensorflow计算flops
  15. 使用java搭建简单的ligerui环境
  16. 用MFC做漂亮界面之美化对话框
  17. R中报错:Error :$ operator is invalid for atomic vectors
  18. openssl bio
  19. QComboBox下拉选择框
  20. 若某非空二叉树的先序序列和后序序列正好相反,或者正好相同,则二叉树形态是怎么样的?

热门文章

  1. 首个应用到大规模真实工业场景的神经网络控制系统在谷歌上线了
  2. 深圳安全研讨会圆满结束,PPT共享下载
  3. C# 线程同步 信号量 Semaphore
  4. java 阻塞队列 BQ_Java Concurrency in Practice 读书笔记 第六章
  5. 3. 什么是icmp?icmp与ip的关系_0.3亿人口的美国会比3亿人口的美国富裕吗?
  6. 高中女销售学Linux云计算4个月搞定年薪12万
  7. Debian 鼠标左右手
  8. fisher criterion
  9. Android 日历提供器(一)
  10. 关于String内存分配的深入探讨