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安装目录的相应文件夹下。



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、代码测试
B. 右键单击工程名,选择属性(properties),在Configuration Properties->C/C++->General下,
D. Linker->General里,Additional Library Directories里填写上一步编译出来的lib文件夹,我的Win7 32bit
netapi32.lib
ofstd.lib
oflog.lib
dcmdata.lib
dcmnet.lib
zlib.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
参考文章:
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支持库,
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上的编译。
DCMTK3.6.1(MD支持库)安装说明的更多相关文章
- DCMTK3.6.0(MD支持库)安装说明
一.运行环境:WIN7 32bit + VisualStudio2008 + dcmtk3.6.0 + Cmake2.8.8 或者 WIN7 64bit 二.准备工作: 1)MD/MT的知识储备: / ...
- DCMTK3.6.0 (MT支持库)安装 完整说明
环境WIN7 + VisualStudio2010 + dcmtk3.6.0 + Cmake2.8.6 准备工作: 从dcmtk官方网站下载源代码及支持库文件.分别名为:dcmtk-3.6.0 dcm ...
- Linux下安装PHP的GD支持库
Linux下安装PHP的GD支持库 1.安装 zlib wget ftp://ftp.sunfreeware.com/pub/freeware/SOURCES/zlib-1.2.3.tar.gz ...
- linux中必备常用支持库的安装(CentOS)
在CentOS安装软件的时候,可能缺少一部分支持库,而报错.这里首先安装系统常用的支持库.那么在安装的时候就会减少很多的错误的出现 yum install -y gcc gdb strace gcc- ...
- phpize 扩展GD库 安装 ! 环境--centos 7 +nginx 1.7.11+php 5.6.7
使用phpize编译GD库安装,先安装前置库libjpeg libpng zlib freetype等 都是下面php编译的几个选项 先看php编译的选项: --with-gd=DIR ...
- Windows2003/2008/2008 R2下易语言点支持库配置就退出的问题
问题: 请问一个问题,我的电脑上win2003系统的,安装了易语言后,一点支持库配置就会自动退出.这是为什么啊? 解决方法如下: 删除 lib下的wmp.npk,重新打开易语言就可以了.
- sqlserver 无法初始化via支持库[QLVIPL.DLL]
安装数据库后,在sqlserver configuration manager, sqlserver的网络配置,有将协议 shared memory,named pipes,tcp/ip,via全部启 ...
- centos 6.5常见lib库安装
在CentOS安装软件的时候,可能缺少一部分支持库,而报错.这里首先安装系统常用的支持库.那么在安装的时候就会减少很多的错误的出现. # yum install -y gcc gdb strace g ...
- 双心一键获取winsxs的写入权限,解决VC运行库安装error1935错误
@Echo offtitle 双心一键获取winsxs的写入权限,解决VC运行库安装error1935等错误set path=%path%;%~dp0setlocal EnableDelayedExp ...
随机推荐
- [poj3274]排排站(Hash)
题目:http://poj.org/problem?id=3274 题目大意:http://www.wikioi.com/problem/1247/ (此题中文版) 分析: 令sum[i][j]表示a ...
- [C#]Main(String[] args)参数输入问题
Main函数是程序的入口点,它是入口点,那它的参数,又是怎样来的呢?首先写个简单的测试程序看看args到底是什么? class Program { static void Main(string[] ...
- Java设计模式-策略模式(strategy)
策略模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响到使用算法的客户.需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口,设计一个抽象类(可有可无 ...
- Hibernate-二级缓存策略
二级缓存的策略 当多个并发的事务同时访问持久化层的缓存中的相同数据时,会引起并发问题,必须采用必要的事务隔离措施. 在进程范围或集群范围的缓存,即第二级缓存,会出现并发问题.因此可以设定以下4种类型的 ...
- Spring-事物传播行为
spring事物的传播属性(7种) REQUIRED(默认) 业务方法需要在一个容器里运行.如果方法运行时,已经处在一个事务中,那么加入到这个事务,否则自己新建一个新的事务. 存在事物,则使用当前事物 ...
- 【XDU1144】合并模板
问题 Fate 有 n 个 ACM/ICPC 比赛的模板,每个都是一个独立的 PDF 文件.为了便于打印,万神希望将这些模板合并成一个 PDF 文件.万神有一个工具,可以将至多 k 个 PDF 文件合 ...
- BZOJ3098 Hash Killer II
Description 这天天气不错,hzhwcmhf神犇给VFleaKing出了一道题: 给你一个长度为N的字符串S,求有多少个不同的长度为L的子串. 子串的定义是S[l].S[l + 1].... ...
- wifi与wimax
这几天在看文献中看到802.11a,802.11n和802.16e这几种无信通信协议标准,在网上查了相关资料后,看到有个帖子总结得不错,故将其转载过来. 转:http://blog.csdn.net/ ...
- ASP.NET MVC ActionFilterAttribute的执行顺序
http://diaosbook.com/Post/2014/6/3/execution-order-of-actionfilter-aspnet-mvc ASP.NET MVC里面我们要自定义Act ...
- resharper安装后,一不小心点错了(选择了object browser)
打开Resharper,选择Options,然后选择Tools中的External Sources,你的情况是选择了Navigation to Object Brower这一项了,换成第一个Defau ...