16位CT DICOM數據轉換為8位


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);
View Code

可看到,通過 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 = 0int 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;
    }
View Code

處理前(16位)

處理后(8位)

上面數據有些偏移,還不確定是什么問題。

 

 

上述方法供探討,謝謝!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM