Dicom全称是医学数字图像与通讯,这里讲diocm格式文件的解读,读取本身是没啥难度的 无非就是字节码数据流处理。只不过确实比较繁琐。 整体结构先是128字节所谓的导言部分,跳过就是了,接着就是四个字节组成的字符串,然后是dataElement元素依次排列的方式, 就是一个dataElement接一个dataElement的方式排到文件结尾.我们要读取dicom里面的各种数据就是在各个数据元素中。通俗的讲dataElement就是指tag,就是破Dicom标准里定义的数据字典,每个dataElement中的tag决定自身或整个文件的某些数据类型或自身dataElement内容类别。 一.标记tag(2字节UInt16分组号和2字节UInt16元素号);tag是4个字节表示的 前两字节是组号后两字节是元素号 比如0008(组号) 0018(元素号)。 一般我们获取dataElement中的数据的主要组号0002组描述设备通讯,0008组描述特征参数,0010组描述患者信息,0028组描述图像信息参数 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的元素结构
组号和元素号组成tag,上面的数组表示给类型占有的字节长度 2.显示VR:VR为普通类型时元素结构(少了预留那一行)
3.隐式VR时元素结构(也就是dataElement中没有VR这个值)
上面三个表格是从网上获取来的,我在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文件,查看数据效果: 二.值表示法VR- Value Representation(2个单字节Char);怎么理解VR呢,VR其实就是表示一种类别,表示的是该dataELement的类别。 dicom的VR类型详解:http://blog.csdn.net/wenzhi20102321/article/details/75127140 数据内容的存储与表现格式与VR是关联的,但比较恶心的是,VR不是一定存在,也就是可能有隐式的情况(需要根据元素标识进行判断),此外VR的属性还可能是UN(Unknown)等等等等。当然除非你要自己写解析,否则了解到这就可以了。dicom文件中的全体数据必须具有相同的数据结构。 VR和Tag还是很有关联的。 三.长度VL-Value Length(2字节UInt16,有些情况是4字节UInt32)数据长度:所有DICOM数据元素都应该为偶数长度,若为奇数,追加空格或空NULL 四.值VF-Value Field(如果VL=0xFFFFFFFF,则需要一直读到截止符)。值是整个dataElement里面数据的表现形式,如:用户名,年龄,性别等等数据,当然,图像字节的数据也在对应的VF里面,但是表现不出来。 整理根据以上的分析相信解析一个dicom格式文件的过程已经很清晰了吧 第一步:跳过128字节导言部分,并读取”DICM”4个字符 以确认是dicom格式文件 第二步:读取第一部分 也就是非常重要的文件元dataElement 。读取tag 并根据0002,0010的值确定dataElement的VR是显式还是隐式和dataElement的传输语法。 其他一个字节是八位,这是固定的。 比如java代码, 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(); } } }123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 程序运行后效果: 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 共勉:其实所有人都是一样的,不管你是否有很多钱,或有多健康。 |
|