DCMTK是目前最全面實現DICOM3.0標準的開源庫,通過結合DCMTK開源庫和CxImage映像開源庫,能夠很方便的開發屬於自己的DCM檔案編輯瀏覽軟體。
下面記錄”DCM檔案到BMP檔案格式的轉換“的學習和探索的過程。
BMP檔案的格式這裡不細講(可自行參閱MSDN相關資料)。BMP屬於裝置無關圖(DIB),記憶體中只要依次包含BMP檔案頭(BITMAPFILEHEADER)、BMP資訊頭(BITMAPINFOHEADER)、調色盤(Palette),以及真實像素資訊,就可以在所有顯示裝置中進行顯示。因此將DCM檔案轉換到BMP格式的主要工作是:從DCM眾多資料元中挑選出BMP檔案頭、資訊頭所必須的資訊(像寬度、映像高度、每個像素所佔的空間、像素資料等)。
此次採用了dcmtk中的dcmimgle開發包,利用DicomImage類提供的createWindowsDIB介面以及writeBMP來進行格式轉化。具體代碼如下:
DcmFileFormat *mImage=new DcmFileFormat();DJDecoderRegistration::registerCodecs(); // register JPEG codecsDcmDataset *dataset = mImage->getDataset();E_TransferSyntax xfer=dataset->getOriginalXfer();dataset->chooseRepresentation(EXS_LittleEndianExplicit,NULL);DicomImage *pdcmImage=new DicomImage((DcmFileFormat*)mImage,EXS_LittleEndianExplicit,CIF_AcrNemaCompatibility,0,1);if(pdcmImage->getStatus()!=EIS_Normal)exit(0);void* pDIB=NULL;int size=0;pdcmImage->createWindowsDIB(pDIB,size,0,8,1,1);
至此,pDIB記憶體中就獲得了”c:\test.dcm“檔案像素資料多對應的BMP格式的資料。如果想將pDIB儲存成BMP檔案,還需要補充BMP檔案頭(BITMAPFILEHEADER)、BMP資訊頭(BITMAPINFOHEADER)、調色盤(Palette)。參照MSDN中BITMAPFILEHEADER和BITMAPINFOHEADER的結構,逐個成員賦值即可。假設我們產生的檔案頭變數為mBmpFileHeader,資訊頭變數為mBmpInfoHeader。由於createWindowsDIB函數中的BMP像素位元設定的是8,所以BMP映像屬於索引映像,其檔案中需要調色盤,調色盤的產生如下所示(最簡單的產生方法):
RGBQUAD* mPalette=new RGBQUAD[256];memset(mPalette,0,sizeof(RGBQUAD)*256);for(int i=0;i<256;++i){mPalette[i].rgbBlue=i;mPalette[i].rgbGreen=i;mPalette[i].rgbRed=i;}
隨後將mBmpFileHeader、mBmpInfoHeader、mPalette添加到pDIB的前面,就構成了一幅BMP映像,直接將此資料儲存成bmp檔案即可。具體的連結步驟如下:
int imgsize=width*height;int headsize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256;int size=headsize+imgsize;BYTE* mDibImage=new BYTE[size];memset(mDibImage,0,size);memcpy(mDibImage,mBmpFileHeader,sizeof(BITMAPFILEHEADER));memcpy(&mDibImage[sizeof(BITMAPFILEHEADER)],mBmpInfoHeader,sizeof(BITMAPINFOHEADER));memcpy(&mDibImage[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)],mPalette,sizeof(RGBQUAD)*256);memcpy(&mDibImage[headsize],pDIB,imgsize);
至此mDibImage記憶體儲存的資料就是一幅完整的BMP檔案。將其儲存後的結果如(左)所示:
相比dcm瀏覽軟體中看到的結果(右),自己產生的映像模糊很多。思考原因,可能是窗寬窗位的關係。DicomImage中也提供了調整窗寬窗位的介面setWindow。在調用createWindowsDIB函數之前,調用setW函數,隨後產生的BMP映像結果如下:
與常用的dcm瀏覽軟體中的結果一致。