注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

在路上...

点滴感悟,成长记录...

 
 
 

日志

 
 

【Practice】DICOM开发工具DCMTK在VS2008下的编译、配置与实例  

2011-12-01 16:19:01|  分类: Practice |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

前两天S老师让帮他写一个由裸数据到DICOM格式图像的转化程序,所以就学了一点DICOM开发的相关知识,现记录一下。

一、DICOM简介

DICOM即数字影像和通信标准。在医学影像信息学的发展和PACS的研究过程中,由于医疗设备生产厂商的不同,造成与各种设备有关的医学图像存储格式、传输方式千差万别,使得医学影像及其相关信息在不同系统、不同应用之间的交换受到严重阻碍。为此,美国放射学会(ACR)和全美电子厂商联合会(NEMA)认识到急需建立一种标准,以规范医学影像及其相关信息的交换, DICOM(Digitalimaging and Communications in Medicine)标准就是在这样的背景下产生的。

二、DICOM 文件格式

DICOM 文件内容在 Part 3 DICOM IOD 里定义。CT, MR, CR, DR, US, NM, PET, XA 等各有自己的内容定义,由共同的专有的部分 (IE 和 Modules) 组成。
DICOM 文件内容由两个部分组成:存参数的 header 和图点数据 (pixel data)。
header 只描述图像的基本参数:如病人基本资料、检验基本资料、系列资料、位置资料等等。
DICOM 的 4 个内容层次: 1. Patient (病人) 2. Study (检验) 3. Series (系列) 4. Image (图像)

尽管头几层的内容在很多图像里是相同的,它们在每个图像文件里都要有。每一层叫一个 Information Entity,或 IE (从 relational database schema 设计引用而来)。每一层又细分成 Module。每个 Module 里面的最小单元叫做一个 attribute 或 element。

一个元素 (element) 的结构是:

1. group tag: 16-bit
2. element tag: 16-bit
3. length (or VR/length): 32-bit
4. data (bytes of length)

VR 说的是 element 格式,比如说 patinet name 的 VR 是 PN。VR可以省略,分为显示VR和隐式VR。数据都是以16进制的形式存储的。下图是一个病人性别element的的例子:

DICOM开发工具DCMTK在VS2008下的编译、配置与实例 - farmingyard - 紫玄客的那点事儿


三、DCMTK工具包的VS2008编译

该toolkit是专门针对DICOM协议进行DICOM图像相关软件开发的工具包。我主要用它来实现最基本的生成、读写DICOM图像等功能。编译生成适用于VS2008环境的库主要是参考的DCMTK编译[转]这篇文章进行相关配置的,只是在Cmake的过程中需要选择自己机器上面的VS2008编译器,其他都按照该文章中的步骤一步一步执行下去即可成功编译。

四、VS2008中的相关设置

编译生成所需要的头文件和静态库文件之后,在VS2008中新建工程,需要进行相关的设置才可以使用DCMTK的库。DCMTK的支持库已经按照上文设置加在VC目录下的相关文件夹下(include、lib和bin文件夹),所以不需要再在VS工程中附加它们,只需要把dcmtk-3.5.4-win32-i386文件夹下面的include和lib路径加入VS工程属性中的‘附加包含目录’(属性->配置属性>C\C++->常规->附加包含路径)和‘附加库目录’(属性->配置属性>链接器->常规->附加库目录)即可。除此之外,还要在属性->配置属性>链接器->输入->附加依赖项中加入所需要的库文件名,这里要特别注意它们之间的依赖关系和顺序,我加入的顺序如下:netapi32.lib wsock32.lib ofstd.lib dcmdata.lib dcmimgle.lib dcmimage.lib ijg8.lib ijg12.lib ijg16.lib dcmjpeg.lib dcmnet.lib dcmdsig.lib dcmsr.lib dcmtls.lib dcmpstat.lib dcmwlm.lib dcmqrdb.lib dcmtkeay.lib dcmtkssl.lib iconv.lib libtiff.lib libpng.lib libxml2.lib zlib.lib

另外,还要在属性->配置属性>C\C++->代码生成->运行时库里面选择【多线程调试\MTd】。

五、示例

经过以上的编译和设置,我们就可以使用DCMTK所提供的强大功能了。

下面是一个很简单的例子,生成一个DICOM格式的文件,然后再读取其中的一些信息并显示

#include <dcmtk/config/osconfig.h>
#include <dcmtk/dcmdata/dctk.h>


void main()
{

  //Create a DICOM dataset and save it to a file.
         char uid[100];
/*   
   Uint8 pixData[100];
   for (int i=0;i<100;i++)
   {
    pixData[i] = i;
   }
*/
//   const unsigned long pixelLength = 1;
   DcmFileFormat fileformat;
   DcmDataset *dataset = fileformat.getDataset();
   dataset->putAndInsertString(DCM_SOPInstanceUID,dcmGenerateUniqueIdentifier(uid,SITE_INSTANCE_UID_ROOT));
   dataset->putAndInsertString(DCM_SOPClassUID,UID_SecondaryCaptureImageStorage);
   dataset->putAndInsertString(DCM_PatientsName,"xiao ming");
   dataset->putAndInsertString(DCM_PatientsSex,"F");
   dataset->putAndInsertString(DCM_PatientsBirthDate,"19881211");
   dataset->putAndInsertString(DCM_Modality,"CT");

//   dataset->putAndInsertUint8Array(DCM_PixelData,pixData,pixelLength);
  // dataset->putAndInsertSint16(DCM_Rows,10);
  // dataset->putAndInsertSint16(DCM_Columns,10);
   OFCondition status = fileformat.saveFile("test.dcm",EXS_LittleEndianExplicit);
   if(status.bad())
    cerr<<"Error:cannot write DICOM file ("<< status.text() << ")" << endl;

  
//********************************
 
//Load a DICOM file and output the related information
// Uint16 *pixData = new Uint16[262144];
// DcmFileFormat fileformat;
    dataset = fileformat.getDataset();
    status = fileformat.loadFile("test.dcm");
 if (status.good())
 {
  OFString patientsName;
  OFString patientsBirthDate;
  OFString patientsSex;
  OFString modality;
  dataset = fileformat.getDataset();
  OFCondition statusOfPatientsName = dataset->findAndGetOFString(DCM_PatientsName,patientsName);
  OFCondition statusOfPatientsBirthDate = dataset->findAndGetOFString(DCM_PatientsBirthDate,patientsBirthDate);
  OFCondition statusOfPatientsSex = dataset->findAndGetOFString(DCM_PatientsSex,patientsSex);
  OFCondition statusOfModality = dataset->findAndGetOFString(DCM_Modality,modality);
//  dataset->findAndGetUint16Array(DCM_PixelData,pixData);
//  dataset->findAndGetUint8Array()
  if (statusOfPatientsName.good())
   cout << "Patient's Name: " << patientsName << endl;
  else
   cerr << "Error: cannot access Patient's Name!" << endl;
  if (statusOfPatientsBirthDate.good())
   cout << "Patient's BirthDate: "<< patientsBirthDate << endl;
  else
   cerr << "Error: cannot access Patient's BirthDate!" << endl;
  if (statusOfPatientsSex.good())
   cout << "Patient's sex: " << patientsSex << endl;
  else
   cerr << "Error: cannot access Patient's Sex!" << endl;
  if (statusOfModality.good())
   cout << "The Modality: " << modality << endl;
  else
   cerr << "Error: cannot access Modality!" << endl;
  
 }

 else
  cerr << "Error: cannot read DICOM file (" << status.text() << ")" << endl;

 


下图是运行结果:
DICOM开发工具DCMTK在VS2008下的编译、配置与实例 - farmingyard - 紫玄客的那点事儿
 

六、一些说明

一幅DICOM格式的图像,可以使用Matlab的dicominfo函数来显示它的文件信息,比如病人信息、设备信息等等,还可以使用dicomread和dicomwrite函数读写DICOM格式的图像。

DCMTK自带的例子也可以帮助自己学习如何使用该工具包,比如dcmtk-3.5.4\dcmdata\apps\Debug目录下的dcmdump就有显示一幅DICOM图像信息的功能。下面以它为例来使用一下这个例子的功能:

1、运行->cmd->进入命令行

2、cd->进入dcmdump所在目录下(D:\dcmtk-3.5.4\dcmdata\apps\Debug)

3、键入命令:dcmdump tests.dcm->回车

即可看到文件tests.dcm的详细信息:

DICOM开发工具DCMTK在VS2008下的编译、配置与实例 - farmingyard - 紫玄客的那点事儿


可以看到每个element都有自己的tag,即最前面的两个字符段所标明的组号和元素号。其中,图像的像素信息存放在tag为(7FE0,0010)的数据元素的值域中。

七、结语

关于DCMTK的使用和学习还在继续进行中...加油...

八、几个有帮助的链接

http://bbs.hc3i.cn/thread-26268-1-2.html

http://cc.usst.edu.cn/Able.Acc2.Web/Template/View.aspx?courseType=0&courseId=1180&topMenuId=-1&menuType=6&code=yunxuweihuluntan&action=view&type=&name=&page=1&fid=1345

http://blog.chinaunix.net/space.php?uid=423637&do=blog&id=357859

http://hi.baidu.com/diqiucun666/blog/item/b4d2a41cb1a5308d87d6b6d5.html

http://cc.usst.edu.cn/Able.Acc2.Web/Template/View.aspx?courseType=0&courseId=1180&topMenuId=-1&menuType=6&code=yunxuweihuluntan&action=view&type=&name=&page=1&fid=535

http://lxsamao.blog.163.com/blog/static/14001206720116510749972/

  评论这张
 
阅读(595)| 评论(1)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017