DICOM二进制文件解读的VC++实现
The analysis and reading of DICOM’s binary file with VC+ +
冯辉
(大连北洋医疗装备总公司 辽宁大连 116o2])
【关键词】医学影像;二进制;标签;字节;像素
中图分类号:R443.8 文献标识码:B 文章编号:1006—9011(2003)0r7—0538—01
DICOM(cugit~.瑚a and coramunieation On medicine)文件为
医学影像的专用存储格式,后缀为.dcm,在CT、磁共振、医院
PACS系统中应用广泛。一般的读图软件无法支持这一图像
格式。在了解DICOM文件格式的基础上,编程实现其二进
制文件的读写,在医学影像领域是一个有普遍意义的题目。
笔者在WIN2000的操作系统下,采用VC++6.0编程实现
其在屏幕上的显示。写下此文,希望能起到抛砖引玉与同行
交流的作用。
将文件后缀.dem改为.cpp后,可以用VC读出其二进制
内容,为了显示方便,文件采用十六进制显示,即一个十六进
制位代表4个二进制单位(bit),一个字节(byte)由2个十六
制位构成,比如08 oo oo 1O表示4个字节的信息。
介绍一下DICOM文件中最重要的概念一标签(tag)结
构:DICOM文件中标签是提供有关图像信息的单位,一般占
用4个字节的空问,标签后面紧跟的4个字节表示标签的内
容所占的字节数(N),再后面的N个字节所表示的值才是标
签的实际内容(这3部分称为标签单元)。在隐式VR结构
中。标签单元的构成如下:
Tag Value(1ength) Value Field
(4 bytes) (4 bytes) (1e~.th bytes)
举个例子,假如有如下的一段代码 垫 !Q
02 oo oo oo 02 O1其中,oo 28 oo 1O为标签,02 oo oo oo表示
它后面的2个字节为标签的实际内容,02 Ol即为标签的值o
DICOM文件中主要的标签有如下几个:
Rows:(0,002S~10) 图像的行数
Columns:(0x002S0011) 图像的列数
Bits Allocated:(0x002S0100) 表示每个像素的位数(bit)
Bits Stored:(o~ty2solo1) 像素的有效位数
Bits High:(0x00280102) 有效位数的最高位
fOx7聊0010) 标志像素数据的起始位置
538
那么,如何用VC实现标签的查找呢?主要解决的问题
是4个字节的“读”和逐个字节的“找”之间的矛盾。下面给
出具体的思路:
①用open()函数打开文件;②用Read()函数读出4个字
节,但注意此时的指针已经移到了第4个字节。如果继续读
下去,就成了每4个字节读一次,这样肯定找不到所需的标
签,因为标签单元的长度并不一定是4的整数倍。所以必须
实现逐字节查找;③用Seek()函数反向定位3位,即可实现
上述目的;④注意循环结束时,再用sed.()函数将指针恢复
原位。因为最后一次循环,指针还向前移动了3位;⑤查找
到标签后,读出后面的4个字节(结果为数值N),然后再读出
接着的N个字节,即得到标签的实际内容;⑥DICOM文件中
存在一个字节换位的问题,即高两个字节与低两个字节换位
存储,例如要查找标签O0280010,实际应查找00100028。
用以上方法可以找到你所需要的任何标签,具体每个标
签的含义可参见DICOM的文档。
读出标签,得到所需的信息,并通过(Ox7聊oo1O)定位
好像素数据的起始点后,怎样显示到屏幕上呢?笔者采用了
SetR ()函数,逐像素绘制图像。这是绘图中最基本的操
作,但开销过大。朋友们可考虑其它方法。
DICOM文件中,像素数据的存储为从左至右,从上至下。
像素数据的结构由以下的三个标签值来说明,举例说明:
①Bits Al】Dc8t甜:f6表示每个像素由16bit表达,即2个字
节;②Bits Stored:10像素的有效位数为1O位,高六位有其它
用途:③Bits High:9有效位数的最高位为9,即0到9共1O
位。
知道了标签的含义,处理起来就简单了:每次读出2个
字节,去掉高6位,灰度图RGB分量相等,即可显示图像了。
当然还有后续的各种处理,在此就不再赘述了。
DICOM文件的数据结构有很多种,本文介绍的只是其中
最简单的隐式vR结构,标签也有许多。另外,像素数据的高
位还含有特定信息,不可轻易舍弃。在此,只是给出一个简
单的思路,希望能对大家有所启发。
(收 |
|