如何从字节 (DCMTK) 创建 DICOM 映像

How create a DICOM image from byte (DCMTK)

本文关键字:创建 DICOM 映像 DCMTK 字节      更新时间:2023-10-16

我想在可以创建DICOM映像的现有项目中使用DCMTK 3.6.1库。我想使用此库,因为我想压缩 DICOM 图像。在一个新的解决方案(Visual Studio 2013/C++)中,按照DCMTK官方文档中的示例,我有这段代码,可以正常工作。

using namespace std;
int main()
{
    DJEncoderRegistration::registerCodecs();
    DcmFileFormat fileformat;
    /**** MONO FILE ******/
    if (fileformat.loadFile("Files/test.dcm").good())
    {
        DcmDataset *dataset = fileformat.getDataset();
        DcmItem *metaInfo = fileformat.getMetaInfo();
        DJ_RPLossless params; // codec parameters, we use the defaults
        // this causes the lossless JPEG version of the dataset 
        //to be created EXS_JPEGProcess14SV1
        dataset->chooseRepresentation(EXS_JPEGProcess14SV1, &params);   
        // check if everything went well
        if (dataset->canWriteXfer(EXS_JPEGProcess14SV1))
        {
            // force the meta-header UIDs to be re-generated when storing the file
            // since the UIDs in the data set may have changed
            delete metaInfo->remove(DCM_MediaStorageSOPClassUID);
            delete metaInfo->remove(DCM_MediaStorageSOPInstanceUID);
            metaInfo->putAndInsertString(DCM_ImplementationVersionName, "New Implementation Version Name");
            //delete metaInfo->remove(DCM_ImplementationVersionName);
            //dataset->remove(DCM_ImplementationVersionName);
            // store in lossless JPEG format
            fileformat.saveFile("Files/carrellata_esami_compresso.dcm", EXS_JPEGProcess14SV1);
        }
    }
    DJEncoderRegistration::cleanup();
    return 0;
}

现在我想在现有的C++应用程序中使用相同的代码,其中

if (infoDicom.arrayImgDicom.GetSize() != 0)  //Things of existing previous code
      {
     //I have added here the registration
     DJEncoderRegistration::registerCodecs(); // register JPEG codecs
     DcmFileFormat fileformat;
     DcmDataset *dataset = fileformat.getDataset();
     DJ_RPLossless params;
      dataset->putAndInsertUint16(DCM_Rows, infoDicom.rows);
     dataset->putAndInsertUint16(DCM_Columns, infoDicom.columns,);
     dataset->putAndInsertUint16(DCM_BitsStored, infoDicom.m_bitstor);
     dataset->putAndInsertUint16(DCM_HighBit, infoDicom.highbit);
     dataset->putAndInsertUint16(DCM_PixelRepresentation, infoDicom.pixelrapresentation);
     dataset->putAndInsertUint16(DCM_RescaleIntercept, infoDicom.rescaleintercept);
     dataset->putAndInsertString(DCM_PhotometricInterpretation,"MONOCHROME2");
     dataset->putAndInsertString(DCM_PixelSpacing, "0.086\0.086");  
     dataset->putAndInsertString(DCM_ImagerPixelSpacing, "0.096\0.096");
     BYTE* pData = new BYTE[sizeBuffer];
     LPBYTE   pSorg;
     for (int nf=0; nf<iNumberFrames; nf++)
     {
        //this contains all the PixelData and I put it into the dataset
        pSorg = (BYTE*)infoDicom.arrayImgDicom.GetAt(nf);
        dataset->putAndInsertUint8Array(DCM_PixelData, pSorg, sizeBuffer);
        dataset->chooseRepresentation(EXS_JPEGProcess14SV1, &params);
        //and I put it in my data set            

         //but this IF return false so che canWriteXfer fails...
        if (dataset->canWriteXfer(EXS_JPEGProcess14SV1))
        {
           dataset->remove(DCM_MediaStorageSOPClassUID);
           dataset->remove(DCM_MediaStorageSOPInstanceUID);
        }
            //the saveFile fails too, and the error is "Pixel 
//rappresentation  non found" but I have set the Pixel rep with 
//dataset->putAndInsertUint16(DCM_PixelRepresentation, infoDicom.pixelrapresentation);
   OFCondition status = fileformat.saveFile("test1.dcm", EXS_JPEGProcess14SV1);
     DJEncoderRegistration::cleanup();
        if (status.bad())
        {
           int error = 0; //only for test
        }
        thefile.Write(pSorg, sizeBuffer); //previous code
     }

实际上,我对一帧上的图像进行了测试,因此for循环仅执行一次。我不明白为什么如果我选择dataset->chooseRepresentation(EXS_LittleEndianImplicit, &params);dataset->chooseRepresentation(EXS_LittleEndianEXplicit, &params);完美工作,但当我选择dataset->chooseRepresentation(EXS_JPEGProcess14SV1, &params);时却不行

如果我在第一个应用程序中使用相同的图像,我可以毫无问题地压缩图像......

编辑:我认为要解决的主要问题是返回"找不到标签"的status = dataset->chooseRepresentation(EXS_JPEGProcess14SV1, &rp_lossless)。我怎么知道错过了标签?

编辑2:正如DCMTK论坛中所建议的那样,我添加了有关分配位的标签,现在适用于少数图像,但不适用于所有图像。对于某些图像,我再次"找不到标签":我怎么知道缺少其中一个标签?通常最好插入所有标签?

我解决了添加标签DCM_BitsAllocated和DCM_PlanarConfiguration的问题。这是遗漏的标记。我希望这对某人有用。

至少你应该在应用数据之后调用函数 chooseRepresentation。

**dataset->putAndInsertUint8Array(DCM_PixelData, pSorg, sizeBuffer);**
dataset->chooseRepresentation(EXS_JPEGProcess14SV1, &params);