dicom格式文件 界定标识符的处理
2015-07-30 10:47
274 查看
转自:/article/6019810.html
说到底无非几个事情 :
1传输语法确定
2数据元素读取
3 7fe0,0010元素 也就是图像数据处理。
关于这整个过程已经不想多说了 在我的上上一篇博客里已经基本实现了。 当然还很有问题比如图像调窗就有bug 这个以后再说吧。众所周知dicom格式文件是由一个接一个连续的“数据元素”组成的。
这次我们只讲怎样去处理文件里一种特殊的数据元素:那就是VR为SQ类型的元素 还有delimited 也就是界定标识付 我们暂且把它归为一类。 为什么特殊呢?因为其他元素都很简单 ,根据传输语法:-> tag_有无显式VR_len_VF 这样的结构。 len是数据长度, VF是固定字节数的字节流数据。 而遇到SQ类型的数据元素就麻烦了 首先他的len是FFFFFFFF 就是无长度。然后是VF 他是一种“文件夹”结构 ,就是里面嵌套其他数据元素,可能嵌套一层 可能嵌套几层 处理是很棘手的问题。
说了这么多我们先来直观的看一下 找到我们上一篇文章《Dicom格式文件解析器》打开测试数据IM-0001-0002.dcm 看到tag数据里有很多类似这样的:
0040,0275SQ
0040,0275(SQ):00
--fffe,e000(**):
--0040,0007(LO):CT2 t阾e, face, sinus
----0040,0008(SQ):00
------fffe,e000(**):
------0008,0100(SH):CTTETE
------0008,0102(SH):XPLORE
------0008,0104(LO):CT2 T蔜E, FACE, SINUS
------fffe,e00d(**):
----fffe,e0dd(**):
----0040,0009(SH):A10011234815
----0040,1001(SH):A10011234814
--fffe,e00d(**):
fffe,e0dd(**):
事先已经知道VR是显式方式的explicit VR 字节序是little edition,这里只是测试 那么我们直接就在处理代码class的变量里写死了:
View Code
这种解析跟数据组织方式 更方便了dicom数据对象的处理 。我这讲讲当然很简单 看上去很容易的样子 ,因为我已经亲手一行代码一行代码的实现了。 代码很多请同学们 仔细阅读每一个细节 他们之间的调用关系及逻辑。很多地方我没讲到 为了限制篇幅其实有很多与重点部分无关的代码贴出来的时候我已经删除了,但是源码文件里有。
源码及测试数据下载猛击此处
说到底无非几个事情 :
1传输语法确定
2数据元素读取
3 7fe0,0010元素 也就是图像数据处理。
关于这整个过程已经不想多说了 在我的上上一篇博客里已经基本实现了。 当然还很有问题比如图像调窗就有bug 这个以后再说吧。众所周知dicom格式文件是由一个接一个连续的“数据元素”组成的。
这次我们只讲怎样去处理文件里一种特殊的数据元素:那就是VR为SQ类型的元素 还有delimited 也就是界定标识付 我们暂且把它归为一类。 为什么特殊呢?因为其他元素都很简单 ,根据传输语法:-> tag_有无显式VR_len_VF 这样的结构。 len是数据长度, VF是固定字节数的字节流数据。 而遇到SQ类型的数据元素就麻烦了 首先他的len是FFFFFFFF 就是无长度。然后是VF 他是一种“文件夹”结构 ,就是里面嵌套其他数据元素,可能嵌套一层 可能嵌套几层 处理是很棘手的问题。
说了这么多我们先来直观的看一下 找到我们上一篇文章《Dicom格式文件解析器》打开测试数据IM-0001-0002.dcm 看到tag数据里有很多类似这样的:
0040,0275SQ
0040,0275(SQ):00
--fffe,e000(**):
--0040,0007(LO):CT2 t阾e, face, sinus
----0040,0008(SQ):00
------fffe,e000(**):
------0008,0100(SH):CTTETE
------0008,0102(SH):XPLORE
------0008,0104(LO):CT2 T蔜E, FACE, SINUS
------fffe,e00d(**):
----fffe,e0dd(**):
----0040,0009(SH):A10011234815
----0040,1001(SH):A10011234814
--fffe,e00d(**):
fffe,e0dd(**):
事先已经知道VR是显式方式的explicit VR 字节序是little edition,这里只是测试 那么我们直接就在处理代码class的变量里写死了:
public IDictionary<uint, DataElement> pdvDecoding() { //pdvBuffer.Seek(0, SeekOrigin.Begin);//把读取偏移点设置到开始处 FileStream fs = new FileStream("IM-0001-0002.bin", FileMode.Open); WarpedStream ws = new WarpedStream(fs, bytOrder); IDictionary<uint, DataElement> ds = new Dictionary<uint, DataElement>(); //int indx = 0; while (ws.getPostion() < fs.Length) { DataElement item = readItemHeader(ws); //Console.WriteLine(Tags.ToHexString(item.tag)); readItem(ref item, ws); ds.Add(item.tag, item); //indx++; //if (indx >= 22) // break; showItem(item); } ws.close(); return ds; } int level = 0; public void showItem(DataElement element) { for (int i = 0; i < level; i++) { Console.Write("-"); } if (element.haveItems) { level++; Console.WriteLine(Tags.ToHexString(element.tag)); foreach (DataElement item in element.items) { showItem(item); } level--; } else { Console.WriteLine(Tags.ToHexString(element.tag)); } }
View Code
这种解析跟数据组织方式 更方便了dicom数据对象的处理 。我这讲讲当然很简单 看上去很容易的样子 ,因为我已经亲手一行代码一行代码的实现了。 代码很多请同学们 仔细阅读每一个细节 他们之间的调用关系及逻辑。很多地方我没讲到 为了限制篇幅其实有很多与重点部分无关的代码贴出来的时候我已经删除了,但是源码文件里有。
源码及测试数据下载猛击此处
相关文章推荐
- mysql 单机同版本多实例 mysql55
- 深入理解hash长度扩展攻击
- HDU 1300 POJ 1260 Pearls (DP)
- Java 实现基本的排序算法
- IOS中使用像素位图(CGImageRef)对图片进行处理
- Qt creator 如何支持中文编码(Qt4和Qt5解决方法不同)
- elasticsearch Snapshot 写php shell
- hdu 1205 思路题
- [翻译]Java日志终极指南
- 第三方框架
- 谷歌免费字体----Google Fonts
- 如何在bat文件执行完毕后不自动关闭窗口
- 代码如人
- 图片处理类库 Universal-image-loader 简介
- 在一个界面使用定时器后,退出界面后,一定要记得取消定时器
- 增加计算列排序
- ogre 种草
- AC自动机初识&hdu 2222 Keywords Search
- asp.net分页,Effective paging with List View control in ASP.NET
- 开发日记