VS2015 编译DCMTK,读取CT图像并转换为OpenCV格式
不清楚各种数据的格式、意义、如何解析?参考书籍:DICOM Structured Reporting
一、DCMTK编译(-mD/-mDd模式)
0. 材料:
- DCMTK3.6.2源码
- CMake
- VS2015
1. DCMTK源码下载
官网下载DCMTK源码:https://github.com/DCMTK/dcmtk
2. CMake下载
官网下载CMake软件:https://cmake.org/
3. 编译
3.1定位源码
打开CMake,选择DCMTK源码所在目录,编译结果存放目录,如下如所示:打开CMake,选择DCMTK源码所在目录,编译结果存放目录,如下如所示:
3.2 确定编译器
选择正确的源码目录和编译结果存放目录后,点击【Configuire】,选择所需编译器,这里编译Win32位,所以选择Visual Studio 14 2015编译器,如果需要编译x64,选择Visual Studio 14 2015 Win64编译器,然后点击【确定】.
3.3 修改CMake配置
这里需要修改许多处,不然会编译出错,修改处见下图:
支持包下载网址:ftp://dicom.offis.de/pub/dicom/offis/software/dcmtk/dcmtk362/support/
3.5 生成工程
上步完成后,再次点击【Configure】,在点击【Generate】生成工程,点击【Open Project】,用VS2015打开构建的工程。
3.6 确认工程构建正确
随便选择一个解决方案:
1. 确认是使用字符集为:多字节字符串集。
- 确认是生成动态链接库形式。
确定无误后,执行编译。
3.7 编译
选择ALL BUILD解决方案,右键【生成】开始编译。
3.8 安装
3.7步无误后,选择INSTALL解决方案,右键【生成】,开始安装,则在安装目录下将生成编译的结果。
3.9 Debug和Release版本各生成一份
通过切换VS2015的解决方案配置,Debug版本和Release版本执行3.7和3.8各一次,则能生成Debug和Release版本各生成一份。
3.10 结果
结果如下图所示
二、VS2015配置DCMTK,OpenCV
0. 材料
- 编译好的DCMTK动态链接库
- OpenCV(这里是2.4.13版本)
1.配置OpenCV
此处不写,参考:http://blog.csdn.net/bendanban/article/details/28661763 , 这种配置方法也是我强烈推荐的。
2. 配置DCMTK
跟配置OpenCV一模一样,此处略过。
三、*.dcm转OpenCV格式
代码及解释如下:
#include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */
#include "dcmtk/ofstd/ofstdinc.h"
#include "dcmtk/dcmdata/dctk.h"
#include "dcmtk/dcmdata/cmdlnarg.h"
#include "dcmtk/ofstd/ofconapp.h"
#include "dcmtk/dcmdata/dcuid.h" /* for dcmtk version name */
#include "dcmtk/dcmjpeg/djdecode.h" /* for dcmjpeg decoders */
#include "dcmtk/dcmjpeg/dipijpeg.h" /* for dcmimage JPEG plugin */
#pragma comment(lib, "ws2_32.lib") // 包含socket,因为.dcm图像包含网络通信协议
#pragma comment(lib,"iphlpapi.lib")
#pragma comment(lib, "netapi32.lib")
/*
* dcm2Mat:将.dcm格式图像转换为OpenCV的Mat格式
* fileName:CT图像的名字
* mat: 保存转换后的CT图像
*返回值:成功返回true,失败返回false
*/
bool dcm2Mat(const char* const fileName, cv::Mat & mat)
{
DJDecoderRegistration::registerCodecs(); // register JPEG codecs
DcmFileFormat fileformat; //DcmFileFormat fileformat;
if (!(fileformat.loadFile(fileName).good()))
return false;
DcmDataset *dataset = fileformat.getDataset();
// decompress data set if compressed
dataset->chooseRepresentation(EXS_LittleEndianExplicit, NULL);
DcmElement* element = NULL;
OFCondition result = dataset->findAndGetElement(DCM_PixelData, element);
if (result.bad() || element == NULL)
return false;
unsigned short* pixData;
result = element->getUint16Array(pixData);
OFintptr_t rows = 0; // 图像行数
OFintptr_t cols = 0; // 图像列数
dataset->findAndGetLongInt(DCM_Rows, rows);
dataset->findAndGetLongInt(DCM_Columns, cols);
if (rows == 0 || cols == 0)
return false;
unsigned short *pbuf = new unsigned short[rows*cols];
memcpy(pbuf, pixData, rows*cols * 2);
Mat xxx(rows, cols, CV_16SC1, pbuf);
Mat xx;
cv::normalize(xxx, xx, 0, 255, NORM_MINMAX, CV_8UC1); // 像素值归一化到0~255
Mat afull(xx.rows, xx.cols, CV_8UC1, 255); // 全白图像
xx = afull - xx; // 图像颜色反转,黑变白,白变黑
mat = xx.clone(); // 为什么不直接用xx? 因为为了防止内存泄漏
cvtColor(mat, mat, CV_GRAY2RGB); // 灰度转彩色,视具体工程而定,如果只需灰度图,可以不转换
delete[]pbuf; // 防止内存泄漏
DJDecoderRegistration::cleanup(); // deregister JPEG codecs
return true;
}
四、*.dcm文件头信息读取
.dcm图像文件头包含的信息非常丰富,此处展示一种读取文件头信息的方法,其他方法参见官方指导:http://support.dcmtk.org/redmine/projects/dcmtk/wiki/howto_loadmetaheader 。
// 功能:读取病人姓名
OFFilename filename= "ct.1";//这里改为你的CT图像文件
OFCondition status = fileformat.loadFile(filename);
DcmDataset *dataset = fileformat.getDataset(); // 通过dataset 同时获取文件头信息和图像数据
OFString PatientName;
dataset->findAndGetOFString(DCM_PatientName, PatientName); // DCM_PatientName:病患姓名
cout <<"姓名:"<<PatientName<<endl;
其他信息的关键字都定义在头文件“dcdeftag.h”中,如下图所示:
不清楚CT片的文件头到底包含什么信息?? 使用Sante DICOM Viewer 8 查看CT图像,从【view】——【file Header】中查看。
五、可能会遇到的编程错误
- 出现错误的提示的函数以WSA开头,如:LNK2001 无法解析的外部符号 [email protected] CC E:\visualstudio\CC\CC\oflog.lib(oflog.obj),如图:
解决方案:显示链接ws2_32.lib库
#pragma comment(lib, "ws2_32.lib")
- 出现错误:LNK2001 无法解析的外部符号 [email protected] CC E:\visualstudio\CC\CC\ofstd.lib(ofstd.obj)
解决方案:显示链接iphlpapi.lib库
#pragma comment(lib,"iphlpapi.lib")
- 出现错误:LNK2001 无法解析的外部符号 [email protected] CC E:\visualstudio\CC\CC\dcmdata.lib(dcuid.obj)
解决方案:显示链接netapi32.lib库
#pragma comment(lib, "netapi32.lib")
六、总结
本文内容包含以下几个方面:
1. 如何编译DCMTK;
2. 如何进行*.dcm图像数据的读取,并转换为OpenCV的Mat格式;
3. *.dcm文件的文件头信息分析;
4. 期间遇到的常见错误列举。
最后,祝你在医学图像处理的道路上越走越好!
参考资料:
Visual Studio 2015+cmake编译安装MD版的DCMTK:http://blog.csdn.net/chaoenhu/article/details/78200274
VisualStudio2010配置OpenCV的一种一劳永逸的方法:http://blog.csdn.net/bendanban/article/details/28661763
转载请注明作者和出处:http://blog.csdn.net/holamirai,未经允许请勿用于商业用途。
上一篇: labelme影像标注后3波段变单波段
下一篇: PHP private