DICOM:DCMTK工具包分析之dcmqrscp.exe、dcmqridx.exe、dcmqrti.exe

背景:

新的一年开始,专栏会坚持下去,继续与大家相互交流学习。本篇博文再一次分析DCMTK自带的工具包dcmqrscp.exe(类似于一个单机版miniPACS),此次主要关注dcmqrscp.exe的数据库部分,通过使用dcmqridx.exe手动操作dcmqrscp.exe的数据库文件,直观了解数据库的记录内容;然后利用dcmqrti.exe查询dcmqrscp.exe的数据库文件,学习如何操作dcmqrscp.exe数据库。

单机版数据库:

单机版数据库就是只能运行在单机上,不提供网络功能的数据库。比如ACCESS、FORPRO等都是单机数据库(摘自百度百科“单机数据库”)其实单机数据库种类还有很多,年前分析过Orthanc的数据库——SQLite,和此次即将要分析的index.dat文件,此外甚至还有FireBird、Derby、HSql、PostgreSQL、JavaDB
、H2等。

之所以使用数据库(无论单机版还是网络版),目的是尽量减少数据的冗余、提高数据利用率、保持数据完整性和一致性,以及数据使用效率。无论哪一种数据库系统,其所建立的数据库文件都可以看做是具有想相同性质的记录的集合,更广义的说,我们常见的xml、json、ini等配置文件也是单机版的数据库。

index.dat:

原本以为index.dat可能是一种类似于xml、json等常见格式的标准文件,搜索了一下百度百科中的描述“在微软windows操作系统中,index.dat是一个由Internet
Explorer和资源管理器创建的文件。这个文件的功能就像一个数据库,随系统启动。它的功能在于收集个人信息,就像网址,搜索字符串和最近打开的文件。它的职责就像数据库中的索引
”。因此博文下面将index.dat看做是DCMTK中自定义的一种用于记录相关信息的索引数据库文件,主要用于dcmqrscp.exe、dcmqridx.exe、dcmqrti.exe等工具包中。

下面就会通过分析和实际使用dcmqrscp.exe、dcmqridx.exe和dcmqrti.exe工具包来分析index.dat数据库文件。

dcmqrscp.exe操作:

关于dcmqrscp.exe的相关介绍参照之前的博文DICOM医学图像处理:DCMTK的wiki资料学习之PACS调试

dcmqridx.exe操作:

之前博文对dcmqrscp.exe的介绍侧重于DIMSE服务,如C-ECHO、C-FIND、C-STORE、C-MOVE等,并未提及内部的数据库部分。既然dcmqrscp能够响应C-FIND请求,那么其内部自然实现了数据库功能,用于存储C-STORE上传的相关记录。

重新查看DCMTK的官方说明文档,也可以发现dcmqridx、dcmqrscp、dcmqrti三个工具同属于dcmqrdb模块,DCMTK文档称之为an image database server。

如果再仔细翻看dcmqrscp.exe工具包的源码会发现,在正式处理链接请求之前,是数据库相关操作,具体代码如下:

#ifdef WITH_SQL_DATABASE
    // use SQL database
    DcmQueryRetrieveSQLDatabaseHandleFactory factory;
#else
    // use linear index database (index.dat)
    DcmQueryRetrieveIndexDatabaseHandleFactory factory(&config);
#endif

    DcmQueryRetrieveSCP scp(config, options, factory);
    scp.setDatabaseFlags(opt_checkFindIdentifier, opt_checkMoveIdentifier);

    /* loop waiting for associations */
    while (cond.good())
    {
      cond = scp.waitForAssociation(options.net_);
      if (!options.singleProcess_) scp.cleanChildren();  /* clean up any child processes */
    }

    cond = ASC_dropNetwork(&options.net_);
    if (cond.bad()) {
      OFLOG_FATAL(dcmqrscpLogger, "cannot drop network: " << DimseCondition::dump(temp_str, cond));
      return 10;
    }

由于目前DCMTK还未实现DcmQueryRetrieveSQLDatabaseHandle相关类,因此windows系统中的dcmqrscp.exe工具包使用的是DcmQueryRetrieveDatabaseIndexDatabaseHandle,即index.dat对应的索引数据库。

查看DcmQueryRetrieveIndexDatabaseHandle类定义,其内部包含了数据库句柄,类型为DB_PrivateHandle,这是一个结构体,具体定义如下:

struct DB_Private_Handle
{
    int pidx ;
    DB_ElementList *findRequestList ;
    DB_ElementList *findResponseList ;
    DB_LEVEL queryLevel ;
    char indexFilename[DBC_MAXSTRING+1] ;
    char storageArea[DBC_MAXSTRING+1] ;
    long maxBytesPerStudy ;
    long maxStudiesAllowed ;
    int idxCounter ;
    DB_CounterList *moveCounterList ;
    int NumberRemainOperations ;
    DB_QUERY_CLASS rootLevel ;
    DB_UidList *uidList ;

    DB_Private_Handle()
    : pidx(0)
    , findRequestList(NULL)
    , findResponseList(NULL)
    , queryLevel(STUDY_LEVEL)
//  , indexFilename()
//  , storageArea()
    , maxBytesPerStudy(0)
    , maxStudiesAllowed(0)
    , idxCounter(0)
    , moveCounterList(NULL)
    , NumberRemainOperations(0)
    , rootLevel(STUDY_ROOT)
    , uidList(NULL)
    {
    }
};

从其构造函数可以判断出pidx记录的是index.dat文件的描述符,与文件句柄类似;indexFilename记录的是index.dat数据库文件的全路径;storageArea记录的是dcmqrscp.cfg配置文件中AETable部分中给出的与storagearea(在dcmqrcnf.txt文件中说明Application Entity Table部分中可针对不同的AE设置不同的storage area,因此启动dcmqrscp.exe后,可能会生成多个index.dat数据库文件,用于分别记录不同AE的操作)

大致了解了dcmqrscp.exe的数据操作后,让我们来实际测试一下,与dcmqrscp.exe工具包测试时公用同一个dcmqrscp.cfg配置文件,其路径为d:\DcmScuScp,

输入下面指令:

cd d:\DcmScuScp,此时可以注意到该路径下有一个曾经使用dcmqrscp.exe工具时生成的index.dat文件,这里为了更清楚的说明index.dat的记录操作,我们将其删除,确保当前目录下不存在index.dat文件。

dcmqridx.exe –d d:\DcmScuScp\ c:\test1.dcm,为了了解更多的信息,我们采用调试状态,添加-d参数。

从输出结果中我们可以大致猜测出,index.dat文件中记录的应该就是上图中罗列的各种信息,然我们打开D:\DcmScuScp目录,使用UltriEdit打开刚生成的index.dat文件,其内容如下:

将标尺拖动到文件后半部分,可以发现dcmqridx.exe调试状态输出的各种信息,例如StudyDate、StudyTime、SeriesNumber、InstanceNumber、Modality、SeriesInstanceUID、SOPInstanceUID等等,由此可以看出index.dat数据库文件就是按照统一的格式来记录每一个dcm文件的相关信息,包含了DICOM常见的关系型数据库中的四级结构所需的全部信息。当然index.dat并非是对每个dcm文件信息简单的在文件末尾进行追加填写,例如添加完test1.dcm文件都index.dat文件大小约为48k,而再添加test2.dcm文件索引后index.dat文件大小变为52k。

dcmqrti.exe操作:

了解了index.dat的基本结构,以及如何手动向index.dat数据文件总添加记录,那么我们又该如何查看index.dat数据文件中的记录呢?dat文件并非是一种统一的标准格式,再未拿到具体协议之前我们无法精确解析index.dat文件,不过还好DCMTK已经为我们提供了一款工具,它就是dcmqrti.exe。

官网对dcmqrti.exe的描述如下:

The dcmqrti program (telnet initiator) is an interactive character based program intended to be used for examining the dcmqrscp image databases and sending images contained within these databases to Vendor nodes.

——dcmqrti是用于检测dcmqrscp图像数据库,即index.dat,的一种交互工具,还可以将index.dat中记录的图像发送到其他DICOM终端(该终端需要在dcmqrscp.cfg的Host Table中进行注册)。

下面我们进行实际测试:

输入dcmqrti.exe可以看到关于该工具包使用的简单介绍,如下图左:

dcmqrti工具必须的唯一参数就是在dcmqrscp.cfg配置文件Vendor Table中注册的vendor节点,博文DICOM医学图像处理:DCMTK的wiki资料学习之PACS调试配置文件中的vendor是acmeCTcompany,该vendor包含了Host Table中的所有节点,Host
Table中的节点就是PACS系统中通常需要配置的各个客户端的节点信息,即AETitle、IP、Port。输入下面指令可看到上图右侧的结果

dcmqrti.exe acmeCTcompany

此刻命令提示符变为ACME_STORE->ACME1>,其中ACME_STORE是dcmqrscp.cfg配置文件中AETable部分设置的本地存储的Title,ACME1是Host Table中设置的某个AE Title(dcmqrt.exe工具默认选择Host Table中的第一个节点)。说明我们进入dcmqrscp数据库index.dat的控制状态。

此刻输入help,如下所示:

我们接下来逐个测试上面的指令,

1)title查看/设置当前AE

输入:title

可以看到在dcmqrscp.cfg配置文件中Host Table部分的所有Host节点,其中带星号的是当前默认,也就是ACME1

输入:title 1

可以看到命令提示符变成ACME_STORE->ACME2>,说明当前host节点的AETitle变为ACME2

2)database查看/设置当前数据库

输入:database

可以看到dcmqrscp.cfg配置文件中AETable部分设置的本地存储的Title,由于此次配置文件中只指定了一个存储区域即ACME_STORE,存储路径为d:\DcmScuScp,因此就只生成了一个index.dat文件。

3)study/series/image查看数据库相关信息

分别输入study、series、image指令可查看刚才通过dcmqridx.exe手动注册的dcm的相关信息,如下图所示:

4)send发送数据库中的数据

此处为了方便,只是用send image来发送刚才上传的test1.dcm文件到指定的节点。

重新开启一个命令行程序,开启C-STORE SCP服务,输入:storescp.exe –d 11110 –aet ACME2

storescp此处的参数是依照dcmqrscp.cfg配置文件中Host Table部分来填写的,为了方便查看直接将dcmqrscp.cfg配置文件截图如下:

在dcmqrti.exe客户端输入:send image,具体结果如下图所示:

转到DcmData目录下,可以看到顺利接收到了dcm图像,如下图:

然后输入quit或exit顺利退出dcmqrti.exe控制状态。

至此对于DCMTK中的dcmqrscp.exe、dcmqridx.exe和dcmqrti.exe工具包的介绍就告一段落了,通过此次亲自测试大致了解了dcmqrscp工具中存储记录数据的方式,以及所采用的数据库文件index.dat,同时在上一篇博文的基础上,对dcmqrscp.cfg配置文件中的各项参数有了更进一步的认识,后续会再进一步详细研究,尝试替换dcmqrscp.exe工具中默认的索引数据库方式,改用sqlite或者mysql,敬请期待……

后续博文介绍:

利用fo-dicom搭建简单的PACS Server服务端

dcmqrscp.exe工具包中的数据库的替换

作者:[email protected]

时间:2015-01-11

时间: 2024-10-11 12:26:27

DICOM:DCMTK工具包分析之dcmqrscp.exe、dcmqridx.exe、dcmqrti.exe的相关文章

DICOM医学图像处理:基于DCMTK工具包学习和分析worklist

背景: DICOM3.0协议中有介绍关于worklist的部分.简而言之,worklist可以看做是放射科设备从医院RIS系统中自动读取患者信息的一种"通信协议",可以指存储在RIS系统中的患者数据库,主要包括患者的基本信息(如年龄.性别.身高.体重.出生年月等),这与DCM文件信息头MetaInfo中的多数字段重合.因此从RIS系统中自动获取worklist是医院信息化的必要组成部分.下面简单的给出几个图像,形象的描述一下worklist的作用. worklist的实例学习: 在简单

Debug目录、Release目录,bin目录、obj目录,vshost.exe.config文件、.exe.config文件分析【C#】

Debug目录.Release目录,bin目录.obj目录,vshost.exe.config文件..exe.config文件分析[C#] 2013-10-06  孤风卓影  摘自 csdn博客  阅 558  转 4 转藏到我的图书馆 微信分享: 今天写程序的时候,需要更改.exe.config文件中的引用的webservice地址,用vs调试的时候,发现会修改vshost.exe.config中的对应项,.exe.config中的对应项是不会修改的,这样会导致在软件重启的情况下,.exe.c

QT编译出现ld.exe: cannot open output file debug\nh_03testCallPy.exe: Permission denied collect2.exe: error: ld returned 1 exit status

D:/Qt/Qt5.9.0/Tools/mingw530_32/bin/../lib/gcc/i686-w64-mingw32/5.3.0/../../../../i686-w64-mingw32/bin/ld.exe: cannot open output file debug\nh_03testCallPy.exe: Permission denied collect2.exe: error: ld returned 1 exit status 原因目前可能有如下: 1.程序已经在运行,进入

链接器link.exe 编译器cl.exe 资源编译器rc.exe

原文地址:https://blog.csdn.net/biggbang/article/details/24433065 1.cl.exe文件是Visual C\C++的编译器,它将程序源代码文件编译为obj文件. 2.rc.exe文件是资源编译器.工程项目中的.rc文件中包含了对程序中所使用资源(菜单.图标等)的描述.rc.exe将.rc格式的文件编译为.res文件,供链接器链接到可执行文件中. 3.link.exe是Windows平台的链接器,它将cl.exe编译生成的obj文件,资源编译器

nwjs如何打包文件为exe文件并修改exe图标

1.下载nw.js,如果是SDK版的可以调试页面,打包后可不可以调试还没有试,不是SDK的话没有调试选项,试了一下,打包后的文件也一样调试不了. 2.把要打包的文件和package.json都放在nw.js同级文件夹下,package.json是入口的配置文件,没搞好的话进行不了.先运行一下nw.exe看可不可以正常运行,如果可以正常运行的话就可以打包了,要改生成的软件的图标的话在这里就把nw.exe的图标改了,先用"IconWorkshop.exe"生成一套ico图标,接着用&quo

adb用不了,error: unknown host service的解决办法 (360的360MobileLoader.exe,QQ的tadb.exe)

这里贴上辨别电脑的5037端口被哪个应用程序占用的方法: 1. 打开命令行,输入命令:netstat -ano | findstr "5037" 360需关闭 自我保护功能才能关闭掉360MobileLoader.exe. QQ需关闭掉tadb.exe. http://bbs.xda.cn/thread-11656869-1-1.html 近日在命令行中使用adb命令时老是会提示 error: unknown host service的错误, 以前一直是正常的,从未出过问题.网上搜索一

py2exe生成exe后,运行exe时提示No module named * 的解决办法

根据 http://www.tuicool.com/articles/7RbU3i ,应该是没有显式地import相关module. 运行exe的时候提示缺什么模块就import什么模块,并在代码里面显示的调用一次 http://www.pceworld.com/view/6937505 1.In the program you are trying to import (eg. in the A.py for A.exe ), specify import statement for _mss

DICOM医学图像处理:DCMTK的wiki资料学习之PACS调试

背景: 前段时间着重从dcmtk和fo-dicom(mDCM)源码角度进行剖析,期望加深对DICOM协议的理解.知其然,知其所以然.如果"所以然"很不好懂,那我们还是先多多"知其然"吧.搞清楚原理的目的不也是为了更好的运用于实践么?所以理论和实践应该彼此交错进行,理论搞不动了就搞搞应用,应用久了就钻研钻研理论. 以前上DCMTK官网仅仅是浏览关于开源库中各个类的设计模式.依赖关系.最近在打开DCMTK官网的wiki时,才发现OFFIS对DCMTK的介绍是如此的详细.

DICOM:dcmqrscp.exe与storescu.exe中C-STORE服务的差别

背景: 专栏中曾分别写过dcmqrscp.exe与storescu.exe工具包的介绍,但是并未深究两者之间的差别.dcmqrscp.exe工具是一个mini版PACS,可分别响应C-FIND.C-MOVE.C-GET.C-STORE等各种DIMSE服务,而storescu.exe工具是C-STORE服务使用者,可以看出这两个工具包都提供C-STORE SCU服务.前几天博友的一个问题使得重新研究了一下两者在实现C-STORE SCU服务上的差别.通过源码分析发现问题根源出在Presentati