DICOM简介

背景:

DICOM分为两大类(这里只是从DICOM相关从业者日常工作角度出发来分类的):1)DICOM医学图像处理,即DCM文件中具体数据的处理,说图像可能有些狭隘,广义上还包括波形(心电)、视频(超声)等等;2)DICOM网络传输,主要描述信息在医院各系统之间的交互方式及传输格式。一旦解析出DICOM的文件格式其实与常规的图像处理就没有差别。如果仅此而已,可以说跟医疗就没有任何关系,与医疗行业结合紧密的是第二类“DICOM网络传输”,该部分是日常患者到医院就诊等整体流程的抽象,是DICOM标准的核心。因此此次博文就重点介绍“DICOM网络传输”中的第一环节:网络连接(Association,在OSI中叫做Connection),并结合DCMTK和fo-dicom的源码进行实例介绍。

DICOM网络传输:

服务端(Server,SCP)/客户端(Client,SCU):

DICOM采用C/S模式来描述网络传输:客户端(Client)连接到服务端(Server)然后使用服务端提供的各项服务(Services)。不同于传统网络连接中的Server和Client的,DICOM中的Server叫做Service Class Provider,Client叫做Service Class User。想要建立DICOM连接(Association,传统OSI模型中叫做Connection),客户端会向服务端发送连接请求消息,该消息主要描述客户端此次连接所期望的DICOM服务及相关设置;随后服务端会查看客户端发送过来的请求信息,确认自己是否支持客户端请求的相关服务并给出反馈信息(DICOM中叫做响应信息Response Message)。响应信息主要分为以下几类:1)如果服务端支持客户端请求的某些服务,服务端会发送确认信息(Association Acknowledge),表明此次连接完成;2)否则发送拒绝信息(Association Reject),通知客户端(SCU)连接失败。所有与连接相关的信息在DICOM协议中的ACSE(Association Control Service Element)定义。

一旦网络连接建立,客户端(SCU)和服务端(SCP)就可以进行信息交互。DICOM标准中的DIMSE(DICOM Message Service Element)将该类信息分为11类(详情可参见DICOM协议中的相关细节,也可参见我之前的博文http://blog.csdn.net/zssureqh/article/details/39098621)。根据与连接信息(ACSE)的不同,提供的DIMSE信息类型也不同。例如传统一幅DICOM图像到服务端进行归档,使用的是C-STORE DIMSE消息;如果希望通过病人姓名和病人出生日期来查询病人的档案,需要使用DIMSE C-FIND消息。

请求连接:

如上所述,客户端SCU向服务端SCP发送连接请求,请求服务及相关信息。除此以外,请求消息中还包括以下信息:

  • 请求端实体名称(Calling AE Title):在DICOM服务中,用于指代客户端(SCU)的符号,如同我们的姓名一样;
  • 被请求实体名称(Called AE Title):在DICOM服务中,用于指代服务端(SCP)的符号,如同我们的姓名一样;
  • 描述上下文(Presentation Contexts):是一个服务清单(List of Services)。清单容量最多不超过128个,用于描述客户端希望从服务端获得的各项服务,每一项服务主要包括SOP Class和List of Transfer Syntaxes。

下面对上述三中信息进行更详细介绍:

AE Title:在DICOM网络中每一个DICOM系统都会被分配一个名称,即Application Entity Title,简称AETitle。AE Title用于标识DICOM网络中的唯一(Unique)DICOM系统(有点类似于互联网中的IP地址),因此在一个DICOM网络环境中,要确保每一个DICOM系统拥有唯一的名称——这个工作通常由DICOM网络管理员来完成。AE Title最长不超过16个字符,通常在实际应用过程中都采用大写字母来表示,当然也可以使用小写字母及其他ASCII码。在建立连接过程中,客户端SCU会发送自己的AE Title(即Calling AE Title)以及服务端的AE Title(即Called AE Title,当然这个只是客户端期望的,实际情况有可能并非如此)。

Presentation Contexts:DICOM协议已经有20多年的历史,从1993年DICOM标准提出以来,新的网络连接不断地被添加到DICOM协议中。例如1996年引入的MWL服务,即Modality Worklist Services(关于WML的描述可参见之前的博文)。因此大多数DICOM系统只支持DICOM标准中的部分服务,例如PACS系统往往就不会提供WML服务。不同的DICOM服务用于不同的目的,客户端(SCU)会向服务端(SCP)发送其希望从服务端获得的服务,而服务端会查看其提供的各项服务是否是客户端期望的来决定是否提供。鉴于以上原因,客户端(SCU)会向服务端发送一系列长度小于128的被称为描述上下文(Presentation Contexts)的消息列表,每一个描述上下文代表一种客户端期望的服务。客户端用DICOM标识符来标识每种服务,即SOP Class UID(Service Object Pair Class Unique Identifier),在DICOM标准的第4部分有详细介绍。在连接上下文中,被发送的SOP Class 也被叫做抽象语义Abstract Syntax(一定要与Transfer Syntaxes中的Syntaxes区分开来,之前在博文http://blog.csdn.net/zssureqh/article/details/39213817#t12的知识储备中有过简单的对比介绍。在OFFIS的WIKI中对此的描述原文为In the context of association negotiation, the field where the SOP class is sent is also called "Abstract Syntax".),因此Abstract Syntax就是SOP Class UID的同义词。在传输SOP Class UID(即Abstract Syntax)的同时,会发送与该服务对应的编码格式,即Transfer Syntaxes。以乳腺检查的X光片为例,通常乳腺X光片很大,需要进行压缩。客户端在向服务端发送上下文信息时会提供给服务端一种乳腺X光片的压缩方式,例如JPEG2000,同时也会提供一种被大多数图像传输服务端接受的非压缩方式。如下图所示:

该客户端SCU向服务端发送了三种上下文信息(最多不超过128个),每一种上下文信息(Presentation Context)包含一种客户端期望的服务以及相关的多种传输方式,例如Presentation Context ID 1中描述了一种数字乳腺X光片存储服务,同时提供了两种编码方式Implicit VR Little Endian和JPEG 2000(无损压缩)。在客户端用奇数来标示每种上下文信息(最小编号为1,最大为255),通常从1号开始单调递增,1、3、5、……。至于上下文信息之间的顺序以及其内部编码格式的顺序可自由设定。通过上图可以看出,每种服务都必须提供Implicit VR Little Endian编码格式,因为这是DICOM协议中默认的传输编码方式。

接受(拒绝)连接:

服务端SCP会至少接受一种上下文信息(Presentation Context)以及其他SCU请求的参数(例如AE Titles)。随后服务端向客户端发送连接响应消息接受该链接请求。链接消息响应有三种状态:

  • 接受
  • 拒绝(短暂的)
  • 拒绝(永久的)

连接响应消息会直接拷贝连接请求消息中的服务端AE Title(即Called AE Title)和客户端AE Title(即Calling AE Title)并返回。此外还会返回响应AE Title(即Respponding AE Title),该AE Title与服务端AE Title相同(这是OSI协议中要求的,但是与DICOM协议不同的是,OSI协议中并未要求两者相同)。

当消息响应结果为接受时(即Accepted),服务端SCP会对客户端SCU请求的各个上下文信息(Presentation Context)进行确认,是接受还是决绝,如下图所示,DICOM标准第7部分的附录D中给出了一个示意图,作为服务触发端的DICOM-Service-User,给出了5种描述上下文,ID为1、3、5、7、9;然而在SCP端只支持其中的三种(ID为1、3、9),并且对于每一种AbstractSyntax服务端只支持其中的一种TransferSyntax。

如上图所示,如果SCU请求的Presentation Context被拒绝,SCP不会进一步发送任何信息;如果接受了某个Presentation Context,SCP会选择其中的一个传输语义添加到返回信息对应的Presentation Context中以通知SCU。如果没有Presentation Context被接受,那么会发送拒绝消息,此时结果代码为Rejected。当连接建立完成后,开始准备传输数据体。

如果结果状态码为”Rejected(permanent)“表明服务端SCP通知客户端SCU它的请求被拒绝了,后续也会被拒绝。出现这种情况的原因通常由两种,一种是请求的AE Title并不存在,也就是说网络中并不存在该实体;另一种是服务端SCP不支持客户端SCU请求的任何服务(即SOP Class)。在拒绝情况下,SCP可有选择的返回Diagnostic状态码以通知客户端被拒绝的原因;最差的情况下,服务端SCP只返回”Calling AE Title not recognized“。在拒绝状态下,DICOM连接就终止了,SCP和SCU无法传输数据;与此同时底层的TCP连接也会关闭直到客户端SCU再一次发送连接请求。

释放(终止)连接:

在连接建立之后,连接双方开始进行数据交换。如果任何一方想终止连接(服务端SCP也可以),有两种方式:

  • 发送连接释放消息;
  • 发送连接终止消息;

第一种情形,接收到连接释放消息的一方会向释放方发送一条确认消息。随后TCP连接关闭,DICOM连接终止,这是DICOM网络连接中正常的关闭方式;第二种情况,客户端发送完放弃消息后,不等到服务端的确认就主动关闭TCP连接。这种关闭是不正常的,通常是客户单遇到意外情况后发生的,这是DICOM中唯一一种不需要服务端发送响应信息的请求信息。当然还有第三种中断方式,就是直接关闭TCP连接,这种情况往往是由于硬件错误所导致的。

数据交换(Date Exchange)DIMSE:

利用ACSE消息成功建立连接后,即客户端发送的请求至少有一种上下文描述的服务被服务端接受,真正的数据开始交换,例如一张或多张CT图像、worklist查询、打印请求等。如上所述,DICOM协议规定了11种DIMSE消息,每种都可以作为客户端的请求或者服务端的响应。11种DIMSE消息如下:C-CTORE、C-GET、C-MOVE、C-FIND、C-ECHO、N-EVENT-REPORT、N-GET、N-SET、N-ACTON、N-CREATE、N-DELETE。所有的消息都可以被不同的服务使用,根据Presentation Context的描述,你只需要其中的一种或多种。

PDU-Protocol Data Units:

在DICOM系统连接中,每种DIMSE消息在传输过程中会被分割成多个片段,叫做Protocol Data Unit,简称PDU。PDU的大小也是连接建立过程中协商的。每一个PDU片段中会包含一个与Presentation Context ID相关的数字。我们可以将每一个Presentation Context看做双方交流的逻辑通道,通过在PDU中包含Presentation Context ID,接收端才知道PDU属于哪一个通道,才能将多个PDU片段进行重组。

DIMSE Message Data:

每种DIMSE消息所传输的内容各有不同,请求消息(request)中主要包括:

  • Message ID:在连接中每个消息的唯一标示
  • Affected SOP Class UID:DIMSE消息中指定的SOP Class,即Presentation Context中指定的Abstract Syntax。
  • Affected SOP Instance UID:真正传输的实体数据标识符,例如上面例子中提到的乳腺X光片数据
  • Priority:消息的优先级,分为HIGH 、NORMAL、LOW三种,但是大多数接收端都忽略。
  • Data Set:传输的数据。

响应消息(response)内容与上述类似。首先包括一个状态信息,例如0代表成功;另外与Message ID对应的是Message ID Being Responsed To,通过拷贝并返回请求端的Message ID,使得接收端知道响应消息的目标。

开源库中相应的实现:

DCMTK:

DCMTK开源库更偏重于按照层(Layer)来实现DICOM应用实体(AE)之间的连接(ACSE)及消息传输(DIMSE),主要分为DIMSE(应用层)、ACSE(属于OSI七层协议中的应用层)和DUL(Dicom Upper Layer层,该层与OSI中的TCP/IP层对接)三大部分。用户通过使用DCMTK提供的DICOM协议中规定的各层的数据结构和操作函数,按照DICOM标准中规定的流程来实现自己的DICOM服务。

dimse.h/dimse.cc中给出了DICOM协议中规定的各种服务对应的结构体,以T_DIMSE_为前缀,例如T_DIMSE_C_StoreRQ/T_DIMSE_C_StoreRSP、T_DIMSE_FindRQ/T_DIMSE_FindRSP、T_DIMSE_CEchoRQ/T_DIMSE_CEchoRSP等;另外给出了各种服务对应的操作函数的声明,以DIMSE_为前缀,例如DIMSE_echoUser/DIMSE_sendEchoResponse、DIMSE_storeUser/DIMSE_storeProvider/DIMSE_sendStoreResponse等等,具体相应的函数定义被分别放在了独立的文件中,主要有dimecho.cc、dimfind.cc、dimget.cc、dimmove.cc、dimstore.cc。

assoc.h/assoc.cc中给出了ACSE应用层的对应结构的封装,以T_ASC_为前缀,例如T_ASC_Parameters、T_ASC_Association、T_ASC_PresentationContext等等;另外给出了相应的连接建立或中断的操作函数,以ASC_为前缀,例如ASC_initializeNetwork、ASC_dropNetwork、ASC_requestAssociation、ASC_receiveAssociation、ASC_acknowledgeAssociation、ASC_rejectAssociation、ASC_releaseAssociation等等。

dul.h/dul.cc中给出了Dicom Upper Layer层的相关数据结构,以DUL_为前缀,例如DUL_ASSOCIATESERVICEPARAMETERS、DUL_PRESENTATIONCONTEXT、DUL_TRANSFERSYNTAX、DUL_PDV、DUL_PDVLIST;另外给出了DUL层的操作函数,同样以DUL_为前缀,例如DUL_InitializeNetwork、DUL_RequestAssociation、DUL_ReleaseAssociation、DUL_ReadPDVs、DUL_WritePDVs、DUL_NextPDV等等。

fo-dicom:

fo-dicom开源库更偏重于按照DICOM消息流来封装,在实现了整体DIMSE消息流框架的基础上,给用户预留了各阶段的接口,方便用户继续自定义实现。

PDU.cs中给出了ACSE应用层对应的服务对象,主要有RawPDU、PDU、A-Associate-RQ、A-Associate-AC、A-Associate-RJ、A-Release-RQ、A-Release-RP、A-Abort、PDataTF。

DicomMessage为基类派生出的一系列子类,例如DicomRequest/DicomResponse、DicomCEchoRequest/DicomCEchoResponse、DicomCStoreRequest/DicomCStoreResponse等等;该部分对DICOM协议中规定的各种消息进行了响应的封装。

DicomService类中给出了整个DICOM协议中规定的SCP/SCU之间交互的流程,但是对于不同的ACSE应用层的连接操作和DIMSE层的消息操作都留出了相应的接口,通过调用后续的回调函数来实现用户自己的意图。

IDicomServiceUser/IDicomServiceProvider、IDicomCStoreProvider、IDicomCEchoProvider等为基础的一系列接口类,该部分给出了DicomService中一系列操作的回调函数接口,具体的实现由用户自己完成。

DicomClient/DicomServer为基础的实体类,该类是用户自己搭建SCP和SCU两端的必须类,可以说DicomClient和DicomServer就是一对简易实现的DICOM服务的SCU和SCP。例如fo-dicom自带的实例中var server = new DicomServer<DicomCEchoProvider>(12345);就开启了一个端口号为12345的接收C-ECHO服务的SCP服务端;var client = new DicomClient();client.NegotiateAsyncOps();client.AddRequest(new DicomCEchoRequest());就实现了一个简易的发起C-ECHO请求的SCU客户端。

DICOM3.0标准分析:

PDU vs PDV:

DCMTK3.0标准中对于PDU(Protocol Data Unit)的解释和定义与上面博文中介绍的一致,但是对于PDV在标准中有两种解释分别是Protocol Data Value和Presentation Data Value,我更偏向于后者。上面博文中介绍的PDU指的是在DICOM连接建立之上传递的消息片段,英文原文是“If such a message is transferred on a DICOM connection, they are cut into pieces, so called Protocol Data Unit (PDUs).”——这里需要注意的是message,并不仅仅指我们所说的DICOM Message(参见图1),还包括了ACSE协议中使用的连接消息,例如A-ASSOCIATION-RQ、A-ASSOCIATION-RSP、A-ABORT,该类消息在DICOM3.0协议的第8部分有详细的介绍(参见图2)。

在图2中P-DATA-TF PDU结构中的Variable Field可变区域才是PDV,即Presentation Data Value。这里PDV指的是DICOM Message在具体传输过程中被分割的多个片段(该部分在DICOM3.0标准第8部分的附录E中有详细介绍,参见图3,其实就是上文中提到的DIMSE Message Data)。在fo-dicom中的PDU.cs文件中可验证,其中PDU的子类P-DATA-TF的成员中包含一个PDV的链表,即List<PDV>。

一句话总结:PDU指的是DICOM协议中的传输的各种消息(包括ACSE和DIMSE)的片段,PDV专指DICOM Message被分割后的片段,属于P-DATA-TF类PDU中的Variable Field部分。

ACSE vs DIMSE:

ACSE是在DICOM3.0中的第8部分介绍,该部分的标题为Network Communication Support for Message Exchange,因此可以断定ACSE主要应用户连接建立阶段。 连接(Association)的建立是两个DICOM实体(AE)之间进行交互的第一步,AEs在建立的连接上进行数据编码格式、传输方式的协商。DICOM AEs利用ACSE-ASSOCIATE服务来建立连接,在ACSE-ASSOCIATE服务中主要用到的是Application Context、Presentation Context和User Information Items(在DICOM3.0标准第7部分的附录3中有详细的介绍)。ACSE服务主要有A-ASSOCIATE、A-RELEASE、A-ABORT、A-P-ABORT、P-DATA五类,对应的PDU有A-ASSOCIATE-RQ、A-ASSOCIATE-AC、A-ASSOCIATE-RJ、P-DATA-TF、A-RELEASE-RQ、A-RELEASE-RP、A-ABORT七种。

DIMSE是在DICOM3.0中的第7部分介绍,该部分的标题为Message Exchange,由此说明DIMSE是对DICOM传输消息的规定。DIMSE服务类型有C-STORE、C-GET、C-MOVE、C-FIND、C-ECHO、N-EVENT-REPORT、N-GET、N-SET、N-ACTION、N-CREATE、N-DELETE,如下图。

有上述对比可以看出ACSE是DIMSE的基础,DIMSE是在ACSE之上实现的。正如PDU vs PDV中提到的,DIMSE Message是在Association建立完成后,通过ACSE中的P-DATA-TF服务来传输,各种DIMSE 消息会被分割成PDVs放入到P-DATA-TF的Variable Field。如下图所示:

最后通过查看fo-dicom中的DicomService.cs中EndPDU和ProcessPDataTF函数可以有一个更形象的理解,在EndPDU函数内部通过读取PDU的前6个字节来识别PDU属于ACSE中的哪一种服务,例如A-ASSOCIATE-RQ、A-ASSOCIATE-AC、A-ASSOCIATE-RJ、P-DATA-TF、A-RELEASE-RQ、A-RELEASE-RP、A-ABORT;当PDU属于P-DATA-TF类型时,进入到ProcessPDataTF函数内部。通过提取P-DATA-TF PDU中的Variable Field中的PDVs来判别是哪一种DIMSE消息,主要有C-STORE-RQ/C-STORE-RSP、C-FIND-RQ/C-FIND-RSP、C-ECHO-RQ/C-ECHO-RSP、C-MOVE-RQ/C-MOVE-RSP等等。

时间: 2024-10-01 04:30:50

DICOM简介的相关文章

医学图像之DICOM格式解析

医学影像学 医学影像学Medical Imaging,是研究借助于某种介质(如X射线.电磁场.超声波等)与人体相互作用,把人体内部组织器官结构.密度以影像方式表现出来,供诊断医师根据影像提供的信息进行判断,从而对人体健康状况进行评价的一门科学,包括医学成像系统和医学图像处理两方面相对独立的研究方向. 仪器主要包括X光成像仪器.CT(普通CT.螺旋CT).正子扫描(PET).超声(分B超.彩色多普勒超声.心脏彩超.三维彩超).核磁共振成像(MRI).心电图仪器.脑电图仪器等 DICOM简介 DIC

dicom通讯的工作方式及dicom标准简介

转自:http://www.cnblogs.com/assassinx/p/3223460.html 本文主要讲述dicom标准及dicom通讯的工作方式.dicom全称医学数字图像与通讯 其实嘛就两个方面 那就是“存储”跟“通讯”. 文件数据组织方式  网络数据组织方式.文件数据组织方式就是解析静态的dicom文件 在 <dicom格式文件解析器>一文中已经阐述过了 就不再说了.网络数据组织方式 简而言之就是各种协议 命令控制 数据序列化.那么这一章中我们将会讲他,但是进行实际操作将在后面几

【网摘】DICOM 基础简介

一 什么是DICOM?DICOM是Digital Imaging and Communication of Medicine的缩写,是美国放射学会(American College of Radiology,ACR)和美国电器制造商协会(National Electrical Manufacturers Association,NEMA)组织制定的专门用于医学图像的存储和传输的标准名称.经过十多年的发展,该标准已经被医疗设备生产商和医疗界广泛接受,在医疗仪器中得到普及和应用,带有DICOM接口的

DICOM医学图像处理:fo-dicom网络传输之 C-Echo and C-Store

背景: 上一篇博文对DICOM中的网络传输进行了介绍.主要參照DCMTK Wiki中的英文原文.通过对照DCMTK与fo-dicom两个开源库对DICOM标准的详细实现,对理解DICOM标准有一个更直观的认识.此篇博文是对上一篇博文的补充.由于专栏前面的演示样例大多是利用DCMTK工具包来进行的,此次借着分析fo-dicom源代码结构的机会,參照fo-dicom的README.md,给出C-ECHO 和C-STORE服务的详细实现.在实现的同一时候给出DICOM3.0标准中的相关介绍,帮助我们理

DICOM医学图像处理:Orthanc Plugin SDK实现WADO服务

背景: Orthanc是博主发现的一个很完美的DICOM和HTTP服务端开源软件,前几篇分别介绍了Orthanc的基本使用.Orthanc从0.8.0版本之后给出了Plugin SDK,通过该SDK可以利用Orthanc内建的REST API实现WADO服务,下面就参照官网给出的说明介绍一下如何使用SDK实现WADO服务,并且对官网的实例进行更新,采用最新的方式直接实现WADO服务. 官方说明中文翻译: 1)简介 DICOM标准定义了文件格式以及医学影像网络传输协议.WADO,即Web Acce

DICOM:再次剖析fo-dicom中DicomService的自己定义事件绑定

题记: 趁着<从0到1>大火的热潮,最近又一次翻阅了一遍<从一到无穷大>(这样是不是感觉整个非负数轴就圆满了^_^). 尽管作为科普类书籍.可是里面的内容还是比較深奥,幸亏有作者精准的翻译,一番细细品味后宛如醍醐灌顶,心中透亮. 一直幻想有外星人.宇宙外生物的存在,从<源代码>描写叙述的"平行世界",到<星际穿越>的"超维空间",再到时下泛滥的穿越剧,却总未解开心中那团疑惑. 也许仅仅有时间的流逝才干给我解答,仅仅怕光

基于DCMTK的DICOM相关程序编写攻略

2008年09月10日 星期三 15:35 前言: 由于现在的医学影像设备的图像存储和传输正在逐渐向DICOM标准靠拢,在我们进行医学图像处理的过程中,经常需要自己编写和DICOM格式的图像相关的各种程序模块,以完成自己处理功能.如果从头开始理解DICOM的协议,然后完全自己编写这些代码来实现这些协议,是一件工程浩大的事情.德国offis公司开发的DCMTK,为我们提供了实现DICOM协议的一个平台,使得我们可以在它的基础上轻松的完成自己的主要工作,而不必把太多的精力放在实现DICOM协议的细节

DICOM医学图像窗口变换的加速算法

详见:http://pan.baidu.com/s/1gfFLbJ9 DICOM医学图像窗口变换的加速算法* 张尤赛 ,陈福民 ( 同济大学计算中心, 上海 200092 ) (华东船舶工业学院电子与信息系,江苏 镇江 212003) E_mail:[email protected]   摘 要:研究DICOM医学图像的显示技术,提出了一种图象窗口变换的加速算法,该算法简洁.实用.加速效果理想, 可以在动态连续调节图像窗值的情况下实时地显示DICOM医学图像. 关键词: DICOM: 医学图像:

dicom网络通讯入门(2)

转自:http://www.cnblogs.com/assassinx/p/3649498.html 第二篇,前面都是闲扯 其实正文现在才开始,这次是把压箱底的东西都拿出来了. 首先我们今天要干的事是实现一个echo响应测试工具 也就是echo 的scu,不是实现打印作业管理么.同学我告诉你还早着呢.本来标题取的就是<dicomviewer 第二弹 之 实现打印管理>名字多霸气,最后我又改回来了. 首先你得把数据组织方式搞懂 那就是pdu  和dimse  元素  数据元素.然后基于这之上你得