CT DICOM數據常用16位有符號數據存儲,可用DCMTK對其進行解析。
解析方法:

DcmFileFormat dfile; OFCondition status1; DcmMetaInfo *metainfo1; status1 = dfile.loadFile("F:\\imageData\\CT\\CTA\\DD0215\\A3932225"); status1 = dfile.loadFile("F:\\imageData\\CT\\CTA\\bianfengying\\bianfengying009.dcm"); status1 = dfile.loadFile("F:\\imageData\\CT\\CTA\\55\\1.2.392.200036.9116.2.1220972159.1407127612.8906.1.26.dcm"); status1 = dfile.loadFile("F:\\imageData\\CT\\12390000\\06379867"); metainfo1 = dfile.getMetaInfo(); DcmDataset *data = dfile.getDataset(); DcmElement* element = NULL; data->findAndGetElement(DCM_PixelData, element); DcmElement* Redelementcolor = NULL; data->findAndGetElement(DCM_RedPaletteColorLookupTableData, Redelementcolor); DcmElement* Greenelementcolor = NULL; data->findAndGetElement(DCM_GreenPaletteColorLookupTableData, Greenelementcolor); DcmElement* Blueelementcolor = NULL; data->findAndGetElement(DCM_BluePaletteColorLookupTableData, Blueelementcolor); unsigned short row(0); data->findAndGetUint16(DCM_Rows, row); unsigned short column(0); data->findAndGetUint16(DCM_Columns, column); OFString frame; data->findAndGetOFString(DCM_NumberOfFrames, frame); OFString windowCenter; data->findAndGetOFString(DCM_WindowCenter, windowCenter); OFString windowWidth; data->findAndGetOFString(DCM_WindowWidth, windowWidth); int window_center = 100; int window_width = 700; window_center = atoi(windowCenter.c_str()); window_width = atoi(windowWidth.c_str()); //Uint8* uint8pixdata = nullptr; //element->getUint8Array(uint8pixdata); long count = row*column;// *atoi(frame.c_str()); int m_bytecount = count * sizeof(Uint16); Uint16* uint16pixdata = nullptr; element->getUint16Array(uint16pixdata);
可看到,通過 element->getUint16Array(uint16pixdata),獲取得到16位無符號的raw數據。如果需要將其處理成8位數據,還需要進一步處理。
我的處理方式(不一定准確,供探討)
1.將獲取得到的無符號16位數據,轉換為有符號16位數據
2.通過窗寬窗位算法,對數據進行壓縮,得到處理后的16位有符號數據。(可參考https://blog.csdn.net/wu_uuww/article/details/6286048)
3.通過最大最小值算法,將16位數據壓縮成8位無符號數據

Sint16 *Sint16PixData = new Sint16[count]; for (int i = 0; i < count; i++) { if (uint16pixdata[i] > 20000) { Sint16PixData[i] = uint16pixdata[i] - 65536; } else { Sint16PixData[i] = uint16pixdata[i]; } } int min2 = 0; int max = 0; min2 = (2 * window_center - window_width) / 2.0 + 0.5; max = (2 * window_center + window_width) / 2.0 + 0.5; Sint16 * sint16PixData2 = new Sint16[count]; unsigned char * uint8PixData = new unsigned char[count]; for (int i = 0; i < count; i++) { Sint16PixData[i] = Sint16PixData[i]; Sint16 temp = (Sint16PixData[i] - min2) * 255 / (max - min2) ; sint16PixData2[i] = temp; } int int16max = getMaxValue(sint16PixData2, count); int int16min = getMinValue(sint16PixData2, count); for (int i = 0; i < count; i++) { int temp = (sint16PixData2[i] - int16min) * 255 / (int16max - int16min); uint8PixData[i] = temp; }
處理前(16位)
處理后(8位)
上面數據有些偏移,還不確定是什么問題。
上述方法供探討,謝謝!