dicom文件解析

Dicom全称是医学数字图像与通讯,这里讲diocm格式文件的解读,读取本身是没啥难度的 无非就是字节码数据流处理。只不过确实比较繁琐。
dicom中文协议文档:http://download.csdn.net/download/wenzhi20102321/9897014
dicom文件结构:

整体结构先是128字节所谓的导言部分,跳过就是了,接着就是四个字节组成的字符串,然后是dataElement元素依次排列的方式, 就是一个dataElement接一个dataElement的方式排到文件结尾.我们要读取dicom里面的各种数据就是在各个数据元素中。通俗的讲dataElement就是指tag,就是破Dicom标准里定义的数据字典,每个dataElement中的tag决定自身或整个文件的某些数据类型或自身dataElement内容类别。
其中tag和VR是要重点理解,也是比较难理解的!

一.标记tag(2字节UInt16分组号和2字节UInt16元素号);

tag是4个字节表示的 前两字节是组号后两字节是元素号 比如0008(组号) 0018(元素号)。
我们获取dicom里面的数据,就是根据tag,来知道这个dataElement里面是否是我们需要的数据,然后读取该dataElement里面的数据。

一般我们获取dataElement中的数据的主要组号

0002组描述设备通讯,0008组描述特征参数,0010组描述患者信息,0028组描述图像信息参数
还是有很多其他组号的,但是里面的数据不常用到,tag总共大约有2000个,但是我们常用的数据就那么几个!

dicom文件数据中所有dataElement从前到后按tag又可简单分段:文件元tag,普通tag,像素tag。

1.文件元tag(组号+0000):不受传输语法影响,总是以显示VR方式表示,因为它里面就定义了传输语法;文件元tag的dataElement,并没有多大的意义,它的VF数值是整个组所有dataElement的字节长度,一个dicom中可以只有一个文件元tag,也可以有多个文件元tag。

2.普通tag:除了文件元tag和像素tag,其余的都是普tag数据。包括:图像宽,高,数据传输格式,病人姓名,病人生日,病历医院,病历科室,病情的描述等等数据;

3.像素tag(7fe0,0010):表示dataElement存储的是病历的图像数据。

上面这段话,信息量其实是很多的,比如什么是显示VR、隐式VR,传输语法又是怎么回事?VR请往下看,传输语法一两句话是说不清楚的!

tag的dataElement结构,分为下面三种:

1.显示VR:VR为OB OW OF UT SQ UN的元素结构

组号 元素号 VR 预留 值长度 数据元素值
2 2 2 2(0x00,0x00) 4 由数据长度决定

组号和元素号组成tag,上面的数组表示给类型占有的字节长度

2.显示VR:VR为普通类型时元素结构(少了预留那一行)

组号 元素号 VR 值长度 数据元素值
2 2 2 4 由数据长度决定

3.隐式VR时元素结构(也就是dataElement中没有VR这个值)

组号 元素号 值长度 数据元素值
2 2 4 由数据长度决定

上面三个表格是从网上获取来的,我在dicom协议中没有看到具体的介绍,也不知怎么验证正确性!
暂时先按照上面的理解,有问题再去思考吧。

dicom文件的所有传输语法(区分显式/隐式VR,litter字节/bie字节):

最关键的两个tag:

1.tag:0002,0010,决定普通tag的读取方式 little字节序还是big字节序,隐式VR还是显示VR。由它的值决定

2.tag:7fe0,0010,像素数据开始处

dicom文件的tag详解:

http://blog.csdn.net/wenzhi20102321/article/details/75127101

使用工具snate DICOM打开dicom文件,查看数据效果:

工具下载地址,下载后直接用:http://download.csdn.net/download/wenzhi20102321/9895616
上面图片每一行数据就是一个dataElement数据,可以看到tag值,VR值,VL值,VF值。
但是一般工具也是看不到图像的tag数据,因为他的VF数据有几万个字节,怎么显示!

二.值表示法VR- Value Representation(2个单字节Char);

怎么理解VR呢,VR其实就是表示一种类别,表示的是该dataELement的类别。
VR,类似于java的String,Long,VR有LO(LongString长字符串),IS(IntergerString整形字符串),DA(data日期)等等共27中类型。

dicom的VR类型详解:

http://blog.csdn.net/wenzhi20102321/article/details/75127140

数据内容的存储与表现格式与VR是关联的,但比较恶心的是,VR不是一定存在,也就是可能有隐式的情况(需要根据元素标识进行判断),此外VR的属性还可能是UN(Unknown)等等等等。当然除非你要自己写解析,否则了解到这就可以了。dicom文件中的全体数据必须具有相同的数据结构。

VR和Tag还是很有关联的。
我们知道tag是有很多的,大概2000个,也就是说有2000种tag。
但是VR只有27种。
每一种Tag其实是有一个固定的VR类型,也就是说不同的dicom文件他的同一个tag,VR肯定也是相同的。
但是,不同的tag可能对应同一个VR类型。这就类是于java中的姓名和身份证号码都是String类型的。

三.长度VL-Value Length(2字节UInt16,有些情况是4字节UInt32)

数据长度:所有DICOM数据元素都应该为偶数长度,若为奇数,追加空格或空NULL
得到这个VL的数值大小就知道这个dataElement的字节长度。

四.值VF-Value Field(如果VL=0xFFFFFFFF,则需要一直读到截止符)。

值是整个dataElement里面数据的表现形式,如:用户名,年龄,性别等等数据,当然,图像字节的数据也在对应的VF里面,但是表现不出来。

整理

根据以上的分析相信解析一个dicom格式文件的过程已经很清晰了吧

第一步:

跳过128字节导言部分,并读取”DICM”4个字符 以确认是dicom格式文件

第二步:

读取第一部分 也就是非常重要的文件元dataElement 。读取tag 并根据0002,0010的值确定dataElement的VR是显式还是隐式和dataElement的传输语法。

其他

一个字节是八位,这是固定的。
机器语言都是二进制(0,1)的数据保存和读取;
一个字节byte就是有八位,比如:0001 0100
但是我们数据的读取都是读取字节byte的,比如前面说的128字节,说的就是128个byte数据
后面四个字节,就是4个byte,这四个字节是可以组成字符串“DICM”
接着就是四个字节的tag,但是这四个字节的tag不能组成字符串
上面说到一个字节是8位,前面四位范围是0000-1111,后面也一样,正好是0到15.
所以一个字节用16进制可以表示为0x00-0xff.同二进制00000000-11111111是一样的。
比如我们看到tag:0020 0010,其实是0x00200010,16进制的!
第一个字节为:0x00
第二个字节为:0x20
第三个字节为:0x00
第四个字节为:0x10
再验证下上面那句话,一个字节8位,所以用一个16进制的数值表示4位,两个16进制的数值就表示8位了!
所有tag四个字节,为啥是8个数值表示!

比如java代码,
读取到dicom的DICOM字符串和第一个:Tag值,VF值

public class ImageDemo {public static void main(String args[]) {getData("D:\\dicom\\test1.dcm");}/*** 读取dicom文件字节流数据看看*/private static void getData(String filePath) {System.out.println("解析文件:" + filePath);File file = new File(filePath);try {FileInputStream is = new FileInputStream(file);//跳过128个字节is.read(new byte[128]);//读取4个字节,要把这四个字节转变成字符串才能看到“DICM”byte[] buf = new byte[4];is.read(buf);String msg_DCM = new String(buf);System.out.println("跳过128后面的四个字节,字节1:" + buf[0] + ",字节2:" + buf[1] + ",字节3:" + buf[2] + ",字节4:" + buf[3]);System.out.println("跳过128后面的四个字节组成的字符串:" + msg_DCM);System.out.println(" ");//获取第一个tag的四个字节is.read(buf);String msg_Tag = new String(buf);System.out.println("Tag的四个字节,字节1:" + buf[0] + ",字节2:" + buf[1] + ",字节3:" + buf[2] + ",字节4:" + buf[3]);System.out.println(" ");//获取第一个VR的两个字节byte[] buf2 = new byte[2];is.read(buf2);String msg_VR = new String(buf2);System.out.println("VR的两个字节,字节1:" + buf2[0] + ",字节2:" + buf2[1]);System.out.println("VR的两个字节组成的字符串:" + msg_VR);System.out.println(" ");//获取第一个VL的四个字节is.read(buf);String msg_VL = new String(buf);System.out.println("VL的四个字节,字节1:" + buf[0] + ",字节2:" + buf[1] + ",字节3:" + buf[2] + ",字节4:" + buf[3]);System.out.println("VL的四个字节组成的字符串:" + msg_VL);System.out.println(" ");//获取第一个VF的四个字节is.read(buf);String msg_VF = new String(buf);System.out.println("VF的四个字节,字节1:" + buf[0] + ",字节2:" + buf[1] + ",字节3:" + buf[2] + ",字节4:" + buf[3]);System.out.println("VF的四个字节组成的字符串:" + msg_VL);System.out.println(" ");} catch (Exception e) {e.printStackTrace();}}}

程序运行后效果:

上面图片标记错了,第一个tag应该是:0002 0000
使用工具查看这个文件,第一个数据也是,这个tag数据:

dicom传输的相关知识也只能介绍到这里,上面很多知识还没有理解透彻,只是把这些知识罗列出来,给大家参考一下!

dicom文件解析知识的其他地址:

1.dicom文件详解

http://blog.csdn.net/wenzhi20102321/article/details/75127362

2.dicom文件的值类型VR详解

http://blog.csdn.net/wenzhi20102321/article/details/75127140

3.dicom文件tag详解

http://blog.csdn.net/wenzhi20102321/article/details/75127101

4.android 解析并显示dicom文件的数据和图像

http://blog.csdn.net/wenzhi20102321/article/details/75040225

5.java代码使用ImageJ解析dicom文件成图片

http://blog.csdn.net/wenzhi20102321/article/details/74995084

前面5个是我自己写的,后面是一些我自己看过的相关资料:

6.Dicom文件解析

http://blog.csdn.net/leaf6094189/article/details/8510325

7.使用dcm4che3获取Dicom的bmp格式缩略图

http://blog.csdn.net/Kerrigeng/article/details/60866656

8.使用dcm4che3解析DICOM中,中文乱码问题

http://blog.csdn.net/Kerrigeng/article/details/53942846

9.使用dcm4che3对jpeg压缩的dcm文件进行解压

http://blog.csdn.net/Kerrigeng/article/details/62215647

10.DICOM的常用Tag分类和说明

http://www.cnblogs.com/stephen2014/p/4579443.html

11.dicom的大牛zssure的博客,几十篇文章

http://blog.csdn.net/zssureqh/article/category/1389985

12.dicom协议中文文档下载

http://download.csdn.net/detail/wenzhi20102321/9897014

13.Sante DICOM Editor 4,查看dicom文件的工具,直接打开用

http://download.csdn.net/detail/wenzhi20102321/9895616

共勉:其实所有人都是一样的,不管你是否有很多钱,或有多健康。

dicom文件详细解析相关推荐

  1. 一、STM32启动文件详细解析

    一.STM32启动文件详细解析 STM32启动文件详细解析(V3.5.0) 以:startup_stm32f10x_hd.s为例 [cpp] view plain copy ;************ ...

  2. Realview MDK 链接脚本文件详细解析(一)–链接符号

    Realview MDK 链接脚本文件详细解析(一)–链接符号 Realview MDK 链接程序使用了两种方式控制程序的链接,即链接控制命令选项和链接脚本文件 链接脚本文件 链接脚本文件类型一般为: ...

  3. FPGA开发技巧:Modelsim仿真.do文件详细解析 原创 特权同学

    FPGA开发技巧:Modelsim仿真.do文件详细解析 原创 特权同学 FPGA快乐学习 以<FPGA边码边学 视频教程>"Lesson06 分频计数器设计"中的si ...

  4. C/C++ 语言中.h文件和.c文件详细解析 引用 .c和.h文件的区别

    参考:http://blog.csdn.net/wuan584974722/article/details/30362405 简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编 ...

  5. linux下分析cel文件,详细解析Linux scp命令的应用

    采用scp命令在Linux系统之间copy文件 不同的Linux之间copy文件常用有3种方法,第一种就是ftp,也就是其中一台Linux安装ftp Server,这样可以另外一台使用ftp的clie ...

  6. STM32之启动文件详细解析(V3.5.0)

    启动文件么,就是进入main函数(其实可以在本文件中改成别的,即替换"_main"为你想改的"_XXXX"即可)之前干的一些事--- 来看看ARM在进入的&qu ...

  7. ENVI_IDL:读取OMI数据(HDF5)并输出为Geotiff文件+详细解析

    目录 1. 课堂内容 2. 知识储备 3. 编程 1. 课堂内容 读取OMI数据(HDF5)并输出为Geotiff文件,最重要的是数据的处理以及输出 这里我个人觉得难度不大, 第一,获取OMI文件的N ...

  8. DICOM:由fo-dicom库解析DICOM文件引申出来的……

    题记: 近期收到不少博友的邮件或私信,有刚入门者,来信咨询DICOM协议基础知识的:也有同行咨询如何开发DICOM服务器,如何选用dcmtk.dcm4che.fo-dicom等开源库:还有一部分是医疗 ...

  9. java代码使用ImageJ解析dicom文件成图片

    ImageJ解析dicom文件成jpg图片 Dicom全称是医学数字图像与通讯,这里讲java解析diocm格式文件变成jpg示例. 这里的代码只能解析普通的dicom文件成jpg图片,对于压缩的di ...

最新文章

  1. pandas使用groupby函数计算dataframe数据中每个分组的N个数值的滚动加和(rolling sum)、例如,计算某公司的多个店铺每N天(5天)的滚动销售额加和
  2. 解决hal.dll丢失问题 调试方法启动XP
  3. 网易云音乐网络库跨平台化实践
  4. 多少行数_经验丰富的程序员和其每日代码行数
  5. 星宿UI V1.1-后台优化激励视频判断插件
  6. Android Studio增加assets目录、raw目录
  7. redis应用之——获取若干最新注册用户
  8. 【高级编程技术作业】第六周
  9. 数据结构--------二叉排序树
  10. python模拟别人说话的声音传得最远_谁说话的声音传得最远脑筋急转弯的答案是什么...
  11. 使用netmeeting进行网络培训
  12. 解决websocket链接失败防火墙规则问题
  13. 中文信息杂志中文信息杂志社中文信息编辑部2022年第6期目录
  14. 小白学习Java第七天
  15. 站内信“数据库设计思路”
  16. 测试眉形的有哪个软件_适合眉毛的软件
  17. 第一章 初识JVAV
  18. Python 分析电影《南方车站的聚会》
  19. 大数据是让人幸福的科学
  20. rabbitMq设置多线程并设置线程池消费处理

热门文章

  1. 歌曲:我愿爱(tvb台庆剧插曲)
  2. CVPR2016 论文快讯:人脸专题
  3. sd卡照片清除用什么软件可以找回
  4. Cannot access ‘androidx.lifecycle.HasDefaultViewModelProviderFactory‘ which is a supertype of ‘com.e
  5. 「游戏」游戏服务器中AOI的原理及四叉树实现
  6. 全球与中国生物气溶胶监测仪市场深度研究分析报告
  7. NVIDIA VIDEO CODEC SDK开发资源下载
  8. C++-顺序栈实现10进制转换为2、8、16进制(详细)
  9. 如何利用链接诱饵来为网站获取强大的流量?
  10. FZU 2181 快来买肉松饼(dfs)