DICOM访问压缩数据(DCMTK)

3
我正在处理DCMTK 3.6.1库的问题,现在我遇到了一个常见的情况:访问DICOM图像的压缩数据像素。正如该库的作者在此处建议的那样http://support.dcmtk.org/redmine/projects/dcmtk/wiki/Howto_AccessingCompressedData,这是获取压缩数据的正确方法。这段代码可以工作,但是它们从文件开始创建数据集。在我的代码中,我通过另一种方式填充了数据集。
status = data->putAndInsertUint8Array(DCM_PixelData, pSource, sizeBuffer);

我需要将pSource中包含的未压缩像素数据进行翻译。随后,我会添加图像DICOM标签(组28),并通过进行压缩来处理数据。

status = data->chooseRepresentation(EXS_JPEGProcess14SV1, &param);

从这个数据集开始,我想访问压缩数据。

status = data->findAndGetElement(DCM_PixelData, element);
    DcmPixelData *dpix = NULL;
    dpix = OFstatic_cast(DcmPixelData*, element);
    /* Since we have compressed data, we must utilize DcmPixelSequence
    in order to access it in raw format, e. g. for decompressing it
    with an external library.
    */
    DcmPixelSequence *dseq = NULL;
    E_TransferSyntax xferSyntax = EXS_Unknown;
    const DcmRepresentationParameter *rep = NULL;
    // Find the key that is needed to access the right representation of the data within DCMTK
    dpix->getOriginalRepresentationKey(xferSyntax, rep);

    // Access original data representation and get result within pixel sequence
    status = dpix->getEncapsulatedRepresentation(xferSyntax, rep, dseq);
    Uint32 length;
    if (status.good())
    {
        DcmPixelItem* pixitem = NULL;
        // Access first frame (skipping offset table)
        dseq->getItem(pixitem, 1);
        if (pixitem == NULL)
            return 1;
        Uint8* pixData = NULL;
        // Get the length of this pixel item (i.e. fragment, i.e. most of the time, the lenght of the frame)
        length = pixitem->getLength();
        if (length == 0)
            return 1;
        // Finally, get the compressed data for this pixel item
        status = pixitem->getUint8Array(pixData);
        // Metto i Pixel Data compressi su pSorgCompr
        pSorgCompr = (LPBYTE)pixData;
    }
    ////////////////////////////

    DJEncoderRegistration::cleanup();
    DJDecoderRegistration::cleanup();

但行 status = dpix->getEncapsulatedRepresentation(xferSyntax, rep, dseq); 返回失败,错误信息为“未找到像素表示”,我不明白为什么。

奇怪的是,在访问压缩数据之前,如果我使用 fileformat.saveFile("compressedPixelData.dcm", EXS_JPEGProcess14SV1); 将压缩文件保存并使用 result = fileformat.loadFile("compressedPixelData.dcm"); 加载该文件,一切都完美地工作。

好像 loadfile 函数解决了问题,我不知道是怎么做到的,也许填充了一些标签?

在调用 chooseRepresentation 函数之前,我填充的标签包括:

  • DCM_Rows
  • DCM_Columns
  • DCM_BitsStored
  • DCM_SamplesPerPixel
  • DCM_PlanarConfiguration
  • DCM_HighBit
  • DCM_BitsAllocated
  • DCM_PixelRepresentation
  • DCM_RescaleIntercept
  • DCM_RescaleSlope
  • DCM_PhotometricInterpretation
  • DCM_PixelAspectRatio
  • DCM_ImagerPixelSpacing
  • DCM_PixelSpacing
2个回答

1

在DICOM中,压缩帧与未压缩(本机)帧在Pixel数据元素(7FE0, 0010)下以不同的方式存储。以下是DICOM中压缩图像编码的基本概念。

封装的像素流(压缩图像数据)在顶层数据集的Pixel Data元素(7FE0, 0010)下被分段为一个或多个片段(项)。在封装编码中,Pixel Data元素是一个序列,它包含两个或更多的项元素(片段),每个片段(项元素)都有自己的显式长度。此外,封装格式支持单帧和多帧图像编码。一帧可以完全包含在一个单独的片段(项)中,也可以跨越多个片段。封装像素流的片段序列以定界符终止。
在编码的像素数据流之前的项目序列中,第一个项目(FFFE,E000)通常为空,或者可能包含一个基本偏移表项,该项保存了每个帧的项目序列中第一个片段的项标记的第一个字节的字节偏移量。

因此,当您想从DICOM数据集中提取压缩的像素流时,需要跳过Pixel Data序列下的第一个Item元素。希望这有助于理解您所引用的文档。请参考DICOM标准PS 3.5附录A以获取更多信息。

谢谢你的回答。是的,我已经阅读了这些内容,你所说的在代码的这一部分完成:// Access first frame (skipping offset table) dseq->getItem(pixitem, 1);但这并没有回答我的问题。对于我的问题,似乎当我选择表示时,原始数据仍然保持不变,我需要将其删除才能访问压缩数据。 - GiordiX

0

嗯,也许我已经解决了这个问题。我已经添加了指令。

dataset->removeAllButCurrentRepresentations(); 

在访问压缩像素数据之前。

我也可以执行PixelData->removeAllButCurrentRepresentations();而不是之前的指令,并且可以以同样的方式工作....

但是我真的不明白它为什么能工作....你能否请尝试解释一下吗? 谢谢


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接