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位)

上面数据有些偏移,还不确定是什么问题。

 

 

上述方法供探讨,谢谢!

 

posted @ 2019-02-26 13:57  丢了木剑的温华  阅读(1762)  评论(0编辑  收藏  举报