`
qimo601
  • 浏览: 3445858 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

【最新snapshot】DCMTK3.6.1(MD支持库)安装说明

阅读更多

 

【前言】 

       最近,因为需要开发DICOM网管模块,必须使用DCMTK的DcmNet模块。但是DCMTK3.6.0在DcmNet模块中只提供两个实验阶段的网络类DcmSCU和DcmSCP。而且他们并没有完全实现DICOM的C-Echo、C-Find、C-Get、C-Move和C-store操作。只实现了C-Echo和C-Find操作。


      调研了一番,发现DCMTK小组在最新的snapshot版本中(DCMTK3.6.1 2012-08-31),已经实现了DICOM全部操作。而且他们官方论坛中,开发人员在回答疑问时候,针对3.6.0中出现的bug等问题。他们也是鼓励大家直接用最新的DCMTK3.6.1.

当然他们也建议大家自己去通过底层代码实现DcmScu的其他的操作。不过对于我们这种新手来讲确实很困难,而且关键问题在后期的3.6.1版本的代码变化很大。我们自己手写的,以后不方便兼容。


       所以最终我还是下载了最新的DCMTK3.6.1-20120831,但是他有一个问题,目前只支持在linux上编译和运行。windows环境,他们并没有提供支持库。于是又让我踌躇了一番,自己也手动试着基于3.6.0写了点代码,但是真的是超级难。最终下定决心在win7上编译3.6.1,并利用DCMTK3.6.0的support(MD)Library。在DCMTK官方论坛开发人员的帮助下,最终编译成功。也实现DcmScu的例子网络访问。

 

【开发环境】

操作系统:win7 32bit

开发工具:VS2008 + Qt4.7.4

1、DCMTK: DCMTK3.6.120120831

2、DCMTK support libraries for windows: dcmtk-3.6.0-win32-i386-support_MD.zip

3、CMake:cmake-2.8.9-win32-x86.exe

 

目前我的Qt项目都是基于MD/MDd的运行时库。

 

【安装过程】

1、将支持库中的相应lib文件,include文件,bin文件拷贝到VS2008安装目录的相应文件夹下。

        A.在解压得到的支持库的文件夹下搜索_d.lib文件(xxx_d.lib为DEBUG版本的支持库,xxx_o.lib为RELEASE版本支持库),应该会得到7个结果,将这些文件复制到一个单独的文件夹下,并把它们的名字中的_d去掉,例如将zlib_d.lib重命名为zlib.lib。将重命名后的文件拷贝至VS2008安装目录下的lib文件夹下,在我的win7 32bit电脑上是C:\Program Files\Microsoft Visual Studio 9.0\VC\lib\

B. 在解压得到的支持库的文件夹下搜索include,应该得到5个文件夹,将这些文件夹复制到C:\Program Files\Microsoft Visual Studio 9.0\VC\下,选择合并文件夹,也就是将include文件夹下的内容全部复制到C:\Program Files\Microsoft Visual Studio 9.0\VC\include\目录下。

C.将D:\DCMTK\dcmtk-3.6.0-win32-i386-support_MD\openssl-1.0.0c\bin下的五个文件复制到C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\下。

 

 

 

2、CMake编译

         A、设置source code 路径:    D:\DCMTK\dcmtk-3.6.1_20120831

 B、设置binaries路径:          D:\DCMTK\DCMTK-bin

 C、选择Configure:visual studio 9 2008

         D、等待configure完毕后,会有很多find和not find,无所谓。

         E、选中Advanced单选框,然后在红色区域设置:

             set DCMTK_OVERWRITE_WIN32_COMPILER_FLAG = OFF;(不选中,这样可以使生成项目运行时库都是MD/MDd,而不是默认的MT/MTd)

     set "DCMTK_WITH_ICONV" to "ON" (选中)

     set "DCMTK_WITH_OPENSSL" to "ON"(选中)

     set "DCMTK_WITH_PNG" to "ON" (选中)

             set "DCMTK_WITH_TIFF" to "ON" (选中)          

             set "DCMTK_WITH_XML" to "ON" (选中)

             set "DCMTK_WITH_ZLIB" to "ON" (选中)

 F、点击Generate,很快就完成。这时候VS项目源码已经生成。

 

3、VS2008编译项目源码

 


        A、用VS打开 D:\DCMTK\DCMTK-bin\DCMTK.sln

        B、点击Build->Batch Build,选择ALL_BUILD项目的debug版,点击右边的Build。耐心等待。会有很多个warning,应该是由字符编码不统一引起的。最后会看到82个编译 成功,0个失败。

       C、再选择Build->Batch Build,这次选择INSTALL项目的debug版本,点击右边的Build。最后会显示1个工程编译成功,这时在你选择的安装目录下(默认是C:\Program Files\DCMTK)就会有lib,bin,include,etc,share文件夹,里面就是之后写程序做医学图像处理所需要的库文件了

 

4、代码测试

 

 

A. 新建一个Qt application,把以上源代码复制粘贴进main.cpp去。 B. 右键单击工程名,选择属性(properties),在Configuration Properties->C/C++->General下,
Additional Include Directories里加入上一步编译出来的include文件夹,我的Win7 32bit电脑上是
C:\Program Files\DCMTK\include,这一步是为了让程序能够找到头文件。
C. C/C++->code generation里,Runtime Library 选择/MDd,这一步是要和之前CMAKE的编译选项一致。
(我的Qt项目默认就是/MDd) D. Linker->General里,Additional Library Directories里填写上一步编译出来的lib文件夹,我的Win7 32bit
电脑上是C:\Program Files\DCMTK\lib,这一步是为了让程序能够找到之前编译好的lib文件。
E. Linker->Input里,在Additional Dependencies 里依次加上
wsock32.lib netapi32.lib ofstd.lib oflog.lib dcmdata.lib dcmnet.lib zlib.lib
这一步是加入具体我们程序需要的lib文件。

 

F. Debug,ok,编译工程,运行成功。访问了www.dicomserver.co.uk的DICOM服务器。

源代码如下:

 

The code uses the public DICOM server at www.dicomserver.co.uk which is offered by Dave Harvey (MedicalObjects). :-) There are also logs you can check at the server in order to debug your application.

 

/* 
 * 
 *  Copyright (C) 2011-2012, OFFIS e.V. 
 *  All rights reserved.  See COPYRIGHT file for details. 
 * 
 *  This software and supporting documentation were developed by 
 * 
 *    OFFIS e.V. 
 *    R&D Division Health 
 *    Escherweg 2 
 *    D-26121 Oldenburg, Germany 
 * 
 * 
 *  Module:  dcmnet 
 * 
 *  Author:  Michael Onken 
 * 
 *  Purpose: Test for move feature of the DcmSCU class 
 */ 
 
#include "dcmtk/config/osconfig.h"    /* make sure OS specific configuration is included first */ 
#include "dcmtk/dcmnet/testscu.h" 
#include "dcmtk/dcmnet/diutil.h" 
 
#define OFFIS_CONSOLE_APPLICATION "testscu" 
 
static OFLogger echoscuLogger = OFLog::getLogger("dcmtk.apps." OFFIS_CONSOLE_APPLICATION); 
 
static char rcsid[] = "$dcmtk: " OFFIS_CONSOLE_APPLICATION " v" 
  OFFIS_DCMTK_VERSION " " OFFIS_DCMTK_RELEASEDATE " $"; 
 
// our application entity title used for calling the peer machine 
#define APPLICATIONTITLE     "TEST-SCU" 
 
// host name of the peer machine 
#define PEERHOSTNAME         "www.dicomserver.co.uk" 
 
// TCP/IP port to connect to the peer machine 
#define PEERPORT 11112 
 
// application entity title of the peer machine 
#define PEERAPPLICATIONTITLE "MOVESCP" 
 
// MOVE destination AE Title 
#define MOVEAPPLICATIONTITLE "TEST-SCU" 
 
static Uint8 findUncompressedPC(const OFString& sopClass, 
                                DcmSCU& scu) 
{ 
  Uint8 pc; 
  pc = scu.findPresentationContextID(sopClass, UID_LittleEndianExplicitTransferSyntax); 
  if (pc == 0) 
    pc = scu.findPresentationContextID(sopClass, UID_BigEndianExplicitTransferSyntax); 
  if (pc == 0) 
    pc = scu.findPresentationContextID(sopClass, UID_LittleEndianImplicitTransferSyntax); 
  return pc; 
} 
 
// ******************************************** 
 
int main(int argc, char *argv[]) 
{ 
  /* Setup DICOM connection parameters */ 
  OFLog::configure(OFLogger::DEBUG_LOG_LEVEL); 
  DcmTestSCU scu; 
  // set AE titles 
  scu.setAETitle(APPLICATIONTITLE); 
  scu.setPeerHostName(PEERHOSTNAME); 
  scu.setPeerPort(PEERPORT); 
  scu.setPeerAETitle(PEERAPPLICATIONTITLE); 
  // Use presentation context for FIND/MOVE in study root, propose all uncompressed transfer syntaxes 
  OFList<OFString> ts; 
  ts.push_back(UID_LittleEndianExplicitTransferSyntax); 
  ts.push_back(UID_BigEndianExplicitTransferSyntax); 
  ts.push_back(UID_LittleEndianImplicitTransferSyntax); 
  scu.addPresentationContext(UID_FINDStudyRootQueryRetrieveInformationModel, ts); 
  scu.addPresentationContext(UID_MOVEStudyRootQueryRetrieveInformationModel, ts); 
  scu.addPresentationContext(UID_VerificationSOPClass, ts); 
 
  /* Initialize network */ 
  OFCondition result = scu.initNetwork(); 
  if (result.bad()) 
  { 
    DCMNET_ERROR("Unable to set up the network: " << result.text()); 
    return 1; 
  } 
 
  /* Negotiate Association */ 
  result = scu.negotiateAssociation(); 
  if (result.bad()) 
  { 
    DCMNET_ERROR("Unable to negotiate association: " << result.text()); 
    return 1; 
  } 
 
  /* Let's look whether the server is listening: 
     Assemble and send C-ECHO request 
   */ 
  result = scu.sendECHORequest(0); 
  if (result.bad()) 
  { 
    DCMNET_ERROR("Could not process C-ECHO with the server: " << result.text()); 
    return 1; 
  } 
 
  /* Assemble and send C-FIND request */ 
  OFList<QRResponse*> findResponses; 
  DcmDataset req; 
  req.putAndInsertOFStringArray(DCM_QueryRetrieveLevel, "STUDY"); 
  req.putAndInsertOFStringArray(DCM_StudyInstanceUID, ""); 
  T_ASC_PresentationContextID presID = findUncompressedPC(UID_FINDStudyRootQueryRetrieveInformationModel, scu);
  if (presID == 0) 
  { 
    DCMNET_ERROR("There is no uncompressed presentation context for Study Root FIND"); 
    return 1; 
  } 
  result = scu.sendFINDRequest(presID, &req, &findResponses); 
  if (result.bad()) 
    return 1; 
  else 
    DCMNET_INFO("There are " << findResponses.size() << " studies available"); 
 
  /* Assemble and send C-MOVE request, for each study identified above*/ 
  presID = findUncompressedPC(UID_MOVEStudyRootQueryRetrieveInformationModel, scu); 
  if (presID == 0) 
  { 
    DCMNET_ERROR("There is no uncompressed presentation context for Study Root MOVE"); 
    return 1; 
  } 
  OFListIterator(QRResponse*) study = findResponses.begin(); 
  Uint32 studyCount = 1; 
  OFBool failed = OFFalse; 
  // Every while loop run will get all image for a specific study 
  while (study != findResponses.end() && result.good())
  { 
    // be sure we are not in the last response which does not have a dataset 
    if ( (*study)->m_dataset != NULL) 
    { 
      OFString studyInstanceUID; 
      result = (*study)->m_dataset->findAndGetOFStringArray(DCM_StudyInstanceUID, studyInstanceUID); 
      // only try to get study if we actually have study instance uid, otherwise skip it 
      if (result.good()) 
      { 
        req.putAndInsertOFStringArray(DCM_StudyInstanceUID, studyInstanceUID); 
        // fetches all images of this particular study 
        result = scu.sendMOVERequest(presID, MOVEAPPLICATIONTITLE, &req, NULL /* we are not interested into responses*/); 
        if (result.good()) 
        { 
          DCMNET_INFO("Received study #" << std::setw(7) << studyCount << ": " << studyInstanceUID); 
          studyCount++; 
        } 
      }
    } 
    study++;
  } 
  if (result.bad()) 
  { 
    DCMNET_ERROR("Unable to retrieve all studies: " << result.text()); 
  }
  while (!findResponses.empty())
  {
    delete findResponses.front();
    findResponses.pop_front();
  }
  /* Release association */ 
  scu.closeAssociation(DCMSCU_RELEASE_ASSOCIATION);
  return 0; 
}
 

P.S: The header file would be trivial:

 

#ifndef TESTSCU_H 
#define TESTSCU_H 
 
#include "dcmtk/config/osconfig.h"  /* make sure OS specific configuration is included first */ 
 
#include "dcmtk/dcmnet/scu.h"     /* Covers most common dcmdata classes */ 
 
 
class DcmTestSCU : public DcmSCU 
{ 
 
public: 
 
  DcmTestSCU()  {} 
  ~DcmTestSCU() {} 
 
}; 
 
#endif // TESTSCU_H
 

 

参考文章:

1、DcmSCU example program

2、DCMTK3.6.0(MD支持库)安装说明

3、how to use DCMTK 3.6.1 on win7

 

 

------------------------------------ 

柳北风儿

http://qimo601.iteye.com

------------------------------------

 

DCMTK3.6.1编译失败总结

 

针对DCMTK3.6.1 编译的错误总结:

1、完全默认CMake配置, DCMTK编译成功。但无支持库externallibraries (OpenSSL, zlib, libtiff, libpng, libxml2 and libiconv)

结果:如果不加支持库,运行网上例子,肯定出错。1>Linking...1> LINK : fatal error LNK1181: cannot open input file 'zlib.lib'

2、设置了MD支持库,在VC里配置好文件,手动修改CMakeList.txt为MD/MDd。会出现如下错误:warning LNK4098: defaultlib 'MSVCRTD' conflicts with use of other libs; use等运行时库冲突错误。

 

3、按照DCMTK官方编译方法失败。官方配置CMake属性,加上3.6.0MD支持库,

 

libpng support:
set "DCMTK_WITH_PNG" to "ON" and
set "WITH_LIBPNGINC" e.g. to "C:\libpng-1.4.2"

libtiff support:
set "DCMTK_WITH_TIFF" to "ON" and
set "WITH_LIBTIFFINC" e.g. to "C:\tiff-3.9.2"

OpenSSL support:
set "DCMTK_WITH_OPENSSL" to "ON" and
set "WITH_OPENSSLINC" e.g. to "C:\openssl-1.0.0"

zlib support:
set "DCMTK_WITH_ZLIB" to "ON" and
set "WITH_ZLIBINC" e.g. to "C:\zlib-1.2.5"

libiconv support:
set "DCMTK_WITH_ICONV" to "ON" and
set "WITH_LIBICONVINC" e.g. to "C:\libiconv-1.14"
以及设置DCMTK_OVERWRITE_WIN32_COMPILER_FLAG = OFF;

  缺少libiconv的编译后的支持库。

  最后还是按照如上方法,完全实现DCMTK3.6.1在win7上的编译。

 

 

 

  • 大小: 109.4 KB
  • 大小: 91.2 KB
0
1
分享到:
评论

相关推荐

    前端开源库-snapshot-diff

    1. **安装库**:首先需要在项目中安装 "snapshot-diff",通常通过npm或yarn完成。 2. **导入库**:在测试脚本中引入库,以便使用其提供的功能。 3. **创建快照**:在Jest测试用例中使用`toMatchSnapshot()`或`expect...

    NetBackup1011_SnapshotManager_InstallGuide.pdf

    1. **SnapshotManager支持的平台**:NetBackup SnapshotManager支持Ubuntu、Red Hat Enterprise Linux (RHEL)和SUSE Linux Enterprise Server (SLES)等操作系统。这意味着用户可以在这些Linux环境下部署Snapshot...

    netcdfAll-5.5.4-SNAPSHOT.jar

    标题 "netcdfAll-5.5.4-SNAPSHOT.jar" 暗示我们正在讨论一个与NetCDF(Network Common Data Form)相关的Java库,版本号为5.5.4,标记为SNAPSHOT版本。SNAPSHOT版本通常表示这是一个开发中的不稳定版本,开发者可能...

    springsecurity-0.0.1-SNAPSHOT.jar及安装方式.zip

    配置pom文件爆红,springsecurity-0.0.1-SNAPSHOT.jar下载不下来,这里面有 springsecurity-0.0.1-SNAPSHOT.jar 和它的安装执行语句

    截图小工具,snapshot

    1. 保存格式:Snapshot支持多种图片格式输出,如常见的JPG、PNG、BMP等。用户可以根据需求选择合适的格式进行保存。 2. 快速分享:除了保存到本地,Snapshot还提供了直接分享至社交媒体、邮件、云存储服务等选项,...

    apache-maven-3.6.1

    SNAPSHOT版本会自动检查远程仓库是否有更新,并自动下载最新的版本。 8. **仓库管理**:Maven使用本地仓库存储已下载的依赖,同时可以连接到远程仓库,如Maven Central Repository。企业还可以设置私有仓库来托管...

    x64dbg(最新snapshot集合多个插件及皮肤)

    标题中的“最新snapshot”指的是x64dbg的一个快照版本,这是一个特定时间点的软件构建,包含了开发者的最新改进和修复。这种快照通常在官方正式版本发布之间提供,供用户测试新功能或bug修复。描述中提到的“集合多...

    netapp存储配置练习_snapshot

    NetApp 存储配置练习专注于Snapshot技术,这是一种高效的数据保护和恢复工具,尤其适用于NetApp的WAFL(Write Anywhere File Layout)文件系统。Snapshot在NetApp存储解决方案中扮演着核心角色,它允许用户创建几乎...

    jamod-1.2-SNAPSHOT.jar

    2. **Modbus RTU通信**:对于串行通信,jamod库支持RTU模式,通过RS-232或RS-485接口与Modbus设备建立连接。 3. **数据类型转换**:jamod库将Modbus的寄存器和线圈等抽象为Java对象,方便开发者处理数值、字符串等...

    SnapShot系统备份恢复双语安装版

    SnapShot系统备份恢复

    snapshot 1.49 中文版

    这两个文件很可能是Snapshot 1.49的安装程序,其中"snapshot64.exe"是64位版本,适用于64位的Windows操作系统,而"snapshot.exe"可能是32位版本,适用于32位系统。用户应根据自己的系统架构选择合适的版本进行安装。...

    fastdfs-client-java-1.29-SNAPSHOT.jar

    解决 Maven 无法下载 fastdfs-client-java-1.29-SNAPSHOT 依赖,直接下载之后用maven命令存储到本地maven仓库即可。 maven命令 mvn install:install-file -DgroupId=org.csource -DartifactId=fastdfs-client-java ...

    ffmpeg-snapshot-git.rar

    这个名为"ffmpeg-snapshot-git.rar"的压缩包文件,显然是从FFmpeg的官方网站上获取的最新源码版本,通过Git版本控制系统管理。 FFmpeg源码的学习和编译是深入理解其工作原理和定制化功能的关键步骤。首先,你需要...

    xxl-job-admin-2.4.1-SNAPSHOT之oracle版

    在部署此版本之前,你需要确保你的Oracle数据库已经准备好,包括但不限于创建数据库用户、权限分配以及安装必要的Oracle驱动。部署过程中,需要将XXL-JOB的配置文件中的数据库连接信息替换为实际的Oracle数据库连接...

    JNDIExploit-1.4-SNAPSHOT.jar

    编译后的JNDIExploit-1.4-SNAPSHOT.jar,可以直接用,1.4版本支持tomcatBypass路由直接上线msf。

    marshalsec-0.0.3-SNAPSHOT-all.jar

    marshalsec-0.0.3-SNAPSHOT-all.jar

    geoserver-2.20-SNAPSHOT-authkey-plugin.zip

    在提供的压缩包文件中,我们可以看到几个关键的依赖库,这些库支持了AuthKey插件的功能: 1. **httpclient-4.5.13.jar** 和 **httpclient-cache-4.5.13.jar**:这是Apache HttpClient库的版本,用于处理HTTP请求和...

    Go-Snapshot采用纯Golang编写的强大可持久化Key-Value(KV)存储

    3. **数据持久化**:Go-Snapshot支持数据持久化,即使在系统崩溃或断电后,也能保证数据的完整性,这得益于其底层的文件系统支持和定期的快照机制。 4. **高性能**:通过优化的I/O调度和数据结构设计,Go-Snapshot...

    简单小巧的截屏工具SnapShot

    与市面上许多大型的截屏软件相比,SnapShot无需安装,用户只需下载并双击SnapShot.exe文件,即可轻松启动,这种轻量级的设计使得它在任何环境下都能快速启动,不占用过多系统资源。 该工具的核心功能与QQ的截图功能...

Global site tag (gtag.js) - Google Analytics