最近的课堂作业接触到了关于医学图像格式Dicom的一些开发,在经过将近一个学期硬着头皮上的学习后,最终,在这里记录一些过程中遇到的问题。
由于在学习过程中,互联网上找到的资料多是关于DCMTK 3.6.0的安装准备,大都有一些过时,且有效信息分布得比较散乱,所以这篇文章先简单记录一下DCMTK 3.6.2开发环境的搭建,以备日后不时之需。
DCMTK是由德国offis公司提供的开源项目,利用C++实现,经过十多年的开发和维护,已经基本实现了Dicom协议的所有内容,且提供了所有源代码、支持库和帮助文档,自然就成了本次课程项目的不二之选。
作者柳北风儿在一篇关于DCMTK 3.6.0编译的博文中提到
MD/MT的知识储备:
/MT和/MTd表示采用多线程CRT库的静态lib版本。该选项会在编译时将运行时库以静态lib的形式完全嵌入。该选项生成的可执行文件运行时不需要运行时库dll的参加,会获得轻微的性能提升,但最终生成的二进制代码因链入庞大的运行时库实现而变得非常臃肿。当某项目以静态链接库的形式嵌入到多个项目,则可能造成运行时库的内存管理有多份,最终将导致致命的“Invalid Address specified to RtlValidateHeap”问题。另外托管C++和CLI中不再支持/MT和/MTd选项。
/MD和/MDd表示采用多线程CRT库的动态dll版本,会使应用程序使用运行时库特定版本的多线程DLL。链接时将按照传统VC链接dll的方式将运行时库MSVCRxx.DLL的导入库MSVCRT.lib链接,在运行时要求安装了相应版本的VC运行时库可再发行组件包(当然把这些运行时库dll放在应用程序目录下也是可以的)。
因/MD和/MDd方式不会将运行时库链接到可执行文件内部,可有效减少可执行文件尺寸。当多项目以MD方式运作时,其内部会采用同一个堆,内存管理将被简化,跨模块内存管理问题也能得到缓解。
结论:/MD和/MDd将是潮流所趋,/ML和/MLd方式请及时放弃,/MT和/MTd在非必要时最好也不要采用了。
DCMTK3.6.2的源代码和已经编译完成的可执行文件都可以在其官网上直接下载。
需要注意的是在下载MD支持库时,要正确选择对应的操作系统版本以及Visual Studio版本,在这里我们选择下载:
dcmtk-3.6.2-win64-support_MD-msvc-15.0.zip
Pre-compiled libraries for Visual Studio 2017 (MSVC 15.0), 64 bit, with “MD” option
对DCMTK源代码的生成需要用到Cmake。CMake版本的选择可能没有那么多讲究,本次直接选择了可以下载到的最新稳定版本3.10.0,但理论上更新的版本也可行。
还是要多嘴说一句,CMake的源码在本项目中没有用,下载时请选择Binary Distributions进行下载,同样也要选择对应操作系统的版本下载。
./dcmnet/apps/cmake_install.cmake
文件,全文搜索openssl
。便会发现此段引用了两个不存在的文件名dcmtkeay.dll
和dcmtkssl.dll
,将其分别修改成先前下载的支持库中 ./openssl-1.1.0f/bin/dcmtkcrypto_d-1_1-x64.dll
和 ./openssl-1.1.0f/bin/dcmtkssl_d-1_1-x64.dll
新建一个VC++空项目,设置工程解决方案配置为debug,解决方案平台为x64 ,添加源文件main.cpp。
进入菜单栏项目(P)–>YOUR_PROJECT_NAME_属性(注意修改的都是debug下的x64的配置,如果换成release要重新设置成release方案下的配置)。
左侧C/C++–>常规,右侧附加包含目录,设置为 C:\Program Files\DCMTK\include
(默认位置)。
左侧链接器–>常规,右侧附加库目录,设置为 C:\Program Files\DCMTK\lib
你下载并解压的支持库目录\zlib-1.2.11\lib
左侧链接器–>输入,右侧附加依赖项,设置为 Iphlpapi.lib
ws2_32.lib
wsock32.lib
netapi32.lib
ofstd.lib
oflog.lib
dcmdata.lib
dcmdsig.lib
dcmnet.lib
dcmsr.lib
dcmimgle.lib
dcmqrdb.lib
dcmtls.lib
dcmwlm.lib
dcmpstat.lib
dcmjpls.lib
dcmjpeg.lib
dcmimage.lib
charls.lib
ijg8.lib
ijg12.lib
ijg16.lib
i2d.lib
zlib_d.lib(Release版本删除_d)
附一张lib依赖关系图,之后遇到具体问题不用全数添加,选择需要的以及其依赖即可
//filename: main.cpp
#include "dcmtk\config\osconfig.h"
#include "dcmtk\dcmdata\dctk.h"
#include
void main() {
DcmFileFormat *myFileFormat = new DcmFileFormat;
OFCondition cond = myFileFormat->loadFile("c:/111.dcm");
if (cond.good()){
OFString patientName;
if (myFileFormat->getDataset()->findAndGetOFString(DCM_PatientName, patientName).good())
std::cout << "Patient Name: " << patientName << "\nTest successed.\n";
else std::cout << "No Patient Name Data!\n";
}
else std::cout << "Error occurs when opening file, check path or filename.\n";
system("pause");
}
最后附上测试用到的dicom格式图片。提取密码: cw3q
如果能够正确显示Patient Name参数,那么恭喜,DCMTK库已经完全正确地安装好了,可以进行下一步的开发工作了!