前面工作需要,将dicom医学文件转化为普通图像,如bmp,jpg等,中间应用到了CxImage_x64和dcmtk包。实现过程中,遇到了不少麻烦,现将相关过程分享如下,希望能给需要的人提供参考,以及上传所有相关文档。
文档分为以下几部分:
(1) 工程文件,需要将支持库拷贝到对应位置,并设置工程库目录,包含目录之后才能运行;
(2) 可执行文件,拷贝到64位机器即可运行(其中包含医学影像文件image-000001.dcm);
(3) 支持库:用于打开解析dicom文件,需要按照说明添加;
(4) Readme.doc:描述文档结构和配置,代码,程序界面等信息。
先按照支持库里面说明,将两个包拷贝到常用位置,方便后面设置工程,具体可以参照我的设置测试方式。
包含目录设置:
D:\Program Files (x86)\Microsoft VisualStudio 10.0\CxImage_x64\include(如果是32位自己下32位版本)
D:\Program Files\DCMTK\include
库目录设置:
D:\Program Files (x86)\Microsoft VisualStudio 10.0\CxImage_x64\lib
D:\Program Files\DCMTK\lib
连接器附加项设置:
cximage.lib
netapi32.lib
wsock32.lib
ofstd.lib
oflog.lib
dcmimgle.lib
ijg8.lib
ijg12.lib
ijg16.lib
dcmdata.lib
dcmimage.lib
dcmjpeg.lib
dcmnet.lib
TCHAR szFilter[] = _T("文本À文件t(*.dcm)|*.dcm"); //选择dcm文件打开
CFileDialog fileDlg(TRUE,_T("txt"),NULL, 0, szFilter,this);// 创建对话框
CStringstrFilePath;
if (IDOK ==fileDlg.DoModal()) // 点击确定保存文件路径
{
strFilePath =fileDlg.GetPathName(); // 文件路径
SetDlgItemText(IDC_EDIT_open,strFilePath); // 设置文件路径显示与界面
savepath = fileDlg.GetFolderPath(); // 生存图像保存路径
filename= fileDlg.GetFileTitle(); // 生存图像保存文件名
}
if ((m_check_bmp.GetCheck()>0)||(m_check_jpg.GetCheck()>0)) // 指定需要转化的图片类型,目前只提供bmP和jpg
{
CString str,savestr; //
GetDlgItem(IDC_EDIT_open)->GetWindowText(str); // 获取文件名
DJEncoderRegistration::registerCodecs();//注册dicom文件封装类
DcmFileFormat fileformat;
if(fileformat.loadFile(str).good()) // 文件加载正常
{
THU_STD_NAMESPACE::TDcmFileFormattdf(fileformat); // 转化为封装类
if (m_check_bmp.GetCheck()>0)
{ // 如果选择了bmp转化
tdf.saveToBmp(savepath+"\\"+filename+".bmp"); // 转化为bmp文件,具体代码可以点击函数定义进去查看,主要步骤包括将dcom文件的头文件信息以及数据索引指针赋值给bmp对象,在进行保存,jpg类似
}
if(m_check_jpg.GetCheck()>0)
{
tdf.saveToJpg(savepath+"\\"+filename+".jpg");// 转化为jpg文件
}
inth = tdf.getHeight(); // 获取影像高度
int w = tdf.getWidth(); //获取影像宽度
CStringstr ;
str.Format("%d",w);
SetDlgItemText(IDC_ew,str); //宽度显示于界面
str.Format("%d",h);
SetDlgItemText(IDC_eh,str); //高度显示
MessageBox("转化完毕!","提示"); // 信息提示
}
DJEncoderRegistration::cleanup();//注销注册类
}
else
MessageBox("请选择转化类型","提示");
void Cdicomview20170310Dlg::OnBnClickedshowpic()
{
int cx, cy;
CImage image;
CRect rect;
if (PathFileExists(savepath+"\\"+filename+".bmp"))// 判断图像是否存在
{
image.Load(savepath+"\\"+filename+".bmp"); // 加载图像
} else if ( PathFileExists(savepath+"\\"+filename+".jpg" ))
{
image.Load(savepath+"\\"+filename+".jpg"); // 加载图像
}
else
return;
cx =image.GetWidth(); // 获取图像宽高
cy = image.GetHeight();
GetDlgItem(IDC_pic)->GetWindowRect(&rect); // 获取显示控件区域
ScreenToClient(&rect);
GetDlgItem(IDC_pic)->MoveWindow(rect.left, rect.top,cx,cy,TRUE); // 移动到指定区域
CWnd *pWnd= NULL;
pWnd = GetDlgItem(IDC_pic);//获取显示控件句柄
pWnd->GetClientRect(&rect);//获取句柄对应区域
CDC *pDc = NULL;
pDc = pWnd->GetDC();//显示图像
image.Draw(pDc->m_hDC,rect);//绘制图像
ReleaseDC(pDc); // 释放资源
}
OFConditionstatus; // 定义变量
DcmFileFormat fileformat;
DcmDataset*mydatasete=fileformat.getDataset();
DicomUtils du;
du.AddDicomElements((DcmDataset*&)mydatasete);
Uint16 rows,cols,samplePerPixel,bitsAlloc,bitsStored,highBit,pixelRpr,planConf,pixAspectH,pixAspectV;
OFString photoMetrInt;
Uint32 length;
E_TransferSyntax ts;
//循-环¡¤添¬¨ª加¨®4张?图ª?片?
//for(inti=0;i<4;++i)
//{
charnumtmp[500]; // 申明文件名字符串
CString tpath = savepath+"\\"+filename+".bmp" ;
memset(numtmp,0,sizeof(tpath));
sprintf(numtmp,"%s",tpath);//转化文件名字符串
I2DBmpSource *bmpSource = new I2DBmpSource();//I2DBmpSource();
bmpSource->setImageFile(numtmp); // 读取bmp图像数据
char*pixData=NULL;
bmpSource->readPixelData(rows,cols,samplePerPixel,photoMetrInt,bitsAlloc,bitsStored,highBit,pixelRpr,planConf,pixAspectH,pixAspectV,pixData,length,ts); // 解析图像数据
//deletebmpSource;
//};
mydatasete->putAndInsertUint16(DCM_SamplesPerPixel,samplePerPixel); // 添加bmp图像数据到dcm文件
mydatasete->putAndInsertString(DCM_NumberOfFrames,"1");
mydatasete->putAndInsertUint16(DCM_Rows,rows);
mydatasete->putAndInsertUint16(DCM_Columns,cols);
mydatasete->putAndInsertUint16(DCM_BitsAllocated,bitsAlloc);
mydatasete->putAndInsertUint16(DCM_BitsStored,bitsStored);
mydatasete->putAndInsertUint16(DCM_HighBit,highBit);
mydatasete->putAndInsertUint8Array(DCM_PixelData,(Uint8*)pixData,1*length);
mydatasete->putAndInsertOFStringArray(DCM_PhotometricInterpretation,photoMetrInt);
mydatasete->putAndInsertString(DCM_PlanarConfiguration,"1");
tpath = savepath+"\\"+filename+"new.dcm" ;
memset(numtmp,0,sizeof(tpath));
sprintf(numtmp,"%s",tpath);
status=fileformat.saveFile(numtmp,ts); //保存dcm文件
if(status.bad()) // 保存状态
{
MessageBox("转Áa换?失º¡ì败㨹!ê?","提¬¨¢示º?");
} else {
MessageBox("转Áa换?完ª¨º毕À?!ê?","提¬¨¢示º?");
}
步骤分3步:
(1)点击打开文件,选择待转化文件;
(2)选择jpg或者bmp待转化格式;
(3)点击转换;
(4)显示转化图像的效果;
(5)退出;
转化生成的图片保存在原始影像文件所在目录,如下图所示: