dicom文件與bmp和jpg文件的相互轉化

        前面工作需要,將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)退出;

 

轉化生成的圖片保存在原始影像文件所在目錄,如下圖所示:



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章