【转】DICOM医学图像处理:开源库mDCM与DCMTK的比較分析(一),JPEG无损压缩DCM图像

转自:https://www.cnblogs.com/mfrbuaa/p/4004114.html 有修订

背景介绍:

近期项目需求,需要使用C#进行最新的UI和相关DICOM3.0医学图像模块的开发。在C++语言下,我使用的是应用最广泛的DCMTK开源库,在本专栏的起初阶段的大多数博文都是对DCMTK开源库的介绍和学习。眼下因为项目需要,现开始对mDCM开源库继续学习分析,因此本专栏接下来的文章大多以mDCM开源库为例进行医学图像的解说,DCMTK因为是C++语言开发的,所以作为我学习和剖析mDCM开源库的原始根据,我们并未放弃对DCMTK开源库的学习,而是通过更加细致的研读和分析DCMTK的C++源代码,从而更好更迅速的切换到C#语言环境下的医学图像处理。

DCMTK、mDCM(fo-dicom)的关系:

DCMTK的官网上有具体的说明文档,对该开源库的各个类,以及类之间的依赖关系进行了清晰的阐述。是学习DICOM3.0医学最新标准不可或缺的资源。其官网网址是:http://www.dcmtk.org/,活跃的开发人员论坛地址是:http://forum.dcmtk.org/index.php。

mDCM眼下了解是从DCMTK开源库转过来的,或者说是该开源项目的另一个分支,是用C#语言对C++版本号的医学图像开源库的再次组织和封装,其项目托管在GitHub上的官方网址是:https://github.com/rcd/mdcm。此处就需要提到fo-dicom了,该开源库是mDCM的升级版本号,里面添加了几大特性,详情可參见GitHub网址:https://github.com/rcd/fo-dicom。

大致上这三者的关系就是如此,更说明了我们依旧要以DCMTK开源库为根据,来高速学习和剖析mDCM(fo-dicom)开源库,要非常好的借助于DCMTK开源库丰富而具体的说明文档,以及活跃的开发人员论坛。以下我们就通过对DCM图像进行无损压缩这一任务来对照学习一下mDCM与DCMTK开源库的不同。

DCMTK与mDCM对DCM图像进行JPEG无损压缩的对照学习:

DCMTK的说明文档中对于dcmjpeg包的介绍中,就直接给出了一个利用JPEG无损压缩的实例。详细代码例如以下:

 

/*****************************************************************************
dcmjpeg程序包 
dcmjpeg提供了一个压缩/解压缩库以及可用工具。该模块包括一些类,可将DICOM图像对象在非压缩和JPEG压缩表示(传输协议)之间转换。无失真和有失真JPEG处理都被支持。这个模块实现了一族codec(编码解码器,由DcmCodec类派生而来),能够将这些codec在codec list中注冊,codec list是由dcmdata模块保存的。
主要接口类: 
--DJEncoderRegistration: 一个singleton(孤立)类,为全部支持的JPEG处理注冊编码器。在djencode.h中定义。 
--DJDecoderRegistration: 一个singleton(孤立)类,为全部支持的JPEG处理注冊解码器。在djdecode.h中定义。 
--DJCodecEncoder: JPEG编码器的一个抽象codec类。This abstract class contains most of the application logic needed for a dcmdata codec object that implements a JPEG encoder using the DJEncoder interface to the underlying JPEG implementation. This class only supports compression, it neither implements decoding nor transcoding. 在djcodece.h中定义。 
--DJCodecDecoder: JPEG解码器的一个抽象codec类。This abstract class contains most of the application logic needed for a dcmdata codec object that implements a JPEG decoder using the DJDecoder interface to the underlying JPEG implementation. This class only supports decompression, it neither implements encoding nor transcoding. 
工具: 
dcmcjpeg: Encode DICOM file to JPEG transfer syntax 
dcmdjpeg: Decode JPEG-compressed DICOM file 
dcmj2pnm: Convert DICOM images to PGM, PPM, BMP, TIFF or JPEG 
dcmmkdir: Create a DICOMDIR file 
举例: 
--用无失真JPEG压缩一幅DICOM图像文件。 
*****************************************************************************/ 
DJEncoderRegistration::registerCodecs(); // register JPEG codecs 
DcmFileFormat fileformat; 
if (fileformat.loadFile("test.dcm").good()) 
{ 
DcmDataset *dataset = fileformat.getDataset(); 
DcmItem *metaInfo = fileformat.getMetaInfo(); 
DJ_RPLossless params; // codec parameters, we use the defaults 
// this causes the lossless JPEG version of the dataset to be created 
dataset->chooseRepresentation(EXS_JPEGProcess14SV1TransferSyntax, ¶ms); 
// check if everything went well 
if (dataset->canWriteXfer(EXS_JPEGProcess14SV1TransferSyntax)) 
{ // force the meta-header UIDs to be re-generated when storing the file // since the UIDs in the data set may have changed delete metaInfo->remove(DCM_MediaStorageSOPClassUID); delete metaInfo->remove(DCM_MediaStorageSOPInstanceUID); // store in lossless JPEG format fileformat.saveFile("test_jpeg.dcm", EXS_JPEGProcess14SV1TransferSyntax); 
} 
}   
DJEncoderRegistration::cleanup(); // deregister JPEG codecs

 

 

(详细的project配置如前一篇博文所述http://blog.csdn.net/zssureqh/article/details/38460445,在此就不在反复介绍了)

通过这段代码能够顺利实现对DCM图像的JPEG无损压缩。例如以下图所看到的,

image

利用Sante DICOM Editor专业DCM图像浏览编辑器打开压缩前后的图像,发现图像质量没有区别,压缩前实际大小为4572K,压缩后为1774K,压缩效果良好。

   设想:既然mDCM开源库就是对DCMTK开源库的封装,那么两个开源库中应该会有相应的功能,同样或类似的函数。由DCMTK实例中的代码可知,演示样例中仅仅调用了DcmFileFormat的loadFile、saveFile和DcmDataset的chooseRepresentation和canWriteXfer四个函数,并且从函数名称上看,就知道实际达到压缩效果的应该是DcmDataset的chooseRepresentation和canWriteXfer的两个函数,那么接下来我们看看mDCM开源库下的DcmDataset是否有相相应的函数呢?

通过VS2012的对象浏览器能够看到,mDCM开源库下的Dicom.Data命名空间中DcmDataset类中的确拥有一个类似的函数ChangeTransferSyntax,例如以下图:

image

   推測:直接调用mDCM的Load、ChangeTransferSyntax和Save三个函数,应该能够实现与DCMTK同样的效果,即完毕对DCM的JPEG无损压缩。

详细代码例如以下,

 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Dicom; 
using Dicom.Data; 
using Dicom.Codec; 
using Dicom.Codec.JpegLs; 
namespace JpegLossLess 
{ class Program { static void Main(string[] args) { DicomCodec.RegisterCodecs(); //Dicom.Codec.JpegLs.DcmJpegLsCodec.Register(); string fName = string.Format("d:\\dcm\\test.dcm"); DicomFileFormat ff = new DicomFileFormat(); ff.Load(fName, DicomReadOptions.Default | DicomReadOptions.DeferLoadingPixelData);//ff.Load(fName, DicomReadOptions.None); DcmPixelData pixels = new DcmPixelData(ff.Dataset);DcmJpegLsParameters JpegParameters = new DcmJpegLsParameters(); ff.FileMetaInfo.TransferSyntax = DicomTransferSyntax.JPEGProcess14SV1;ff.Dataset.ChangeTransferSyntax(DicomTransferSyntax.JPEGProcess14SV1, JpegParameters);string OutFile = string.Format(@"d:\dcm\outfile.dcm"); ff.Save(OutFile, DicomWriteOptions.Default);  } } 
}


 

 

project顺利编译成功,执行调试后,也相同出现了大小为1774K的文件,可是利用Sante DICOM Editor打开该文件时,出现错误,例如以下图所看到的:

image

利用DCMTK开源库的工具包dcmdump.exe查看利用mDCM压缩后的文件outfile.dcm,输出例如以下错误提示:

image

警告(Warning)提示(0008,0000)数据元素的数值有误,错误(Error)是出现了无法识别的标签和数据(f752,0e57),经过查看DICOM3.0标准,并未发现有(f752,0e57)该标签,利用UltraEdit打开DCMTK压缩后的文件test_jpeg.dcm和mDCM压缩的文件outfile.dcm,通过查找功能发现,(f752,0e57)字段实际上是标准的JPEG无损压缩后的(7fe0,0010)字段的Value Field内容(例如以下图所看到的),因此推測应该是mDCM压缩后的文件头中某个字段写入有误,导致在读取数据体的时候并未依照原本的DICOM3.0标准去读取。

解决方法:

利用DCMTK的project来读取我们利用mDCM压缩后的文件outfile.dcm,结果单步调试进入后,利用Load函数读取Jpeg压缩后的图像时,metainfo部分是没有问题的。可是当读取到dataset时,对于(0008,0000)元素的读取有误,正确的(0008,0000)元素的解析方式为

clip_image002

元素标签,即(group,element)为:08 00 00 00——(0008,0000)

元素类型,即VR为:55 4C——UL

元素长度,即VL为:04 00——0004(长度为4)

元素值域,即Value Field:B8 00 00 00——00000008(值为184)

可是在读取dataset时,将55 4c 04 00所有当成了长度来读取,因此推測是将原本为ExplicitUL格式的元素当做了ImplicitVR格式来读取了,文件流的指针_streamPosition直接从0x0000000000000160直接跳转到了0x0000000000044db5,例如以下图所看到的:

clip_image004

因此尝试在mDCM的c#project中加入手动改动文件元信息中传输语义的语句,

 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Dicom; 
using Dicom.Data; 
using Dicom.Codec; 
using Dicom.Codec.JpegLs; 
namespace JpegLossLess 
{ class Program { static void Main(string[] args) { /**************************************************** * 对照C++中DCMTK对于DICOM进行JPEG无损压缩,来学习C# * 中Dicom库的使用 * 2014-08-06 * zssure ****************************************************/ DicomCodec.RegisterCodecs(); string fName = string.Format(@"d:\dcm\test.dcm"); DicomFileFormat ff = new DicomFileFormat(); ff.Load(fName, DicomReadOptions.Default | DicomReadOptions.DeferLoadingPixelData);DcmJpegLsParameters JpegParameters = new DcmJpegLsParameters();ff.FileMetaInfo.TransferSyntax = DicomTransferSyntax.JPEGProcess14SV1;ff.Dataset.ChangeTransferSyntax(DicomTransferSyntax.JPEGProcess14SV1, JpegParameters);string OutFile = string.Format(@"d:\dcm\outfileJpeg22.dcm"); ff.Save(OutFile, DicomWriteOptions.Default); } } 
}

project编译后,可以顺利完成压缩DCM的功能,至此利用mDCM对DICOM图像进行JPEG无损压缩的目的已经实现。

总结:

DICOM3.0标准的第10部分中,有对于dcm文件存储格式的具体介绍,当中对于传输语义的介绍例如以下:

1)Except for the 128 byte preamble and the 4 byte prefix, the File Meta Information shall be encoded using theExplicit VR Little Endian Transfer Syntax (UID=1.2.840.10008.1.2.1) as defined in DICOM PS 3.5. Values of each File Meta Element shall be padded when necessary to achieve an even length, as specified in PS 3.5 by their corresponding Value Representation. The Unknown (UN) Value Representation shall not be used in the File Meta Information. For compatibility with future versions of this Standard, any Tag (0002,xxxx) not defined in Table 7.1-1 shall be ignored. Values of all Tags (0002,xxxx) are reserved for use bythis Standard and later versions of DICOM. Data Elements with a group of 0002 shall not be used in datasets other than within the File Meta Information

2)The Transfer Syntax used to encode the DataSet cannot be changed within the Data Set; i.e., the Transfer Syntax UID Data Element may not occur anywhere within the Data Set, e.g., nested within a Sequence Item.

因此DCM文件元信息中的标签(0002,0010),即传输语义,对于DCM文件的数据体Dataset的读取起到关键的作用。通过此次的mDCM开源库与DCMTK开源库的比較发现,两者尽管大多的函数都同样,且名称和功能都类似,可是对于细节部分应该注意。

如今对两个开源库对DCM文件的JPEG无损压缩功能所须要调用的函数进行一个对照分析,以找到两者之间的区别所在,详细分析例如以下表

mDCM

DCMTK

1) DicomFileFormat.Load,打开文件(也是通过文件流的方式一一读取DCM文件的各个信息到内存中)

2) DicomFileFormat.Dataset.ChangeTransferSyntax,该函数与DCMTK中的chooseRepresentation函数类似,在參数中都须要指出新的传输语义,函数内部会依据新的传输语义来改动数据体的存储方式。该函数主要完毕的功能是:

比較新旧传输语义、依据新旧语义决定数据体是否解压缩或压缩(Dicom.Codec.Encode或者Dicom.Codec.Decode)。

3) DicomFileFormat.Save,存储文件,可是该函数中并不须要填写新的传输语义

【注】:这一点与DCMTK中的saveFile函数不同。这也就是上个周C#版本号的mDCM实现对DCM数据的JPEG无损压缩后无法顺利读取的原因。由于数据体存储格式不是依照文件元信息中指定的传输语义存储的,或者说文件元信息中的传输语义没有改动为JPEG无损压缩的方式。

1) DicomFileFormat::loadFile,导入文件,主要是DcmMetaInfo和DcmDataset两部分;

2) Dataset::chooseReresentation,參数中会出现新旧传输语义TransferSyntax,函数依据新的语义对对应数据(主要是像素数据)进行处理,会调用DcmPixelData::canChooseRepresentation、DcmPixelData::chooseRepresentation

3) Dataset::canWriteXfer,參数中是新改动后的传输语义。

4) DcmFileFormat::saveFile,參数中须要指出改动后的传输语义。

——》随后会调用dcfilefo.cc文件里的validateMetaInfo函数(该函数中也须要指定新的传输语义)。

——》对文件元信息的各个元素分别调用DcmMetaInfo::search和chekMetaHeaderValue两个函数(在该函数内,会检測各个元信息元素是否存在,不存在会新建之并插入,其參数中就须要指出新的传输语义)

——》DcmElement::putString将新的传输协议写入到MetaInfo中。(基本调用流程例如以下图。

clip_image002[5]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/435913.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

量子计算机的核心元件简称,计算机文化基础复习题(含答案).doc

计算机文化基础复习题(含答案)整理计算机文化基础复习题第一套一、单项选择题(每题1分,共30分)1、在Powerpoint2003中,若为幻灯片中的对象设置"驶入效果",应选择对话框 (? )???? A、自定义放映???? B、幻灯片版式????…

xfire客户端对返回list很挑剔,所以需要使用泛型。

casldap异常分析 | xfirewebservice(服务器配置篇) 2008-12-31xfirewebservice(客户端调用篇) 服务接口,就是用来调用的,所以客户端显得尤为重要,xfire客户端对返回list很挑剔,所以需要使用泛型。 如何建立webservice client 步骤…

C语言关键字----Const

C中CONST的使用:   虽然这听起来很简单,但实际上,const的使用也是c语言中一个比较微妙的地方,微妙在何处呢?请看下面几个问题。   问题:const变量 & 常量   为什么下面的例子在使用一个const变量…

【转】DICOM的常用Tag分类和说明!!!!

转自:https://www.cnblogs.com/stephen2014/p/4579443.html 有删改 1. 前言: 基于DICOM3.0标准的医学图像中,每一张图像中都携带着许多的信息,这些信息主要可以分为Patient, Study, Series和Image四类。每一个DICOM Tag都是…

计算机卡在无法显示网页,我的电脑上网上银行一直“无法显示网页”

首先:打开一个网页,点击“工具”--internet选项--高级--还原默认设置--应用--确定 其次:使用这个修复工具试一试&#xff…

在虚拟机上运行vxWorks

Vxworks是一个嵌入式系统,主要运行在arm、ppc、mips等嵌入式处理器上,它同样可以运行在X86处理器上。风河公司开发的tornado开发环境就 包括了pentium版本,并且发布了相应的bsp。因此我们可在vmware虚拟机上运行vxworks,利用虚拟机…

【转】成熟的医学影像“调窗”(window-leveling)算法详解

转自:http://blog.sina.com.cn/s/blog_4bce5f4b0100o9iy.html 图像显示和打印面临的一个问题是:图像的亮度和对比度能否充分突出关键部分。这里所指的“关键部分”在 CT 里的例子有软组织、骨头、脑组织、肺、腹部等等。 技术问题: 显示…

南京大学计算机系副教授名单,2018年度国际“人工智能10大新星”名单公布:南京大学俞扬副教授国内高校入选者...

中公考研小编为各位考研小伙伴们整理了关于2018年度国际“人工智能10大新星”名单公布:南京大学俞扬副教授国内高校唯一入选者的相关资讯文章,一起了解一下吧~日前,国际人工智能领域著名杂志 IEEE Intelligent Systems 发布了2018年度“人工智…

使用SDL打造游戏世界之入门篇 - 7

打开和显示图片在这个例子里我们将学习如何使用SDL程序中打开和显示图片。示例程序将绘制一个漂亮的背景,上面显示一个正方形图案,并可以使用键盘的方向键移动它。如果比较熟悉“推箱子”这个游戏,可以看出这个程序实际就是推箱子游戏的基础。…

WDB

1. 符号表同步貌似只能是target shell下载后,能够在host shell下更新,当host shell下载的话,target shell是无法更新的。 2. host shell下执行某一个函数的时候,WDB会自动生成一个新的任务来运行,这个任务的IO将被重定…

【转】GPS从入门到放弃(一) --- GPS基础原理

转自:https://blog.csdn.net/tyst08/article/details/100529424 GPS从入门到放弃(一) — GPS基础原理 GPS,全称Global Positioning System,已经广泛应用于我们的日常生活中了,现在的智能手机 里都会自带G…

计算机系统的物质实体,计算机基础-(-第1次-).pdf

计算机基础 -(- 第 1 次-)第 1 次作业一、填空题(本大题共 30 分,共 10 小题,每小题 3 分)1. 二进制数求积 011 ______ 。2. 计算机系统是由 _ ______ 和 ______ _ 两大部分组成的。3. 八个二进制位称为一个 ______ ,是计算机的最小存储单元。…

JS判断数字/字母/中文

原文链接:http://tieba.baidu.com/f?kz140213674 1JS判断数字/字母/中文 1. var reg /^(\w|[\u4E00-\u9FA5])*$/; if(arrusername.match(reg)) { ti1; return ture; } else { alert("用户名只允许为英文,数字和汉字的混合,\n请检查是否前后有…

【转】10个推荐的 PACS/DICOM Server开源项目

10个推荐的 PACS/DICOM Server开源项目 转自:https://zhuanlan.zhihu.com/p/65437040 soolaugust 喜欢我的分享可以关注公众号:雨夜随笔 35 人赞同了该文章 本文仅授权给公众号:雨夜随笔, 欢迎关注 本文翻译自:To…

字节序、位序

字节序 字节序,又称端序、尾序,英文单词为Endian,该单词来源于于乔纳森斯威夫特的小说《格列佛游记》,小说中的小人国因为吃鸡蛋的问题而内战,战争开始是由于以下的原因:我们大家都认为,吃鸡蛋前…

怎么抓取屏幕截图计算机考试时间,定时抓屏快照(电脑截屏工具)V4.8 最新版

定时抓屏快照(电脑截屏工具)是一款非常实用的电脑屏幕定时抓拍软件。想定时截取电脑屏幕?定时抓屏快照(电脑截屏工具)轻松帮助用户。马上要放假了,家长一定很担心小孩最新的上网情况,看是在电脑上玩什么,用户通过该软件可以及时了…

什么是IIS

IIS的设计目的是建立一套集成的服务器服务,用以支持HTTP,FTP和SMTP,它能够提供快速且集成了现有产品,同时可扩展的Internet服务器。IIS相应性极高,同时系统资源的消耗也是最少,IIS的安装,管理和…

【转】C#检查键盘大小写锁定状态的方法

转自: 本文实例讲述了C#检查键盘大小写锁定状态的方法。分享给大家供大家参考。具体分析如下: 1、命名空间: 1 using System.Runtime.InteropServices; 2、导入方法 1 2 [DllImport("user32.dll", EntryPoint "GetKeybo…

计算机系统的备份与还原实验报告,数据库《数据备份与还原》实验报告.doc

《数据库《数据备份与还原》实验报告.doc》由会员分享,提供在线免费全文阅读可下载,此文档格式为doc,更多相关《数据库《数据备份与还原》实验报告.doc》文档请在天天文库搜索。1、xx大学计算机与信息技术学院实验报告姓 名学 号…

jquery智能提示

中文提示文件http://code.google.com/p/csm-ui/downloads/list aspx页面编写时候<script src"http://www.cnblogs.com/Scripts/jquery-1.3.2.min.js" type"text/javascript"></script><script src"http://www.cnblogs.com/Scripts/jqu…