前面工作需要,將dicom醫學文件轉化爲普通圖像,如bmp,jpg等,中間應用到了CxImage_x64和dcmtk包。實現過程中,遇到了不少麻煩,現將相關過程分享如下,希望能給需要的人提供參考,以及上傳所有相關文檔。
文檔分爲以下幾部分:
(1) 工程文件,需要將支持庫拷貝到對應位置,並設置工程庫目錄,包含目錄之後才能運行;
(2) 可執行文件,拷貝到64位機器即可運行(其中包含醫學影像文件image-000001.dcm);
(3) 支持庫:用於打開解析dicom文件,需要按照說明添加;
(4) Readme.doc:描述文檔結構和配置,代碼,程序界面等信息。
1、支持庫拷貝
先按照支持庫裏面說明,將兩個包拷貝到常用位置,方便後面設置工程,具體可以參照我的設置測試方式。
2、工程設置
包含目錄設置:
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
3、工程字符集設爲多字節
4、核心代碼簡單說明
4.1、選擇文件
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(); // 生存圖像保存文件名
}
4.2、打開並轉化文件
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("請選擇轉化類型","提示");
4.3、顯示圖像
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); // 釋放資源
}
4.4、bmp轉dcm
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換?完ª¨º畢À?!ê?","提¬¨¢示º?");
}
5、程序效果
步驟分3步:
(1)點擊打開文件,選擇待轉化文件;
(2)選擇jpg或者bmp待轉化格式;
(3)點擊轉換;
(4)顯示轉化圖像的效果;
(5)退出;
轉化生成的圖片保存在原始影像文件所在目錄,如下圖所示: